在最坏情况下,找到n个元素中第二小的元素需要n+lgn-2次比较。
/*用树的方法求解第二小元素*/
#include <stdio.h>
#include <vector>
#include <iostream>
using namespace std;
typedef struct lnode{
lnode* lchild;
lnode* rchild;
lnode* next;
int key;
lnode(int k):key(k), lchild(NULL), rchild(NULL), next(NULL){};
lnode():key(0), lchild(NULL), rchild(NULL), next(NULL){};
}lnode;
lnode* createTree(vector<int> &N){
lnode* head = new lnode(N[0]);
lnode* tail = head;
for(int i = 1; i < N.size(); ++i){
lnode *p = new lnode(N[i]);
tail->next = p;
tail = p;
}
lnode* x = head;
//遍历
/*
while(x){
cout << x->key << endl;;
x = x->next;
}
*/
while(head->next != NULL){
lnode* p = head;
head = NULL; //用来存比较完之后
lnode* headtmp;
lnode* headtmptail;
while(p != NULL){
if(p->next != NULL){//可以凑成一对进行比较
if(p->key <= p->next->key){
headtmp = new lnode(p->key);
}else{
headtmp = new lnode(p->next->key);
}
headtmp->lchild = p;
headtmp->rchild = p->next;
p = p->next->next;
}else{//还剩余一个元素
headtmp = new lnode(p->key);
headtmp->lchild = p;
p = p->next;
}
if(head == NULL){
head = headtmp;
headtmptail = head;
}else{
headtmptail->next = headtmp;
headtmptail = headtmp;
}
}
}
return head;
}
int findSecMin(lnode* Tree){
int sec = 0xFFFFFFF;
lnode* head = Tree;
while(head->lchild != NULL){
//来源于左孩子 已经取到右孩子的值 如果右孩子是次大 右孩子的子孙都比他大
if(head->rchild && head->key == head->rchild->key){
//cout << "1"<< endl;
if(sec >= head->lchild->key)
sec = head->lchild->key;
head = head->rchild;
}else if(head->rchild && head->key != head->rchild->key){
//cout << "2" <<endl;
if(head->rchild && sec >= head->rchild->key)
sec = head->rchild->key;
head = head->lchild;
}else{
return sec;
}
}
return sec;
}
int main(){
freopen("input.txt", "r", stdin);
vector<int> nums;
int n, secMin;
lnode* T;
while(scanf("%d", &n) != EOF){
nums.push_back(n);
}
T = createTree(nums);
secMin = findSecMin(T);
cout << secMin << endl;
return 0;
}