排序二叉树的建立,查询与删除

因为排序二叉树的有序性,建立与查询都不是很难,唯一的难点是删除结点的操作,删除节点且要保证该树仍为二叉树且仍满足有序的性质

二叉树的删除操作主要有三种情况:

  • 所删除的节点是叶子节点,这样就可以先遍历这个树,然后找到需要删除的节点,把它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 }
原文地址:https://www.cnblogs.com/fan-jiaming/p/9965790.html