将二叉搜索树转换为双向链表(不创建新的结点)&&数组中出现超过一半的数字

转换的双向链表是从小到大顺序的,而二叉搜索树如果按照中序遍历则肯定是这个序列,所以要在中序遍历的过程中建立双向链表。

而因为结点的左右指针都要在遍历中用到,所以创建一个新的遍历plast来记载已经找到的双向链表的最后一个结点,然后将其它结点与其连接。初始值为NULL。

创建和遍历二叉树就不用再说明了,关键是链接的过程,详细参照代码。

#include<iostream>
#include<string>
#include<queue>
using namespace std;
struct Binarytree{  
    int value;  
    Binarytree *left;  
    Binarytree *right;  
};  
int path[20];
Binarytree* Buildtree(){  
    int x;  
    scanf("%d",&x);  
    if(x == 0)  
        return NULL;  
    queue<Binarytree *> Bq;  
    Binarytree* root = (Binarytree *)malloc(sizeof(Binarytree));  
    root->value = x;  
    root->left = NULL;  
    root->right = NULL;  
    Binarytree* temp = root;  
    Bq.push(temp);  
    while(!Bq.empty()){  
        temp = Bq.front();  
        Bq.pop();  
        if(temp->left == NULL){  
            int x;  
            printf("输入%d的左结点\n",temp->value);  
            scanf("%d",&x);  
            if(x!=0){  
                Binarytree * tleft = (Binarytree *)malloc(sizeof(Binarytree));  
                tleft->value = x;  
                tleft->left = tleft->right = NULL;  
                temp->left = tleft;  
                Bq.push(tleft);  
            }  
        }  
        if(temp->right == NULL){  
            int x;  
            printf("输入%d的右结点\n",temp->value);  
            scanf("%d",&x);  
            if(x!=0){  
                Binarytree * tright = (Binarytree *)malloc(sizeof(Binarytree));  
                tright->value = x;  
                tright->left = tright->right = NULL;  
                temp->right = tright;  
                Bq.push(tright);  
            }  
        }  
    }  
    return root;  
}  

Binarytree *plast;
void reverse(Binarytree *pCurrent){
	if(pCurrent->left)
		reverse(pCurrent->left);
	pCurrent->left = plast;
	if(plast)
		plast->right = pCurrent;
	plast = pCurrent;
	if(pCurrent->right)
		reverse(pCurrent->right);
}

int main(){
	Binarytree *root = Buildtree();
	plast = NULL;
	reverse(root);
	plast->right = NULL;
	Binarytree *phead = plast;
	while(phead->left){
		printf("%d->",phead->value);
		phead = phead->left;
	}
	Binarytree *phead1 = phead;
	printf("%d\n",phead->value);
	while(phead1->right){
		printf("%d->",phead1->value);
		phead1 = phead1->right;
	}
	printf("%d\n",phead1->value);
	system("PAUSE");
	return 0;
}

数组中超过一半的数字,有两种思路:

一、联想到求第K大的数这个题目,对数组进行快速排序,一半后面的数肯定是寻找的数字,即找到那个座标就行。

二、利用数组的性质,进行遍历,如果和前面一个数相同,计数加一,否则减去一,如果为0,重新开始计数,多出的那个数字可以找出。

#include<iostream>
#include<string>
int test[] = {1,5,3,5,5,5,2,4,5};

//检查数组是否有效
bool IsValidArray(int *a,int len){
	if(a == NULL || len<=0)
		return false;
	return true;
}
//检查多于一半
bool IsMoreThanHalf(int *a,int len,int result){
	int times =0;
	for(int i=0;i<len;i++){
		if(a[i] == a[result])
			++times;
	}
	if(2*times <= len)
		return false;
	return true;
}
//分治
int partion(int a[],int beg,int end){
	int key = a[beg];
	int i = beg+1,j = end;
	while(i<j){
		while(a[j]>=key && j>beg)
			--j;
		while(a[i]<key && i<j)
			++i;
		if(i<j){
			int temp = a[i];
			a[i] = a[j];
			a[j] = temp;
		}
	}
	int temp = a[j];
	a[j] = key;
	key = temp;
	return j;
}
//用快排获得结果,改变数组
int GetHalf_Partion(int *a,int len){
	if(a == NULL || len<=0)
		return -1;
	int beg = 0,end = len-1;
	int mid = len>>1;
	int result = partion(a,beg,end);
	while(result != mid){
		if(result>mid){
			end = result-1;
			result = partion(a,beg,end);
		}
		else{
			beg = result+1;
			result = partion(a,beg,end);
		}
	}
	return a[result];
}
//统计获得结果,不改变数组
int GetHalf_Count(int a[],int len){
	int result = a[0];
	int times =1;
	for(int i =1;i<len;i++){
		if(times == 0){
			result = a[i];
			times = 1;
		}
		else if(a[i] == result)
			++times;
		else
			--times;
	}
	return result;
}

int main(){
	int result;
	result =GetHalf_Count(test,9);
	printf("%d\n",result);
	result =GetHalf_Partion(test,9);
	printf("%d\n",result);
	system("PAUSE");
	return 0;
}





發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章