二叉排序樹

/*
	二叉排序樹,這裏例子的結點只給出關鍵字 key
	插入過程相當於動態排序,可以有折半搜索和線性搜索的性質
	最差情況是導致線性搜索,例如下面的例子都是右子樹 
	改進可以用平衡二叉樹或稱AVL樹或稱紅黑樹,從而壓縮樹深度,越接近折半搜索 
*/
#include<iostream>
#include<queue>
using namespace std;

struct node {
	int key;
	node *lchild;
	node *rchild;
};

node *root;
node *father;

//若找到返回結點的指針,沒找到返回NULL。傳入參數,記錄當前查找結點的父結點指針
node *find(int key) {
	//這裏查找root若空,父指針這裏也空.當在父節點找到了,父指針也爲空
	father=NULL;
	if(!root) {
		return NULL;
	}
	node *temp=root;
	while(temp) {
		if(key==temp->key) {
			return temp;
		} else if(key<root->key) {
			father=temp;
			temp=temp->lchild;
		} else {
			father=temp;
			temp=temp->rchild;
		}
	}
	return NULL;
}

bool insert(int key) {
	if(!root) {
		root=new node();
		root->key=key;
		printf("空樹,已插入爲根結點!key=%d\n",key);
		return true;
	}
	//root!=NULL的情況
	father=NULL;
	node *p=find(key);
	if(p) {
		return  true;
	}
	//在這裏father不可能是空的
	if(father) {
		node *temp=new node();
		temp->key=key;
		if(key<father->key) {
			father->lchild=temp;
		} else {
			father->rchild=temp;
		}
		printf("已插入!\n");
		return true;
	}
}

//獲取結點下子樹的最小key結點,即最左邊的結點
node *getmin(node *root) {
	if(!root)return NULL;
	if(!root->lchild) {
		return root;
	}
	return getmin(root->lchild);
}

//二叉排序樹刪除:!只刪除一個結點,刪除後其他結點仍保持二叉排序樹的性質(有兩種方法)
//有三種情況,刪樹的根結點,刪葉結點,刪有子樹的結點(父結點不是樹的根結點) 
bool del(int key) {
	if(!root)return false;
	node *temp=find(key);
	if(!temp)return false;
	//別漏了刪除根節點的情況
	if(temp==root) {
		node *l=getmin(root->rchild);
		l->lchild=root->lchild;
		root=root->rchild;
		return true;
	}
	//別漏了葉節點情況
	if(!temp->lchild&&!temp->rchild) {
		if(father->lchild==temp) {
			father->lchild=NULL;
		} else {
			father->rchild=NULL;
		}
		delete temp;
		return true;
	}

	if(father->lchild==temp) {
		if(temp->rchild) {
			father->lchild=temp->rchild;
			if(temp->lchild) {
				//這裏的temp->rchild已判斷不爲空,返回的肯定不爲空
				node *p=getmin(temp->rchild);
				p->lchild=temp->lchild;
				return true;
			}
		} else if(temp->lchild) {
			father->lchild=temp->lchild;
			return true;
		}
	} else if(father->rchild==temp) {
		if(temp->rchild) {
			father->rchild=temp->rchild;
			if(temp->lchild) {
				//這裏的temp->rchild已判斷不爲空,返回的肯定不爲空
				node *p=getmin(temp->rchild);
				p->lchild=temp->lchild;
				return true;
			}
		} else if(temp->lchild) {
			father->rchild=temp->lchild;
			return true;
		}
	}
	return false;
}

void out(node *root) {
	if(root) {
		out(root->lchild);
		out(root->rchild);
		printf("%d ",root->key);
	}
}

int main() {
	insert(1);
	insert(2);
	insert(3);
	insert(4);
	insert(5);
	insert(6);
	out(root);
	printf("\n");
	del(1);
	del(4);
	del(6);
	del(3);
	printf("del...\n");
	out(root);
	printf("\n");
	return 0;
}

發佈了81 篇原創文章 · 獲贊 8 · 訪問量 3萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章