在最坏情况下,找到n个元素中第二小的元素需要n+lgn-2次比较

首先两两比较找到最大的元素,需要n-1次,即二叉树的非叶子节点的个数。之后次最大的一定在和最大的元素比较过的元素中,共有lgn-1个,即树的高度。故加起来就是n+lgn-2



#include<iostream>
using namespace std;
class Node
{
public:
    Node();
    Node(int d);
    Node*left;
    Node*right;
    int data;
};
Node::Node()
{
    right = left = NULL;
}
Node::Node(int d)
{
    data = d;
    right = left = NULL;
}
class BinaryTree
{
public:
    Node*root;
    void create_tree(Node**node,int len);
    int min(int a, int b);
    int search_second_small();
    BinaryTree();

};
BinaryTree::BinaryTree()
{
    root = new Node();
}
int BinaryTree::min(int a, int b)
{
    return a < b ? a : b;
}
void BinaryTree::create_tree(Node**node, int len)
{
    if (len < 2)
        return;
    if (len == 2)
    {
        root->left = node[0];
        root->right = node[1];
        root->data = min(node[0]->data,node[1]->data);
    }
    else
    {
        int new_len = (len % 2) ? (len / 2 + 1) : (len / 2);
        Node**new_node = new Node*[new_len];
        int mod = len % 2;

        for (int i = 0; i < new_len - mod; i++)
        {
            new_node[i] = new Node(min(node[2*i]->data,node[2*i+1]->data));
            new_node[i]->left = node[2 * i];
            new_node[i]->right = node[2 * i + 1];
        }
        if (mod)
           new_node[new_len - 1] = node[len-1];
        create_tree(new_node, new_len);
        delete[] new_node;
    }
}
int BinaryTree::search_second_small()
{
    Node*p = root;
    int second = 0x7fffffff;
    while (p->left&&p->right)
    {
        if (p->data == p->left->data)
        {
            if (second > p->right->data)
                second = p->right->data;
            p = p->left;
        }
        else
        {
            if (second > p->left->data)
                second = p->left->data;
            p = p->right;
        }
    }
    return second;

}
int main()
{
    int arr[] = {1,3,2,4,6,0,9,8};
    int N = sizeof arr / sizeof arr[0];
    Node**node = new Node*[N];

    for (int i = 0; i < N; i++)
        node[i] = new Node(arr[i]);
    BinaryTree* bi_tree = new BinaryTree();
    bi_tree->create_tree(node, N);
    cout << bi_tree->root->data << endl;
    cout << bi_tree->search_second_small() << endl;
    return 0;

}

				
时间: 2024-10-13 01:33:51

在最坏情况下,找到n个元素中第二小的元素需要n+lgn-2次比较的相关文章

二、给定一个 n 行 m 列的地牢,其中 &#39;.&#39; 表示可以通行的位置,&#39;X&#39; 表示不可通行的障碍,牛牛从 (x0 , y0 ) 位置出发,遍历这个地牢,和一般的游戏所不同的是,他每一步只能按照一些指定的步长遍历地牢,要求每一步都不可以超过地牢的边界,也不能到达障碍上。地牢的出口可能在任意某个可以通行的位置上。牛牛想知道最坏情况下,他需要多少步才可以离开这个地牢。

给定一个 n 行 m 列的地牢,其中 '.' 表示可以通行的位置,'X' 表示不可通行的障碍,牛牛从 (x0 , y0 ) 位置出发,遍历这个地牢,和一般的游戏所不同的是,他每一步只能按照一些指定的步长遍历地牢,要求每一步都不可以超过地牢的边界,也不能到达障碍上.地牢的出口可能在任意某个可以通行的位置上.牛牛想知道最坏情况下,他需要多少步才可以离开这个地牢. 个输入包含 1 个测试用例.每个测试用例的第一行包含两个整数 n 和 m(1 <= n, m <= 50),表示地牢的长和宽.接下来的

如何在没有实际项目经验的情况下找到工作

原文:How to Land a Development Job Without Experience 作者:Paddy Sherry 译者:LeviDing 声明:转载请注明出处. ??许多开发人员在找工作的时候,虽然满足了对方所要求的理论技能,但是缺乏实际的开发经验,这让雇主在是否雇用你这个问题上犹豫不决.在这篇文章中,具有丰富招聘经验的 Paddy Sherry 为你提供了一些指南,来帮助你提高找到工作的体会. ??对于许多年轻的计算机或 IT 相关专业毕业生,在没有实际项目开发经验的情况

找到一段话中第二个关键字的位置

namespace  找到一段话中第二个关键字的位置 {    class Program    {        static void Main(string[] args)        {     //找第二个a            string s = "cabcaceadf";            int n = s.IndexOf("a");  //找到第一个a的索引n            string x = s.Substring(n+1);

如何在使用eclipse的情况下,清理android项目中的冗余class文件和资源文件以及冗余图片

在我们迭代项目的过程中,经常会启用某些功能,或者修改某些界面的问题,那么问题来了,这样很容易出现大量的冗余.java文件,冗余资源文件,一些冗余的界面文件等.那么问题既然出现了,那么如何去解决呢,这就是今天着重要去解决的问题? first: eclipse有个检查冗余java文件的插件,名叫UCDetector: 下载地址为:http://sourceforge.net/projects/ucdetector/files/latest/download?source=files 官网地址:htt

查找序列中第二大的元素

这个问题,感觉很简单,一看就可能首先想到几种方法,例如: 首先对这个序列进行排序,然后取第二个位置的元素:或者循环遍历元素序列,找到最大的元素,然后将其移除.再重复此过程,得到第二大的元素. 但是都没有考虑其效率.下面提出一种方法: <span style="font-size:14px;">package algrithm; public class secondbignum { public static void main(String[] args) { int [

链表:在不给出整个链表头结点的情况下,删除单链表中的某个节点

问题描述: 有一个包含int型节点值的单链表,给定一个链表中的节点node,但不给定整个链表的头结点,删除链表中的某个结点. 算法实现: class Node { public int value; public Node next; public Node(int value) { this.value = value; } } public void removeWiredNode(Node node) { if(node == null) { return; } Node next = n

在仅拿到头文件的情况下,如何修改类中的私有成员值?

1 通过使用从对象开始处的硬编码/手工编码的偏移量构造指针来访问私有成员数据 class Weak { public: Weak() = default; ~Weak() = default; // 想想如果去掉该函数,外部想修改类中的私有成员变量 m_name 时该如何操作? void name(const std::string &name) { m_name = name; } std::string name() const { return m_name; } private: std

css选择器指定元素中第几个子元素

tr td:nth-child(2){ background-color:gray; } 就是tr当中的td的第二个td的属性 tr:nth-child(2n+0){ background-color:#F0F0F0; } 这个是tr的2的倍数的 使用公式 (an + b).描述:表示周期的长度,n 是计数器(从 0 开始),b 是偏移值. 在这里,我们指定了下标是 3 的倍数的所有 p 元素的背景色: p:nth-child(3n+0) { background:#ff0000; }

通过css 实现元素中单行内容超出元素宽度,以省略号代替超出内容 效果

css如下: width: **px; // text-overflow: ellipsis; overflow: hidden; white-space: nowrap;