今天學到了搜索二叉樹趕緊來鞏固一下。
簡單介紹一下數據結構中的樹 ,在《離散數學》中樹的定義是:連通無迴路的圖 。
樹(tree)是包含n個結點的有窮集,其中 每個元素稱爲節點,樹中邊的條數 爲 n - 1。
相關術語:
節點的度:一個節點含有的子樹的個數稱爲該節點的度;
葉節點或終端節點:度爲0的節點稱爲葉節點;
非終端節點或分支節點:度不爲0的節點;
雙親節點或父節點:若一個節點含有子節點,則這個節點稱爲其子節點的父節點;
孩子節點或子節點:一個節點含有的子樹的根節點稱爲該節點的子節點;
兄弟節點:具有相同父節點的節點互稱爲兄弟節點;
樹的度:一棵樹中,最大的節點的度稱爲樹的度;
節點的層次:從根開始定義起,根爲第1層,根的子節點爲第2層,以此類推;
樹的高度或深度:樹中節點的最大層次;
堂兄弟節點:雙親在同一層的節點互爲堂兄弟;
節點的祖先:從根到該節點所經分支上的所有節點;
子孫:以某節點爲根的子樹中任一節點都稱爲該節點的子孫。
來介紹一下二叉樹 :每個節點最多含有兩個子樹的樹稱爲二叉樹。二叉樹有完全二叉樹和滿二叉樹;滿二叉樹是除最後一層無任何子節點外,每一層上的所有結點都有兩個子結點二叉樹,完全二叉樹是若設二叉樹的深度爲h,除第 h 層外,其它各層 (1~h-1) 的結點數都達到最大個數,第 h 層所有的結點都連續集中在最左邊。
好了那麼什麼是搜索二叉樹呢?搜索二叉樹(又:二叉查找樹,二叉排序樹)它或者是一棵空樹,或者是具有下列性質的二叉樹: 若它的左子樹不空,則左子樹上所有結點的值均小於它的根結點的值; 若它的右子樹不空,則右子樹上所有結點的值均大於它的根結點的值; 它的左、右子樹也分別爲二叉排序樹。搜索二叉樹可以方便的查找樹中的最大值或最小值。
今天學習的搜索二叉樹的操作有:建樹(搜索二叉樹),查找最小(大)值,刪除節點。
首先介紹建樹(搜索二叉樹):話不多說直接上代碼:
typedef struct TNode *Position;
typedef Position BinTree;
typedef int ElementType;
struct TNode{
ElementType Data;
BinTree Left;
BinTree Right;
};
BinTree Insert( BinTree BST, ElementType X ){
BinTree T = (BinTree)malloc(sizeof(struct TNode)); //創建一個用於儲存X的節點。
T->Data = X;//初始化T
T->Left = NULL;
T->Right = NULL;
if (BST==NULL){//這是遞歸的終止條件
BST = T;
return T;
}
if (BST->Data<X)BST->Right=Insert(BST->Right,X);//若數據大於該節點數據那麼它肯定在節點的右邊;
else BST->Left = Insert(BST->Left,X);//若數據小於該節點數據那麼它肯定在節點的左邊;
}
然後介紹查找最小值:
ElementType FindMin( BinTree BST ){
if (BST->Left == NULL) //遞歸查找的結束條件
return BST->Data;
FindMin(BST->Left); // 根據搜索二叉樹的性質左節點的數據肯定比其父節點和兄弟節點的數據大所以只需要一隻尋找左節點的數據即可
}
接下來就是刪除節點了,刪除節點有點困難 ,原因是刪除節點會有三種情況:
① 該節點的左節點和右節點 均是NULL 這是直接讓該節點的父節點指向NULL即可。
②該節點有一個左節點或右節點,那麼我們直接讓其父節點指向該節點的子節點即可。
③最麻煩的是該節點有兩個子節點。我們要在保證搜索二叉樹性質的前提下把節點刪除。這時我們有兩種情況可以選擇:一種時找到該節點左子樹的最大值取代該節點然後刪除左子樹最大值節點,最大值節點肯定是 ① 或 ②兩種情況的一種。第二種是找到該節點右子樹的最小值代替該節點,然後刪除右子樹最小值節點。 OK,分析完畢之後 代碼奉上:
BinTree Delete( BinTree BST, ElementType X ){
if (BST->Data!=X){ //利用遞歸查找數據X的所在地
if (BST->Data>X&&BST->Left==NULL){//用兩個判斷來作爲沒有找到X時的結束語句
printf("Not Found!\n");
return BST;
}
if (BST->Data<X&&BST->Right==NULL){
printf("Not Found!\n");
return BST;
}
if (BST->Data>X) BST->Left=Delete(BST->Left,X);
else BST->Right=Delete(BST->Right,X);
}
else {
BinTree T = BST;
if (BST->Left==NULL&&BST->Right==NULL){ //一個if和後面的兩個else if 是上文說的前兩種情況。
BST=NULL;
free(T);
return BST;
}
else if(BST->Left==NULL&&BST->Right!=NULL){
BST = BST->Right;
free(T);
return BST;
}
else if(BST->Left!=NULL&&BST->Right==NULL){
BST = BST->Left;
free(T);
return BST;
}
else { //當被刪除節點有左右子節點時;
BST->Data = FindMin(BST->Right);
BST->Right = Delete(BST->Right,BST->Data);
}
}
}
以上就是今天學的搜索二叉樹的知識!