排序二叉树系列操作

前些天,听一位找到工作的大神谈起面试题,突然说起一道关于排序二叉树的题,题目要求找出比给定值小,但是最接近给定值的节点。

身为小白的我,看到这个题还是比较迷茫的,回来之后好好思考了一下,经过查资料,发现其实就是问查找前驱和后驱的问题。

下面是我自己实现的查找二叉树的系列操作,分享给大家,其中关于前驱后驱的问题,主要是参考算法导论的做法,现在网上的博客似乎这个讲的不是很清楚,所以具体的大家可以看算法导论相关部分。

 

  1 #include <stdio.h>
  2 
  3 typedef struct node
  4 {
  5     int m_nValue;
  6     struct node *m_pLeft;
  7     struct node *m_pRight;
  8     struct node *m_pParent;
  9 }BinarySearchTreeNode;
 10 
 11 void InsertKey(BinarySearchTreeNode **pRoot, int nKey)
 12 {
 13     BinarySearchTreeNode *pNode = new BinarySearchTreeNode();
 14     pNode->m_nValue = nKey;
 15     pNode->m_pLeft = NULL;
 16     pNode->m_pRight = NULL;
 17     pNode->m_pParent = NULL;
 18 
 19     if(*pRoot == NULL)
 20     {
 21         *pRoot = pNode;
 22         return;
 23     }
 24 
 25     if((*pRoot)->m_pLeft == NULL && (*pRoot)->m_nValue > nKey)
 26     {
 27         pNode->m_pParent = (*pRoot);
 28         (*pRoot)->m_pLeft = pNode;
 29         return;
 30     }
 31 
 32     if((*pRoot)->m_pRight == NULL && (*pRoot)->m_nValue < nKey)
 33     {
 34         pNode->m_pParent = (*pRoot);
 35         (*pRoot)->m_pRight = pNode;
 36         return;
 37     }
 38 
 39     if(nKey > (*pRoot)->m_nValue)
 40         InsertKey(&(*pRoot)->m_pRight, nKey);
 41     
 42     if(nKey < (*pRoot)->m_nValue)
 43         InsertKey(&(*pRoot)->m_pLeft, nKey);
 44 }
 45 
 46 BinarySearchTreeNode *Search(BinarySearchTreeNode *pRoot, int nValue)
 47 {
 48     if(pRoot == NULL)
 49         return NULL;
 50 
 51     if(nValue == pRoot->m_nValue)
 52         return pRoot;
 53     else if(nValue > pRoot->m_nValue)
 54         return Search(pRoot->m_pRight, nValue);
 55     else
 56         return Search(pRoot->m_pLeft, nValue);
 57 }
 58 
 59 BinarySearchTreeNode *SearchMin(BinarySearchTreeNode *pRoot)
 60 {
 61     if(pRoot == NULL)
 62         return NULL;
 63 
 64     if(pRoot->m_pLeft == NULL)
 65         return pRoot;
 66     else
 67         return SearchMin(pRoot->m_pLeft);
 68 }
 69 
 70 BinarySearchTreeNode *SearchMax(BinarySearchTreeNode *pRoot)
 71 {
 72     if(pRoot == NULL)
 73         return NULL;
 74 
 75     if(pRoot->m_pRight == NULL)
 76         return pRoot;
 77     else
 78         return SearchMax(pRoot->m_pRight);
 79 }
 80 
 81 BinarySearchTreeNode *SearchPredecessor(BinarySearchTreeNode *pNode)
 82 {
 83     if(pNode == NULL)
 84         return NULL;
 85 
 86     if(pNode->m_pLeft != NULL)
 87         return SearchMax(pNode->m_pLeft);
 88     else
 89     {
 90         BinarySearchTreeNode *pTemp = pNode->m_pParent;
 91         while(pTemp != NULL && pTemp->m_pLeft == pNode)
 92         {
 93             pNode = pTemp;
 94             pTemp = pNode->m_pParent;
 95         }
 96         return pTemp;
 97     }
 98 }
 99 
