1. 程式人生 > >排序二叉樹的建立,查詢與刪除

排序二叉樹的建立,查詢與刪除

因為排序二叉樹的有序性,建立與查詢都不是很難,唯一的難點是刪除結點的操作,刪除節點且要保證該樹仍為二叉樹且仍滿足有序的性質

二叉樹的刪除操作主要有三種情況:

  • 所刪除的節點是葉子節點,這樣就可以先遍歷這個樹,然後找到需要刪除的節點,把它free掉就好
  • 所刪除的節點只有一個左子結點,或者只有一個右子結點,則把該節點的子結點變為它父結點的子結點 ,然後free掉這個結點
  • 就是最麻煩的一類,刪除的結點既有左子結點又有右子結點,這時,我們的處理方式是,用左子樹的最右結點,就是值最大那個葉節點的值覆蓋掉要刪除的結點,並free掉那個葉子節是

具體實現程式碼如下:

  1 #include <iostream>
  2
#include <cstdio> 3 #include <cstring> 4 #include <algorithm> 5 #include <string> 6 #include <queue> 7 #include <vector> 8 #include <cmath> 9 #include <iomanip> 10 #include <malloc.h> 11 12 #define INF 0x3f3f3f3f 13 #define
FRER() freopen("in.txt", "r", stdin) 14 #define FREW() freopen("out.txt", "w", stdout) 15 16 using namespace std; 17 18 typedef struct node { 19 int nValue; 20 struct node *pLeft; 21 struct node *pRight; 22 }BinaryTree; 23 24 void InsertNode(BinaryTree **pTree, int
nNum) { 25 BinaryTree *pTemp = NULL; 26 pTemp = (BinaryTree*)malloc(sizeof(BinaryTree)); 27 pTemp->nValue = nNum; 28 pTemp->pLeft = NULL; 29 pTemp->pRight = NULL; 30 31 //空樹 32 if(*pTree == NULL) { 33 *pTree = pTemp; 34 return ; 35 } 36 37 //非空樹 38 BinaryTree *pNode = *pTree; 39 while(1) { 40 if(nNum > pNode->nValue) { 41 //去右側 42 if(pNode->pRight == NULL) { 43 pNode->pRight = pTemp; 44 return; 45 } 46 47 //向右走 48 pNode = pNode->pRight; 49 } 50 else if(nNum < pNode->nValue) { 51 //去左側 52 if(pNode->pLeft == NULL) { 53 pNode->pLeft = pTemp; 54 return ; 55 } 56 57 //向左走 58 pNode = pNode->pLeft; 59 } 60 //相等 61 else { 62 free(pTemp); 63 pTemp = NULL; 64 return ; 65 } 66 } 67 } 68 69 void CreateBST(int arr[], int nLength, BinaryTree **pTree) { 70 if(arr == NULL || nLength <= 0) 71 return ; 72 for(int i = 0; i < nLength; ++i) { 73 InsertNode(pTree, arr[i]); 74 } 75 } 76 77 void BiTreeTreavelsal(BinaryTree *pNode) { 78 if(pNode == NULL) return ; 79 printf("%d ", pNode->nValue); 80 BiTreeTreavelsal(pNode->pLeft); 81 BiTreeTreavelsal(pNode->pRight); 82 } 83 84 void Search(BinaryTree *pTree, int nNum, BinaryTree **pDel, BinaryTree **pFather) { 85 while(pTree != NULL) { 86 if(pTree->nValue == nNum) { 87 *pDel = pTree; 88 return ; 89 } 90 else if(pTree->nValue > nNum) { 91 *pFather = pTree; 92 pTree = pTree->pLeft; 93 } 94 else { 95 *pFather = pTree; 96 pTree = pTree->pRight; 97 } 98 } 99 } 100 101 void DelNode(BinaryTree **pTree, int nNum) { 102 if(*pTree == NULL) return ; 103 104 //查詢 105 BinaryTree *pDel = NULL; 106 BinaryTree *pFather = NULL; 107 108 Search(*pTree, nNum, &pDel, &pFather); 109 110 //二叉樹上沒有該點 111 if(pDel == NULL) return ; 112 113 BinaryTree *pMark = NULL; 114 if(pDel->pLeft != NULL && pDel->pRight != NULL) { 115 116 //找左的最右 117 pMark = pDel; 118 119 //向左走一步 120 pFather = pDel; 121 pDel = pDel->pLeft; 122 123 while(pDel->pRight != NULL) { 124 pFather = pDel; 125 pDel = pDel->pRight; 126 } 127 128 //值覆蓋 129 pMark->nValue = pDel->nValue; 130 } 131 132 //被刪除的結點是根結點 133 if(pFather == NULL) { 134 *pTree = pDel->pLeft ? pDel->pLeft : pDel->pRight; 135 free(pDel); 136 pDel = NULL; 137 return ; 138 } 139 140 //被刪除的結點不是根結點 141 if(pDel == pFather->pLeft) { 142 pFather->pLeft = pDel->pLeft ? pDel->pLeft : pDel->pRight; 143 free(pDel); 144 pDel = NULL; 145 return ; 146 } 147 else { 148 pFather->pRight = pDel->pLeft ? pDel->pLeft : pDel->pRight; 149 free(pDel); 150 pDel = NULL; 151 return ; 152 } 153 } 154 155 int main() 156 { 157 int arr[] = {10,38,2,100,80,15,1,8,16}; 158 BinaryTree *pTree = NULL; 159 CreateBST(arr,sizeof(arr)/sizeof(arr[0]),&pTree); 160 BiTreeTreavelsal(pTree); 161 printf("\n"); 162 DelNode(&pTree,10); 163 BiTreeTreavelsal(pTree); 164 return 0; 165 }