1:概述
搜索樹是一種可以進行插入,搜索,刪除等操作的數據結構,可以用作字典或優先級隊列。二叉搜索樹是最簡單的搜索樹。其左子樹的鍵值<=根節點的鍵值,右子樹的鍵值>=根節點的鍵值。
如果共有n個元素,那么每次操作需要的O(log n)的時間.
常用知識點
- 滿二叉樹 : 一棵深度為k,且有2^k-1個節點的二叉樹,稱為滿二叉樹。這種樹的特點是每一層上的節點數都是最大節點數。
- 完全二叉樹 : 而在一棵二叉樹中,除最后一層外,若其余層都是滿的,並且最后一層要么是滿的,要么在右邊缺少連續若干節點,則此二叉樹為完全二叉樹。具有n個節點的完全二叉樹的深度為floor(log2n)+1。深度為k的完全二叉樹,至少有2^(k-1)個葉子節點,至多有2^k-1個節點。
2.基本操作
- 查找(search)
- 插入(insert)
- 刪除(remove)
3:操作原理
查找
假設查找的值為x,從根節點的值開始比對,如果小於根節點的值,則往左兒子繼續查找,如果大於根節點的值,則往右兒子繼續查找.依次類推.直到當前節點的值等於要查找的值.
以查找數值10為例
插入
按照查找的步驟即可找到插入值應該在的位置
以插入數值6為例
刪除:
有四種情況:
1: // 當前節點無左節點 ,右字節點7覆蓋5,
: 3: // 當前節點無右節點 ,右字節點7覆蓋5,
: 4: // 刪除節點5的左節點沒有右節點, 只需要8作為3的右節點 ,3節點覆蓋5
: 2: 如果以上3中情況都沒有,只需要尋找當前節點的左節點的所有字節點的最大值,用最大值填充5節點 4填充5
5:完整代碼
#include <stdio.h> #include <stdlib.h> struct TNode{ int data; struct TNode *lt; struct TNode *rt; }; struct TNode* insrtTree(struct TNode *t,int key,int i); void printTree(struct TNode *root); struct TNode* delTree(struct TNode* t,int key); int find(struct TNode* t,int key); int arr[1000]={0}; int main(){ int n,m; int i,t; scanf("%d%d",&n,&m); struct TNode *root=NULL; for(i=0;i<n;i++){ scanf("%d",&arr[i]); root=insrtTree(root,arr[i],i); } //t=arr[m-1]; /* if(arr[m-1]==0){ printf("Right child"); }else{ printf("Light child"); }*/ root=delTree(root,10); printTree(root); return 0; } int find(struct TNode* pt,int key){ if(pt==NULL)return NULL; else if(pt->data==key)return 1; else if(pt->data>key) return find(pt->lt,key); else if(pt->data<key) return find(pt->rt,key); } // 刪除節點 struct TNode* delTree(struct TNode* pt,int key){ if(pt==NULL)return NULL; else if(pt->data>key) pt->lt=delTree(pt->lt,key);//尋找左節點 else if(pt->data<key) pt->rt=delTree(pt->rt,key);//尋找右節點 // 找到節點 處理四種情況 else if(pt->lt==NULL){ // 當前節點無左節點 struct TNode* curt=pt->rt; free(pt); return curt; }else if(pt->rt==NULL){// 當前節點無右節點 struct TNode* curt=pt->lt; free(pt); return curt; }else if(pt->lt->rt==NULL){// 當前節點的左節點無右節點 struct TNode* curt=pt->lt; curt->rt=pt->rt; free(pt); return curt; }else{ // 以上不滿足就把左兒子的子孫中最大的節點, 即右子樹的右子樹的...右子樹, //提到需要刪除的節點位置 struct TNode* p; for(p=pt->lt;p->rt->rt!=NULL;p=p->rt); struct TNode* curt=p->lt; p->rt=curt->rt; curt->lt=pt->lt; curt->rt=pt->rt; free(p); return curt; } return pt; } struct TNode* insrtTree(struct TNode *t,int key,int i){ if(t==NULL){ //處理第一個節點 以及子節點為NULL情況 t=(struct TNode*)malloc(sizeof(struct TNode)); t->lt=t->rt=NULL; t->data=key; return t; } if(t->data>key){// 插入左子樹情況 arr[i]=1; t->lt=insrtTree(t->lt,key,i); }else{ // 插入右子樹情況 arr[i]=0; t->rt=insrtTree(t->rt,key,i); } return t; } void printTree(struct TNode *root){ if(root==NULL)return; printf("%d ",root->data); printTree(root->lt); printTree(root->rt); }
說明: 本身學習了 https://blog.csdn.net/li_l_il/article/details/88677927 但是完善了代碼