100 BinarySearchTreeNode *SearchSuccessor(BinarySearchTreeNode *pNode)
101 {
102     if(pNode == NULL)
103         return NULL;
104 
105     if(pNode->m_pRight != NULL)
106         return SearchMin(pNode->m_pRight);
107     else
108     {
109         BinarySearchTreeNode *pTemp = pNode->m_pParent;
110         while(pTemp != NULL && pTemp->m_pRight == pNode)
111         {
112             pNode = pTemp;
113             pTemp = pNode->m_pParent;
114         }
115         return pTemp;
116     }
117 }
118 
119 void CreateBinarySearchTree(BinarySearchTreeNode **pRoot, int *pKeyArray, int nLength)
120 {
121     for(int i = 0; i < nLength; i++)
122         InsertKey(&(*pRoot), pKeyArray[i]);
123 }
124 
125 int DeleteNode(BinarySearchTreeNode **pRoot, int nKey)
126 {
127     BinarySearchTreeNode *pNode = Search((*pRoot), nKey);
128     if(pNode == NULL)
129         return 0;
130 
131     // 1. 删除节点是页节点(直接删除节点)
132     if(pNode->m_pLeft == NULL && pNode->m_pRight == NULL)
133     {
134         if(pNode->m_pParent->m_pLeft == pNode)
135         {
136             pNode->m_pParent->m_pLeft = NULL;
137             delete pNode;
138         }
139         else
140         {
141             pNode->m_pParent->m_pRight = NULL;
142             delete pNode;
143         }
144     }
145     // 2. 删除节点只有一个子节点
146     else if(pNode->m_pLeft != NULL && pNode->m_pRight == NULL)
147     {
148         pNode->m_pLeft->m_pParent = pNode->m_pParent;
149         
150         // 如果待删节点为根节点
151         if(pNode->m_pParent == NULL)
152             *pRoot = pNode->m_pLeft;
153 
154         else if(pNode->m_pParent->m_pLeft == pNode)
155             pNode->m_pParent->m_pLeft = pNode->m_pLeft;
156         else
157             pNode->m_pParent->m_pRight = pNode->m_pLeft;
158 
159         delete pNode;
160     }
161     // 2. 删除节点只有一个子节点
162     else if(pNode->m_pRight != NULL && pNode->m_pLeft == NULL)
163     {
164         pNode->m_pRight->m_pParent = pNode->m_pParent;
165 
166         if(pNode->m_pParent == NULL)
167             *pRoot = pNode->m_pRight;
168         else if(pNode->m_pParent->m_pLeft == pNode)
169             pNode->m_pParent->m_pLeft = pNode->m_pRight;
170         else
171             pNode->m_pParent->m_pRight = pNode->m_pRight;
172     }
173     // 3. 删除节点有左右两个子节点
174     else
175     {
176         BinarySearchTreeNode *pSuccessor = SearchSuccessor(pNode);
177         int nTempValue = pSuccessor->m_nValue;
178         DeleteNode(pRoot, nTempValue);
179         pNode->m_nValue = nTempValue;
180     }
181     return 1;
182 }
183 
184 int main()
185 {
186     int data[6] = {5, 8, 2, 0, 1, 7};
187 
188     BinarySearchTreeNode *pRoot = NULL;
189 
190     CreateBinarySearchTree(&pRoot, data, 6);
191 
192     printf("Max: %d\n", SearchMax(pRoot)->m_nValue);
193     printf("Min: %d\n", SearchMin(pRoot)->m_nValue);
194 
195     printf("Root: %d\n", pRoot->m_nValue);
196     printf("Root Predecessor: %d\n", SearchPredecessor(pRoot)->m_nValue);
197     printf("Root Successor: %d\n", SearchSuccessor(pRoot)->m_nValue);
198     printf("Search: %d\n", Search(pRoot, 7)->m_nValue);
199     printf("Search Node Predecessor: %d\n", SearchPredecessor(Search(pRoot, 7))->m_nValue);
200     printf("Search Node Successor: %d\n", SearchSuccessor(Search(pRoot, 7))->m_nValue);
201     int isDelete = DeleteNode(&pRoot, 8);
202     printf("Delete 8: %d\n", isDelete);
203     return 0;
204 }

 

posted @ 2013-04-15 17:15  ITeed  阅读(173)  评论(0)    收藏  举报