排序二叉树节点的删除
全部代码
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <assert.h>
4
5 typedef struct node
6 {
7 int nValue;
8 struct node *pLeft;
9 struct node *pRight;
10 }BiTree;
11
12 void Add(BiTree **ppRoot, int nNum)
13 {
14 BiTree *pTemp = NULL;
15 BiTree *pNode = NULL;
16
17 assert(ppRoot!=NULL);
18
19 //临时节点开辟空间
20 pTemp = (BiTree *)malloc(sizeof(BiTree));
21 if(NULL == pTemp)
22 {
23 printf("pTemp空间分配失败!\n");
24 exit(-1);
25 }
26 pTemp->nValue = nNum;
27 pTemp->pLeft = NULL;
28 pTemp->pRight = NULL;
29
30 //空树
31 if(NULL == *ppRoot)
32 {
33 *ppRoot = pTemp;
34 return;
35 }
36
37 pNode = *ppRoot;
38
39 //非空树
40 while(pNode != NULL)
41 {
42 //比根大
43 if(nNum > pNode->nValue)
44 {
45 //向右走
46 if(NULL == pNode->pRight)
47 {
48 pNode->pRight = pTemp;
49 return;
50 }
51 else
52 {
53 pNode = pNode->pRight;
54 }
55 }
56 //比根小
57 else if(nNum < pNode->nValue)
58 {
59 //向左走
60 if(NULL == pNode->pLeft)
61 {
62 pNode->pLeft = pTemp;
63 return;
64 }
65 else
66 {
67 pNode = pNode->pLeft;
68 }
69 }
70 //相等 出错
71 else
72 {
73 //释放临时节点空间
74 free(pTemp);
75 pTemp = NULL;
76 return;
77 }
78 }
79 }
80
81 BiTree *CreateSBT(int arr[], int len)
82 {
83 BiTree *pRoot = NULL;
84 int i;
85
86 assert(arr!=NULL && len>0);
87
88 for(i=0; i<len; ++i)
89 {
90 Add(&pRoot, arr[i]);
91 }
92
93 return pRoot;
94 }
95
96 void BiTreeTraversal(BiTree *pRoot)
97 {
98 if(NULL == pRoot)
99 {
100 return;
101 }
102 printf("%d ", pRoot->nValue);
103 BiTreeTraversal(pRoot->pLeft);
104 BiTreeTraversal(pRoot->pRight);
105 }
106
107 void FindNode(BiTree *pRoot, int nNum, BiTree **pDel, BiTree **pFather)
108 {
109 assert(pRoot!=NULL && pDel!=NULL && pFather!=NULL);
110
111 while(pRoot != NULL)
112 {
113 if(nNum == pRoot->nValue)
114 {
115 *pDel = pRoot;
116 return;
117 }
118 else if(nNum < pRoot->nValue)
119 {
120 *pFather = pRoot;
121 pRoot = pRoot->pLeft;
122 }
123 else
124 {
125 *pFather = pRoot;
126 pRoot = pRoot->pRight;
127 }
128 }
129 }
130
131 void DelNode(BiTree **ppRoot, int nNum)
132 {
133 BiTree *pDel = NULL;
134 BiTree *pMark = NULL;
135 BiTree *pFather = NULL;
136
137 assert(*ppRoot!=NULL && ppRoot!=NULL);
138
139 //查找
140 FindNode(*ppRoot, nNum, &pDel, &pFather);
141
142 //没找到
143 if(NULL == pDel)
144 {
145 return;
146 }
147
148 //找到
149 //检测节点情况
150 //两个孩子
151 while(pDel->pLeft!=NULL && pDel->pRight!=NULL)
152 {
153 //找到左的最右
154 //先标记要删除节点
155 pMark = pDel;
156
157 //向左走一步
158 pFather = pDel;
159 pDel = pDel->pLeft;
160
161 //最右
162 while(pDel->pRight != NULL)
163 {
164 pFather = pDel;
165 pDel = pDel->pRight;
166 }
167
168 //值覆盖
169 pMark->nValue = pDel->nValue;
170 }
171
172 //一个孩子
173 //被删除节点是根节点
174 if(NULL == pFather)
175 {
176 *ppRoot = (*ppRoot)->pLeft?(*ppRoot)->pLeft : (*ppRoot)->pRight;
177 free(pDel);
178 pDel = NULL;
179 return;
180 }
181
182 //被删除节点是父亲的左
183 if(pDel == pFather->pLeft)
184 {
185 pFather->pLeft = pDel->pLeft?pDel->pLeft : pDel->pRight;
186 }
187 //被删除节点是父亲的右
188 else
189 {
190 pFather->pRight = pDel->pRight?pDel->pRight : pDel->pLeft;
191 }
192 free(pDel);
193 pDel = NULL;
194 }
195
196 int main(void)
197 {
198 int arr[] = {1, 7, 3, 4, 5, 6, 7};
199 int len = sizeof(arr)/sizeof(arr[0]);
200 BiTree *pRoot = CreateSBT(arr, len);
201 BiTreeTraversal(pRoot);
202 printf("\n");
203 DelNode(&pRoot, 4);
204 BiTreeTraversal(pRoot);
205
206 return 0;
207 }