赞
踩
- 若它的左子树不为空,则左子树上的所有节点的值均小于它的根节点的值
- 若它的右子树不为空,则右子树上的所有节点的值均大于它的根节点的值
- 它的左右子树也为二叉排序树
二叉排序树又称二叉查找树,一般使用二叉链表作为二叉排序树的存储结构。
二叉排序树结构:
-
- class BST_Node
- {
- public:
- int data;//数据
- BST_Node* lchild;//左孩子
- BST_Node* rchild;//右孩子
- BST_Node(int i=0):data(i),lchild(nullptr),rchild(nullptr){}//构造函数
- };
- class BSTree
- {
- public:
- BST_Node* tree;
- BSTree()
- {
- tree = nullptr;//初始化
- }
-
- };
二叉排序树的查找:(根据数据查找)
- 先判断根节点是否为空和判断数据是否相同
- 数据大于根节点,那就进入右子树
- 数据小于根节点,那就进入左子树
时间复杂度:
- 最好的情况:O(log2 n)
- 最坏的情况:O(n)
- BST_Node* SeachBST(BST_Node* B,int K)
- {
- if (!B || B->data == K)//结束条件
- {
- return B;
- }
- else if (B->data< K)
- {
- SeachBST(B->rchild, K);//进入右孩子
- }
- else
- {
- SeachBST(B->lchild, K);//进入左孩子
- }
- }
二叉排序树的插入:
- 若二叉排序树为空,则插入该节点,使该节点成为根节点、
- 否则,继续在左子树和右子树中寻找
- 树中有该数据的话则不插入
- 树中没有的话,直到找到某个叶子的左子树或右子树为空为止,则插入节点应该为该节点的左孩子或右孩子。
- void insert(BST_Node*& B, int K)
- {
- if (B == nullptr)//如果根节点为空,直接当成根节点
- {
- B = new BST_Node(K);
- return;//结束
- }
-
- BST_Node* B1 = B;
- BST_Node* P1=nullptr;//获取父节点位置
- while (!B1)//寻找插入位置
- {
- P1 = B1;//保存父节点
- if (K < B1->data)
- {
- B1 = B1->lchild;//如果K小于data,进入左孩子
- }
- else if(K > B1->data)
- {
- B1 = B1->rchild;//如果K大于data,进入右孩子
- }
- else
- {
- return;//相同的话,不插入,结束
- }
- }
- BST_Node* G = new BST_Node(K);//创建新节点
- if (K > P1->data)
- {
- P1->rchild = G;//作为右孩子
- }
- else
- {
- P1->lchild = G;//作为左孩子
- }
- }
二叉排序树的删除:
- 第一种情况:叶子节点,可以直接删除
- 第二种情况:被删除节点只有左子树或右子树,可以直接把左子树或右子树直接拼接其父节点上
- 第三种情况:被删除节点既有左子树又有右子树
- 可以用左子树中的最大值替换该节点,并删除该最大值节点
- 可以用右子树中的最小值替换该节点,并删除该最小值节点
按照以上思路写的代码,可以用查找和判段左右孩子函数来精简该代码。
- void Delete(BST_Node*& B, int K)
- {
- if (B == nullptr) return;//根节点为空,退出
- BST_Node* P = B;
- BST_Node* F = nullptr;//保存父节点
- while (P != nullptr)
- {
- F = P;
- if (P->data > K){
- P = P->lchild;//K小于节点数据,进入左孩子
- }
- else if (P->data < K){
- P = P->rchild;//K小于节点数据,进入右孩子
- }
- else{
- break;//找到节点退出循环
- }
- }
- if (P == nullptr)return;//如果没找到的话退出
- //查看该节点是否拥有右左子树
- if (P->lchild == nullptr && P->rchild == nullptr)// 叶子节点的话
- {
- if (F->data > P->data)F->lchild = nullptr;
- else { F->rchild = nullptr; }
- delete P;//释放节点内存
- return;
- }
- if (P->lchild != nullptr && P->rchild != nullptr)//拥有左右子树的话
- {
- //找到右子树的最小值,在该节点的右子树的左子树中
- BST_Node* M = P;//存放当前节点位置
- F = P;
- P = P->rchild;
- while (P->lchild!=nullptr)
- {
- F = P;
- P = P->lchild;//找到最小值
- }
- M->data = P->data;//数据赋值给节点
- F->lchild = nullptr;
- delete P;//释放节点内存
- return;
- }
- //单子树的情况
- if (P->lchild == nullptr && F->lchild==P)
- {
- F->lchild = P->rchild;
- }
- else if (P->lchild == nullptr && F->rchild == P)
- {
- F->rchild = P->rchild;
- }
- else if (P->rchild == nullptr && F->lchild == P)
- {
- F->lchild = P->rchild;
- }
- else
- {
- F->rchild = P->rchild;
- }
- delete P;
- }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。