二叉搜索树学习——————之一
二叉查找树(Binary Search Tree),(又:二叉搜索树,二叉排序树)它或者是一棵空树,或者是具有下列性质的二叉树: 若它的左子树不空,则左子树上所有结点的值均小于它的根结点的值; 若它的右子树不空,则右子树上所有结点的值均大于它的根结点的值; 它的左、右子树也分别为二叉排序树。也就是说对于任意一个节点x,其左子树中的关键字均不大于x.key,其右子树均不小于x.key。概念性的东西就不多说了,,下面直接用C语言实现,,用注释说明问题会更清晰一些
二叉查找树主要定义了如下操作:
typedef struct TreeNode{ //二叉搜索树的节点信息 int data; struct TreeNode* pRight; struct TreeNode* pLeft; struct TreeNode* pFather; }TreeNode; TreeNode* Tree = NULL; //使用指定的整形数组,构造二叉搜索树 TreeNode* constructTree(int arr[] , int len); //使用一个整型值初始化一个节点 TreeNode* constructNode(int num); //搜索二叉搜索树 TreeNode* search(TreeNode* tree, int num); //在树中查找最小的元素 TreeNode* minNum(TreeNode* tree); //在树种查找最大的元素 TreeNode* maxNum(TreeNode* tree); //中序遍历输出树并输出相关信息 void traverse(TreeNode* tree); //处理节点 void handleNode(TreeNode* node); //插入节点 bool insert(TreeNode* tree, int num); //删除节点信息 TreeNode* deleteNode(TreeNode* tree, int num); TreeNode* transplant(TreeNode* u, TreeNode* v); //寻找给定节点的前驱 TreeNode* successor(TreeNode* tree, int num);
我是将上面的的搜索二叉树的操作方法定义在binarySearchTree.h中,然后在binarySearchTree.cpp中实现的,下面是具体的实现代码:
#include<iostream> #include"binarySearchTree.h" #include<stdlib.h> #include<time.h> using namespace std; //使用指定的整形数组,构造二叉搜索树 TreeNode* constructTree(int arr[] , int len){ int index = rand() % len; TreeNode* pHead = constructNode(arr[1]); for (int i = 0; i < len; i++){ insert(pHead, arr[i]); } return pHead; } //使用一个整型值初始化一个节点 TreeNode* constructNode(int num){ TreeNode* pNode = new TreeNode(); pNode->data = num; pNode->pFather = NULL; pNode->pLeft = NULL; pNode->pRight = NULL; return pNode; } //插入节点 bool insert(TreeNode* tree, int num){ TreeNode* pNode = constructNode(num); TreeNode* pTemp = tree; TreeNode* p = NULL; while (pTemp != NULL){ p = pTemp; //指向当前节点的父节点 if (num > pTemp->data){ //num值比当前节点大就向右移动指正,否则就像左移动指针 pTemp = pTemp->pRight; } else{ pTemp = pTemp->pLeft; } } if (p == NULL){ //空树,,无法插入节点 return false; } pNode->pFather = p; if (pNode->data > p->data){ p->pRight = pNode; } else{ p->pLeft = pNode; } return true; } //中序遍历输出树并输出相关信息 void traverse(TreeNode* tree){ if (tree == NULL){ return; } traverse(tree->pLeft); handleNode(tree); traverse(tree->pRight); } void freeTree(TreeNode* tree){ if (tree == NULL){ return; } traverse(tree->pLeft); traverse(tree->pRight); free(tree); } //处理节点 void handleNode(TreeNode* node){ cout << node->data << " "; } //在树中查找最小的元素 TreeNode* minNum(TreeNode* tree){ if (tree == NULL){ return NULL; } while (tree->pLeft != NULL){ tree = tree->pLeft; } return tree; } //在树种查找最大的元素 TreeNode* maxNum(TreeNode* tree){ if (tree == NULL){ return NULL; } while (tree->pRight != NULL){ tree = tree->pRight; } return tree; } //搜索二叉搜索树 TreeNode* search(TreeNode* tree, int num){ while (tree != NULL){ if (tree->data == num){ break; } if (num > tree->data){ tree = tree->pRight; } else{ tree = tree->pLeft; } } return tree; } //寻找给定节点的前驱 TreeNode* successor(TreeNode* tree, int num){ TreeNode* pNode = search(tree, num); if (pNode->pRight != NULL){ return minNum(pNode->pRight); } TreeNode* p = pNode->pFather; while (p != NULL && p->pRight == pNode){ pNode = p; p = p->pFather; } return p; } //删除节点信息 TreeNode* deleteNode(TreeNode* tree, int num){ TreeNode* pNode = search(tree, num); if (pNode == NULL){ return NULL; } if (pNode->pLeft == NULL){ //左节点为空时就直接使用有节点替换需要删除的节点 transplant(pNode, pNode->pRight); } else if (pNode->pRight == NULL){ transplant(pNode, pNode->pLeft); } else{ TreeNode* v = minNum(pNode->pRight); if (v->pFather != pNode){ transplant(v, v->pRight); v->pRight = pNode->pRight; v->pRight->pFather = v; } transplant(pNode, v); v->pLeft = pNode->pLeft; v->pLeft->pFather = v; } return pNode; } TreeNode* transplant(TreeNode* u, TreeNode* v){ if (u->pFather == NULL){ v->pFather = u->pFather; Tree = v; return u; } if (u == u->pFather->pLeft){ u->pFather->pLeft = v; } else{ u->pFather->pRight = v; } if (v != NULL){ v->pFather = u->pFather; } return u; } int main(){ cout << "========== Binary Search Tree --- > Construct and Traverse=======\n"; int arr[] = { 3, 4, 1, 2, 5, 10, 6, 9, 8 ,0}; TreeNode* tree = constructTree(arr , 10); Tree = tree; traverse(tree); cout << "\n========== Binary Search Tree --- > minNUm 、 maxNum、search、=======\n"; cout << "minNum = " << minNum(tree)->data << "\n"; cout << "maxNum = " << maxNum(tree)->data << "\n"; cout << "search = " << search(tree, 5)->data << "\n"; cout << "========== Binary Search Tree --- > delete Num =======\n"; for (int i = 0; i < 10; i++){ TreeNode* node = deleteNode(Tree, arr[i]); cout << "delete num : " << node->data << "\n"; free(node); if (i<9){ traverse(Tree); } } //free(tree); getchar(); return 0; }
以上代码实在VS2013上测试全部通过的,,,如果有bug,欢迎指正,感激不尽。。。。。