排序二叉树节点的删除

全部代码

  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 }

 

posted @ 2017-11-21 19:24  c&z  阅读(1786)  评论(0编辑  收藏  举报