將二叉搜索樹轉換爲雙向鏈表(不創建新的結點)&&數組中出現超過一半的數字

轉換的雙向鏈表是從小到大順序的,而二叉搜索樹如果按照中序遍歷則肯定是這個序列,所以要在中序遍歷的過程中建立雙向鏈表。

而因爲結點的左右指針都要在遍歷中用到,所以創建一個新的遍歷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;
}





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