排序二叉树的建立,查询与删除
Posted fan-jiaming
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了排序二叉树的建立,查询与删除相关的知识,希望对你有一定的参考价值。
因为排序二叉树的有序性,建立与查询都不是很难,唯一的难点是删除结点的操作,删除节点且要保证该树仍为二叉树且仍满足有序的性质
二叉树的删除操作主要有三种情况:
- 所删除的节点是叶子节点,这样就可以先遍历这个树,然后找到需要删除的节点,把它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(" "); 162 DelNode(&pTree,10); 163 BiTreeTreavelsal(pTree); 164 return 0; 165 }
以上是关于排序二叉树的建立,查询与删除的主要内容,如果未能解决你的问题,请参考以下文章