二叉排序樹spa
插入,刪除和查找的效率都比較高(建立時與二叉樹相同)3d
二叉排序樹又稱爲二叉排序樹,若不爲空樹,則有如下性質:指針
查找:二叉樹的中序遍歷(從小到大)code
插入:比根節點小的插入到二叉樹根節點的左邊,反之插入到右邊blog
刪除:排序
1 #include <stdio.h> 2 #include <stdlib.h> 3 #include <malloc.h> 4 typedef int ElemType; 5 6 typedef struct BiTNode{ 7 ElemType data; 8 struct BiTNode *lchild;//左孩子 9 struct BiTNode *rchild;//右孩子 10 }BiTNode,* BiTree; 11 12 int Delete(BiTree *); 13 14 //遞歸查找二叉樹T中是否存在key 15 //指針f指向T的雙親,其初始值調用值爲NULL 16 //若查找成功,則指針p指向該數據元素結點並返回1 17 //不然指針p指向查找路徑上訪問的最後一個結點,返回0 18 int SearchBST(BiTree T,int key,BiTree f,BiTree *p){ 19 if(!T){//查找不成功 20 *p=f; 21 return 0; 22 }else if(key==T->data){ 23 *p=T; 24 return 1; 25 }else if(key<T->data){ 26 return SearchBST(T->lchild,key,T,p);//在左子樹繼續查找 27 }else{ 28 return SearchBST(T->rchild,key,T,p);//在右子樹繼續查找 29 } 30 } 31 32 //當二叉排序樹T中不存在關鍵字等於key的數據元素樹 33 //插入key並返回1,否者返回0 34 int InsertBST(BiTree *T,ElemType key){ 35 BiTree p,s; 36 if(!SearchBST(*T,key,NULL,&p)){ 37 s=(BiTree)malloc(sizeof(BiTNode)); 38 s->data=key; 39 s->lchild=s->rchild=NULL; 40 if(!p){//查找不到key 41 *T=s; 42 }else if(key<p->data){ 43 p->lchild=s; 44 }else{ 45 p->rchild=s; 46 } 47 return 1; 48 }else{ 49 return 0;//樹中已有關鍵字相同的結點,不在插入 50 } 51 } 52 53 void cenprintf(BiTree tree){ 54 if(tree){ 55 cenprintf(tree->lchild); 56 printf("%d ",tree->data); 57 cenprintf(tree->rchild); 58 } 59 } 60 61 int DeleteBST(BiTree *T,int key){ 62 if(!*T){ 63 return 0; 64 }else{ 65 if(key==(*T)->data){ 66 return Delete(T); 67 }else if(key<(*T)->data){ 68 return DeleteBST(&(*T)->lchild,key); 69 }else{ 70 return DeleteBST(&(*T)->rchild,key); 71 } 72 } 73 } 74 75 int Delete(BiTree *p){ 76 BiTree q,s; 77 if((*p)->rchild==NULL){ 78 q=*p; 79 *p=(*p)->lchild; 80 free(q); 81 } 82 else if((*p)->lchild==NULL){ 83 q=*p; 84 *p=(*p)->rchild; 85 free(q); 86 }else{ 87 q=*p; 88 s=(*p)->lchild; 89 90 while(s->rchild){ 91 //q:始終表明是s是雙親結點 92 //s:用於尋找刪除結點左子樹上最右邊的結點(值最大的結點)(刪除結點的前驅結點) 93 q=s; 94 s=s->rchild; 95 } 96 (*p)->data=s->data; 97 //若是q==p:代表while語句循環體沒有執行,即刪除結點的前驅就是它的左孩子 98 //若是前驅是它的左孩子,就說明他前驅沒有右孩子;就要把左孩子接到原前驅位置上 99 //否者表示前驅不爲刪除結點的左孩子,那麼他可能有左孩子,必定沒有右孩子,因此把前驅左孩子接到原前驅位置上 100 if(q != *p){ 101 q->rchild=s->lchild; 102 }else{ 103 q->lchild=s->lchild; 104 } 105 free(s); 106 } 107 return 1; 108 } 109 110 void main(){ 111 ElemType val; 112 BiTree tree=(BiTree)malloc(sizeof(BiTNode)); 113 tree->data=5; 114 tree->lchild=tree->rchild=NULL; 115 printf("請輸入插入樹的值:"); 116 scanf("%d",&val); 117 while(-1!=val){ 118 InsertBST(&tree,val); 119 printf("請輸入插入樹的值:"); 120 scanf("%d",&val); 121 } 122 cenprintf(tree); 123 printf("\n請輸入刪除結點:"); 124 scanf("%d",&val); 125 DeleteBST(&tree,val); 126 cenprintf(tree); 127 }
平衡二叉樹遞歸
排序二叉樹生成的二叉樹結構與輸入的順序有很是重要的關係,若按循序輸入的話就會生成斜二叉樹,那麼斜二叉樹的效率是很是低的,正是有圖這個緣由就出現了平衡二叉樹;it
1 #define TRUE 1 2 #define FALSE 0 3 #define LH 1//左子樹高 4 #define EH 0//兩子樹同樣高 5 #define RH -1//右子樹高 6 typedef int ElemType; 7 8 typedef struct BiTNode{ 9 ElemType data; 10 int bf;//樹的BF值 11 struct BiTNode *lchild;//左孩子 12 struct BiTNode *rchild;//右孩子 13 }BiTNode,* BiTree; 14 15 //左旋轉 16 void L_Rotate(BiTree *T) 17 { 18 BiTree R = (*T)->rchild; 19 (*T)->rchild = R->lchild; 20 R->lchild = *T; 21 *T = R; 22 return; 23 } 24 //右旋轉 25 void R_Rotate(BiTree *T) 26 { 27 BiTree L = (*T)->lchild; 28 (*T)->lchild = L->rchild; 29 L->rchild = *T; 30 *T = L; 31 return; 32 } 33 34 //T 的左邊高,不平衡,使其平衡,右旋轉,右旋轉前先檢查L->bf, 35 //若是爲RH,L要先進行左旋轉,使T->lchild->bf和T->bf一致 36 void LeftBalance(BiTree* T) 37 { 38 BiTree L,Lr; 39 L = (*T)->lchild; 40 Lr = L->rchild; 41 switch (L->bf) 42 { 43 case LH: 44 L->bf = (*T)->bf = EH; 45 R_Rotate(T); 46 break; 47 case RH: 48 switch (Lr->bf) 49 { 50 case LH: 51 L->bf = EH; 52 (*T)->bf = RH; 53 break; 54 case EH: 55 L->bf = (*T)->bf = EH; 56 break; 57 case RH: 58 L->bf = LH; 59 (*T)->bf = EH; 60 break; 61 } 62 Lr->bf = EH; 63 L_Rotate(&L); 64 R_Rotate(T); 65 break; 66 } 67 } 68 //T 的右邊高,不平衡,使其平衡,左旋轉,左旋轉前先檢查R->bf, 69 //若是爲LH,R要先進行右旋轉,使T->rchild->bf和T->bf一致 70 void RightBalance(BiTree* T) 71 { 72 BiTree R,Rl; 73 R = (*T)->rchild; 74 Rl = R->lchild; 75 switch(R->bf) 76 { 77 case RH: 78 R->bf = (*T)->bf = EH; 79 L_Rotate(T); 80 break; 81 case LH: 82 switch(R->bf) 83 { 84 case LH: 85 R->bf = RH; 86 (*T)->bf = EH; 87 break; 88 case EH: 89 R->bf = (*T)->bf = EH; 90 break; 91 case RH: 92 R->bf = EH; 93 (*T)->bf = LH; 94 break; 95 } 96 Rl->bf = EH; 97 R_Rotate(&R); 98 L_Rotate(T); 99 break; 100 } 101 } 102 103 //taller:標誌樹有沒有長高,長高返回TRUE,否者FALSE 104 int InsertAVL(BiTree *T,ElemType e,int *taller){ 105 if(!(*T)){ 106 *T=(BiTree)malloc(sizeof(BiTNode)); 107 (*T)->bf=EH; 108 (*T)->data=e; 109 (*T)->lchild=(*T)->rchild=NULL; 110 *taller=TRUE; 111 } 112 else{ 113 if(e==(*T)->data){ 114 *taller=FALSE; 115 return FALSE; 116 } 117 if(e<(*T)->data){ 118 //遞歸向左子樹尋找: 119 //尋找到時返回FALSE:這裏進入判斷繼續FALSE返回(一步步退出遞歸) 120 if(!InsertAVL(&(*T)->lchild,e,taller)){ 121 return FALSE; 122 } 123 if(*taller){ 124 //樹長高了,分析樹是否還平衡,並處理不平衡狀況 125 switch((*T)->bf){ 126 case LH: 127 //在左子樹高的狀況下,左子樹又長高了致使的不平衡 128 LeftBalance(T);//通過處理後,長高的一層被平衡到原倒數層(左旋轉/右旋轉) 129 *taller=FALSE; 130 break; 131 case EH: 132 //在平衡的狀況,左子樹長高了 133 (*T)->bf=LH; 134 *taller=TRUE; 135 break; 136 case RH: 137 //右子樹高的狀況下,左子樹長高了 138 (*T)->bf=EH;//兩子樹高度相等 139 *taller=FALSE; 140 break; 141 } 142 } 143 } 144 else{ 145 //遞歸向右子樹尋找: 146 //尋找到時返回FALSE:這裏進入判斷繼續FALSE返回(一步步退出遞歸) 147 if(!InsertAVL(&(*T)->rchild,e,taller)){ 148 return FALSE; 149 } 150 if(*taller){ 151 //樹長高了,分析樹是否還平衡,並處理不平衡狀況 152 switch((*T)->bf){ 153 case LH: 154 //在左子樹高的狀況下,右子樹長高了 155 (*T)->bf=EH;//兩子樹如今等高 156 *taller=FALSE; 157 break; 158 case EH: 159 //在平衡的狀況,右子樹長高了 160 (*T)->bf=RH; 161 *taller=TRUE; 162 break; 163 case RH: 164 //在右子樹高的狀況下,右子樹又長高了致使的不平衡 165 RightBalance(T);//通過處理後,長高的一層被平衡到原倒數層(左旋轉/右旋轉) 166 *taller=FALSE; 167 break; 168 } 169 } 170 } 171 } 172 }
LeftBalance的4中狀況;
RightBalance中的四種狀況