// 头文件 BSTree.h #ifndef _H_BSTREE_H_ #define _H_BSTREE_H_ #include <iostream> #include <stdio.h> #include <stdlib.h> #include <time.h> using namespace std; typedef struct BSTreeNode { struct BSTreeNode* m_pLeft; // 左孩子 struct BSTreeNode* m_pRight; // 右孩子 struct BSTreeNode* m_pParent; // 父亲节点 int m_nValue; BSTreeNode(int val):m_pLeft(NULL), m_pRight(NULL), m_pParent(NULL),m_nValue(val){}; }BSTree; // 输出数组元素 void printArr(int* arr, int len); // 随机生成数组数据 void randArr(int* arr, int len, int maxVal); // func proto // 函数名后面带_v2的均为非递归实现 // 向二叉查找树插入元素val void insert2BSTree(BSTree* &root, BSTree* pParent, int val); void insert2BSTree_v2(BSTree* &root, int val); // 中序遍历二叉查找树 void inorderBSTree(BSTree* &root); // 查找元素,返回该节点的指针 BSTree* searchBSTree(BSTree* &root, int val); BSTree* searchBSTree_v2(BSTree* &root, int val); // 删除某一节点 bool removeFromBSTree(BSTree* &root, int val); // 清空二叉查找树 void emptyBSTree(BSTree* &root); // 找到最下节点 BSTree* findMin(BSTree* &root); BSTree* findMin_v2(BSTree* &root); // 找到最大节点 BSTree* findMax(BSTree* &root); BSTree* findMax_v2(BSTree* &root); // 找到元素的后继节点 BSTree* findSuccessor(BSTree* &root, int val); // 找到元素的前驱节点 BSTree* findPredecessor(BSTree* &root, int val); #endif // cpp文件 BSTree.cpp #include "BSTree.h" // 输出数组元素 void printArr(int* arr, int len) { for (int i = 0; i < len; i++) { printf("%d ", *(arr+i)); } } // 随机生成数组数据 void randArr(int* arr, int len, int maxVal) { srand((int)time(0)); for (int i = 0; i < len; i++) { *(arr+i) = rand() % maxVal; } } // 向二叉查找树插入元素val void insert2BSTree(BSTree* &root,BSTree* pParent,int val) { if (root == NULL) { root = new BSTreeNode(val); root->m_pParent = pParent; if (!root) { printf("error: alloc failed, exit!!/n"); return; } } // root != NULL else if (val <= root->m_nValue) { insert2BSTree(root->m_pLeft, root, val); } else if (val >= root->m_nValue) { insert2BSTree(root->m_pRight, root, val); } } // 插入的非递归版本 void insert2BSTree_v2(BSTree* &root, int val) { if (root == NULL) // 空树 { root = new BSTreeNode(val); return; } BSTree* pChild = root; BSTree* pParent = NULL; while(pChild != NULL) { pParent = pChild; // 保存父节点 if (val > pChild->m_nValue) { pChild = pChild->m_pRight; } else { pChild = pChild->m_pLeft; } } BSTreeNode* node = new BSTreeNode(val); node->m_pParent = pParent; // 父节点 if (pParent->m_nValue < node->m_nValue) { pParent->m_pRight = node; // 右孩子 } else { pParent->m_pLeft = node; // 左孩子 } } // 中序遍历二叉查找树 void inorderBSTree(BSTree* &root) { if (root != NULL) { inorderBSTree(root->m_pLeft); cout << root->m_nValue << " "; inorderBSTree(root->m_pRight); } } // 查找元素,返回该节点的指针 BSTree* searchBSTree(BSTree* &root, int val) { if (!root) { return NULL; } else { if (root->m_nValue == val) { return root; } else if (val < root->m_nValue) { return searchBSTree(root->m_pLeft, val); } else // val > root->m_nValue { return searchBSTree(root->m_pRight, val); } } } BSTree* searchBSTree_v2(BSTree* &root, int val) { if (root) { // 否则从树跟开始 BSTree* pRoot = root; while(pRoot != NULL) // 当前节点不为空 { if (val == pRoot->m_nValue) { return pRoot; // 直接返回 } if (val < pRoot->m_nValue) { pRoot = pRoot->m_pLeft; } else { pRoot = pRoot->m_pRight; } } } return NULL; } // 清空二叉查找树, 先根遍历 void emptyBSTree(BSTree* &root) { if (root) { emptyBSTree(root->m_pLeft); emptyBSTree(root->m_pRight); cout << root->m_nValue << " "; delete root; } root = NULL; } // 删除某一节点 bool removeFromBSTree(BSTree* &root, int val) { BSTree* pCurr = NULL; pCurr = searchBSTree_v2(root, val); // 找到当前元素位置 if (!pCurr) { return false; } BSTree* pSuccessor = NULL; if (pCurr->m_pLeft == NULL || pCurr->m_pRight == NULL) // 有一个或者无孩子, pSuccessor指向被删节点 { pSuccessor = pCurr; } else // 有俩孩子,pSuccessor指向被删节点后继,后继为右子树最左节点,最多一个右孩子 { pSuccessor = findSuccessor(root, pCurr->m_nValue); } // pChild指向pSuccessor的非空儿子,pSuccessor最多一个儿子 BSTree* pChild = NULL; if (pSuccessor->m_pLeft != NULL) // 后继有左孩子 { pChild = pSuccessor->m_pLeft; } else { pChild = pSuccessor->m_pRight; } if (pChild != NULL) // pSuccessor有孩子,修改指针,删除pSuccessor { pChild->m_pParent = pSuccessor->m_pParent; } if (pSuccessor->m_pParent == NULL) // pSuccessor为根 { root = pChild; // 删除根后更新根 } else { if (pSuccessor == pSuccessor->m_pParent->m_pLeft) // pSuccessor 为左孩子 { pSuccessor->m_pParent->m_pLeft = pChild; } else // pSuccessor 为右孩子 { pSuccessor->m_pParent->m_pRight = pChild; } } if (pSuccessor != pCurr) // pCurr的后继就是要被删除的结点(pCurr有俩孩子),拷贝数据 { pCurr->m_nValue = pSuccessor->m_nValue; } // 删除后继 pSuccessor delete pSuccessor; return true; } // 找到最下节点 BSTree* findMin(BSTree* &root) { if (!root) { return NULL; } if (root->m_pLeft == NULL) { return root; } else { return findMin(root->m_pLeft); } } BSTree* findMin_v2(BSTree* &root) { BSTree* pRoot = root; while (pRoot->m_pLeft != NULL) { pRoot = pRoot->m_pLeft; } return pRoot; } // 找到最大节点 BSTree* findMax(BSTree* &root) { if (!root) { return NULL; } if (root->m_pRight == NULL) { return root; } else { return findMax(root->m_pRight); } } BSTree* findMax_v2(BSTree* &root) { BSTree* pRoot = root; while (pRoot->m_pRight != NULL) { pRoot = pRoot->m_pRight; } return pRoot; } // 找到元素的后继节点 BSTree* findSuccessor(BSTree* &root, int val) { BSTree* pCurr = searchBSTree_v2(root, val); // 找到当前元素位置 if (!pCurr) { return NULL; } if (pCurr->m_pRight) //有右子树 { return findMin_v2(pCurr->m_pRight); // 右子树的最小 } // 无右子树,从当前节点开始向上查找, // 直到遇到某个是其父节点的左儿子的节点为止 BSTree* pParent = NULL; pParent = pCurr->m_pParent; while(pParent != NULL && pCurr == pParent->m_pRight) { pCurr = pParent; pParent = pCurr->m_pParent; // 向上走 } return pParent; } // 找到元素的前驱节点 BSTree* findPredecessor(BSTree* &root, int val) { BSTree* pCurr = searchBSTree_v2(root, val); // 找到当前元素位置 if (!pCurr) { return NULL; } if (pCurr->m_pLeft) //有左子树 { return findMax_v2(pCurr->m_pLeft); // 左子树的最大 } // 无左子树,从当前节点开始向上查找, // 直到遇到某个是其父节点的右儿子的节点为止 BSTree* pParent = NULL; pParent = pCurr->m_pParent; while(pParent != NULL && pCurr == pParent->m_pLeft) { pCurr = pParent; pParent = pCurr->m_pParent; // 向上走 } return pParent; } // 测试文件 mainEntry.cpp // copyright by Kennie.D.John #include "BSTree.h" int main(int argc, char* argv[]) { cout << "hello, i am Kennie" << endl; int len = 20; int* arr = new int[len]; randArr(arr, len, 100); cout << "source array data: " << endl; printArr(arr, len); // test func insert2BSTree BSTree* root = NULL; for (int i = 0; i < len; i++) { insert2BSTree(root, NULL, arr[i]); //insert2BSTree_v2(root, arr[i]); } cout << endl; cout << "inorder BSTree: " << endl; inorderBSTree(root); // test func searchBSTree BSTree* toBeFound = NULL; int valToBeFound = 63; //toBeFound = searchBSTree(root, valToBeFound); toBeFound = searchBSTree_v2(root, valToBeFound); if (toBeFound != NULL) { cout << endl; cout << toBeFound->m_nValue << "found " << endl; } else { cout << endl; cout << valToBeFound << " not found" << endl; } // test func findMin BSTree* minNode = NULL; //minNode = findMin(root); minNode = findMin_v2(root); cout << endl; cout << "min val: " << minNode->m_nValue << endl; // test func findMax BSTree* maxNode = NULL; //maxNode = findMax(root); maxNode = findMax_v2(root); cout << endl; cout << "max val: " << maxNode->m_nValue << endl; // test func findSuccessor and findPredecessor BSTree* pSuccessor = NULL; BSTree* pPredecessor = NULL; int toBeInserted = 49; insert2BSTree_v2(root, toBeInserted); cout << endl; cout << "inorder BSTree: " << endl; inorderBSTree(root); pSuccessor = findSuccessor(root, toBeInserted); pPredecessor = findPredecessor(root, toBeInserted); if (pPredecessor != NULL) { cout << endl; cout << toBeInserted << "'s predecessor is " << pPredecessor->m_nValue << endl; } else { cout << endl; cout << " no successor" << endl; } if (pSuccessor != NULL) { cout << endl; cout << toBeInserted << "'s successor is " << pSuccessor->m_nValue << endl; } else { cout << endl; cout << " no successor" << endl; } // test func removeFromBSTree bool isRemoved = false; int toBeRemoved = root->m_nValue; isRemoved = removeFromBSTree(root, toBeRemoved); if (isRemoved) { cout << endl; cout << "after removed " << toBeRemoved << endl; inorderBSTree(root); } else { cout << endl; cout << "nothing removed " << endl; } // test func emptyBSTree cout << endl; cout << "empty BSTree " << endl; emptyBSTree(root); cout << endl; delete arr; arr = NULL; return 0; } // 运行结果