二叉樹搜索樹spa
二叉搜索樹:一顆二叉樹能夠爲空:若是不爲空,知足如下性質:3d
1.非空左子樹的全部值小於根節點的鍵值指針
2.非空右子樹的全部值大於根節點的鍵值code
3.左右子樹都是二叉搜索樹blog
查找:1.查找關鍵之2.查找最值遞歸
對於遇到的每一個結點x,都會比較x.key與k的大小,若是相等,就終止查找,不然,決定是繼續往左子樹仍是右子樹查找。所以,整個查找過程就是從根節點開始一直向下的一條路徑,若假設樹的高度是h,那麼查找過程的時間複雜度就是O(h)。element
遞歸作法:io
Pision Find(elementType x,Pision binTree bst) { if(!bst)//空樹 return NULL if(x>bst->data)//去右子樹中查找 return Find(x,bst->right); else if(x<bst->data)//去左子樹中查找 return Find(x,bst->Left) else //找到 return bst; }
此遞歸爲尾遞歸,遞歸效率並不高,通常尾遞歸均可以用循環表示:class
Pision Find(elementType x,Pision binTree bst) { while(bst) { if(x>bst->data)//去右子樹中查找 bst=bst->right); else if(x<bst->data)//去左子樹中查找 bst=x,bst->Left; else //找到 return bst; } return NULL; }
最大元素必定是在樹的最右分支的端結點上(必定沒有右兒子)效率
最小元素必定是在樹的最左分支的端結點上(必定沒有左兒子)
遞歸作法:
Pision FindMin(binTree bst) { if(!bst) return NULL else if(!bst->Left) return bst->Left else FindMin(bst); return bst; } Pision FindMax(binTree bst) { if(!bst) return NULL else if(!bst->Right) return bst->Right else FindMax(bst); return bst; }
迭代作法:
Pision FindMin(binTree bst) { if(bst) { while(bst->Left) bst=bst->Left; } return bst; } Pision FindMax(binTree bst) { if(bst) { while(bst->Right) bst=bst->Right; } return bst; }
插入
(關鍵是找到應該插入的位置)
BST的插入過程很是簡單,很相似與二叉樹搜索樹的查找過程。當須要插入一個新結點時,從根節點開始,迭代或者遞歸向下移動,直到遇到一個空的指針NILL,須要插入的值即被存儲在該結點位置。
遞歸作法:
binTree insert( elemenType x,binTree bst) { if(!bst) { bst=(binTree)malloc(sizeof(treeNode)); bst->data=x; bst->Left=bst->Right=NULL; } else { if(x<bst->data) { bst->Left=insert(x,bst->Left); } else if(x>bst->Right) { bst->Right=insert(x,bst->Right); } //若是x已經存在,則什麼都不作 } return bst; }
迭代作法:
void insert( elemenType x,binTree bst) { binTree p=(binTree)malloc(sizeof(treeNode)); binTree temp=NULL; p->data=x; p->Left=p->Right=NULL; if(!bst) { bst=p; return ; } while(bst) { temp=bst; if(x>bst->data) bst=bst->Right else if(x<bst->data) bst=bst->Left; else return ; } if(p->data>temp->data) temp->Right=p; else if(p->data<temp->data) temp->Left=p; }
刪除
二叉搜索樹的結點刪除比插入較爲複雜,整體來講,結點的刪除可歸結爲三種狀況:
由於左子樹的最大值和右子樹的最小值必定不會有兩個結點
遞歸方法:
binTree Delete(elementype x,binsTree bst) { binTree temp; if(!bst) printf("沒找到"); else if(x<bst->data) bst->Left=Delete(x,bst->Left);//左子樹遞歸刪除 else if(x>bst->data) bst->Right=Delete(x,bst->Right);//右子樹遞歸刪除 else//找到要刪除的結點 { if(bst->Left&&bst->Right)//該刪除的結點有左右孩子 { temp=FindMin(bst->Right);//去右子樹中找最小值代替該刪除結點 bst->data=temp->data; bst->Right=Delete(bst->data,bst->Right);//在右子樹中刪除最小值 } else { if(!bst->Left&&!bst->Left)//無孩子結點 { free(bst); return NULL; } temp=bst; if(!bst->Left)//無左子樹 bst=bst->Right; else(!bst->Right)//無右子樹 bst=bst->Left; free(temp); } } return bst; }
二插搜索樹的調整:
未完