排序二叉树系列操作
前些天,听一位找到工作的大神谈起面试题,突然说起一道关于排序二叉树的题,题目要求找出比给定值小,但是最接近给定值的节点。
身为小白的我,看到这个题还是比较迷茫的,回来之后好好思考了一下,经过查资料,发现其实就是问查找前驱和后驱的问题。
下面是我自己实现的查找二叉树的系列操作,分享给大家,其中关于前驱后驱的问题,主要是参考算法导论的做法,现在网上的博客似乎这个讲的不是很清楚,所以具体的大家可以看算法导论相关部分。
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 }
浙公网安备 33010602011771号