查找——2、二叉树排序树

1、二叉排序树(BST)的定义
二叉排序树(Binary Sort Tree或Binary Search Tree) BST的定义为:
二叉排序树或者是空树,或者是满足下列性质的二叉树。
(1) :若左子树不为空,则左子树上所有结点的值(关键字)都小于根结点的值;
(2) :若右子树不为空,则右子树上所有结点的值(关键字)都大于根结点的值;
(3) :左、右子树都分别是二叉排序树。
结论:若按中序遍历一棵二叉排序树,所得到的结点序列是一个递增序列

2、BST树的查找
首先将给定的K值与二叉排序树的根结点的关键字进行比较:若相等:则查找成功;
① 给定的K值小于BST的根结点的关键字:继续在该结点的左子树上进行查找;
② 给定的K值大于BST的根结点的关键字:继续在该结点的右子树上进行查找

3、BST树的插入
在BST树中插入一个新结点,要保证插入后仍满足BST的性质。

插入思想
在BST树中插入一个新结点x时,若BST树为空,则令新结点x为插入后BST树的根结点;否则,将结点x的关键字与根结点T的关键字进行比较:
① 若相等: 不需要插入;
② 若x.keykey:结点x插入到T的左子树中;
③ 若x.key>T->key:结点x插入到T的右子树中。

4、BST树的删除
删除操作过程分析
从BST树上删除一个结点,仍然要保证删除后满足BST的性质。设被删除结点为p,
其父结点为f ,删除情况如下:
① 若p是叶子结点: 直接删除p,如图所示。
② 若p只有一棵子树(左子树或右子树):直接用p的左子树(或右子树)取代p的位
置而成为f的一棵子树。即原来p是f的左子树,则p的子树成为f的左子树;原
来p是f的右子树,则p的子树成为f的右子树,如图©、 (d)所示。
③ 若p既有左子树又有右子树 :处理方法有以下两种,可以任选其中一种。
◆ 用p的直接前驱结点代替p。即从p的左子树中选择值最大的结点s放在p的
位置(用结点s的内容替换结点p内容),然后删除结点s。s是p的左子树中的
最右边的结点且没有右子树,对s的删除同②,如图(e)所示。
◆ 用p的直接后继结点代替p。即从p的右子树中选择值最小的结点s放在p的
位置(用结点s的内容替换结点p内容),然后删除结点s。s是p的右子树中的
最左边的结点且没有左子树,对s的删除同②,如图(f)所示。
在这里插入图片描述

5、性能分析
》 每个结点的C(i)为该结点的层次数。
》 最坏情况下,当先后插入的关键字有序时,构成的二叉排序树蜕变为
单支树,树的深度为其平均查找长度(n+1)/2(和顺序查找相同),最
好的情况是二叉排序树的形态和折半查找的判定树相同,其平均查找
长度和log 2 (n)成正比

6、BST树的操作代码实现

#include <iostream>
#include <cstdlib>
#include <cstring>
#include <stack>
#include <queue>

using namespace std;

typedef struct node{
    int item;
    struct node *lchild;
    struct node *rchild;
}BSTNode;

BSTNode *root = NULL;

//创建节点
BSTNode *mk_node(int item)
{
    BSTNode *p = (BSTNode *)malloc(sizeof(BSTNode));
    if(p == NULL)
    {
        cout << "malloc failed!" << endl;
        exit(1);
    }

    p->item = item;
    p->lchild = NULL;
    p->rchild = NULL;

    return p;
}

//创建BST树(插入节点)//递归
void insert_node(BSTNode *current, BSTNode *p)
{
    if(p->item > current->item)
    {
        if(current->rchild == NULL)
        {
            current->rchild = p;
        }else
        {
            insert_node(current->rchild, p);
        }
    }else if(p->item < current->item)
    {
        if(current->lchild == NULL)
        {
            current->lchild = p;
        }else
        {
            insert_node(current->lchild, p);
        }
    }else
    {
        free(p);
    }
}

void create_BST(int item)
{
    BSTNode *p = mk_node(item);
    if(root == NULL)
    {
        root = p;
    }else
    {
        insert_node(root, p);
    }
}

//创建BST树(插入节点)//迭代
void create_BST_r(int item)
{
    BSTNode *pre = NULL;
    BSTNode *parent = NULL;
    BSTNode *p = mk_node(item);

    pre = parent = root;
    if(root == NULL)
    {
        root = p;
        return;
    }

    while(pre != NULL)
    {
        parent = pre;
        if(item > pre->item)
        {
            pre = pre->rchild;
        }else if(item < pre->item)
        {
            pre = pre->lchild;
        }else
        {
            free(p);
            return;
        }
    }
    if(item > parent->item)
        parent->rchild = p;
    else
        parent->lchild = p;
}

/*---------------------三种递归遍历----------------------*/
//先序遍历
void prePrint_o(BSTNode *p)
{
    if(p == NULL)
        return;

    cout << p->item << " ";
    prePrint(p->lchild);
    prePrint(p->rchild);
}

//中序遍历
void inPrint_o(BSTNode *p)
{
    if(p == NULL)
        return;

    prePrint(p->lchild);
    cout << p->item << " ";
    prePrint(p->rchild);
}

//后序遍历
void nextPrint_o(BSTNode *p)
{
    if(p == NULL)
        return;

    prePrint(p->lchild);
    prePrint(p->rchild);
    cout << p->item << " ";
}

/*--------------------------迭代遍历的几种--------------------------*/
//先序遍历
void prePrint_s(BSTNode *p)
{
    if(p == NULL)
        return;
    stack<BSTNode *> st;
    BSTNode *pr = p;
    do
    {
        cout << pr->item <<" ";
        if(pr->rchild != NULL)
        {
            st.push(pr->rchild);
        }
        pr = pr->lchild;
        if(pr == NULL)
        {
            pr = st.top();
            st.pop();
        }
    }while(pr != NULL);
}

//中序遍历
void inPrint_s(BSTNode *p)
{
    if(p == NULL)
        return;
    stack<BSTNode *> st;
    BSTNode *pr = p;

    do
    {
        while(pr != NULL)
        {
            st.push(pr);
            pr = pr->lchild;
        }
        if(!st.empty())
        {
            pr = st.top();
            st.pop();
            cout << pr->item << " ";
            pr = pr->rchild;
        }

    }while(!st.empty())
}

//后序遍历
void nextPrint_s(BSTNode *p)
{
    if(p == NULL)
        return;

    stack<BSTNode *> st;
    stack<int> si;          //设立一个标志位的栈
    BSTNode *pr = p;

    do
    {
        while(pr != NULL)
        {
            st.push(pr);
            si.push(0);
            pr = pr->lchild;
        }

        if(si.top() == 0)
        {
            pr = st.top()->rchild;
            si.pop();
            si.push(1);
        }else
        {
            pr = st.top();
            st.pop();
            si.pop();
            cout << pr->item << " ";
            pr = NULL;
        }
    }while(!st.empty() && !si.empty());
}

//层次遍历
void levelPrint(BSTNode *p)
{
    if(p == NULL)
        return;

    queue<BSTNode *> qt;
    BSTNode *pr = p;

    do
    {
        if(!qt.empty())
        {
            pr = qt.front();
            qt.pop();
        }
        cout << pr->item << " ";
        if(pr->lchild != NULL)
        {
            qt.push(pr->lchild);
        }
        if(pr->rchild != NULL)
        {
            qt.push(pr->rchild);
        }
    }while(!qt.empty());
}

//求二叉树叶子结点的个数
int search_leaves(BSTNode *p)
{
    if(p == NULL)
        return 0;

    int sum = 0;
    BSTNode *pr = p;
    stack<BSTNode *> st;

    do
    {
        if(pr->lchild == NULL && pr->rchild == NULL)
        {
            sum++;
        }

        if(pr->rchild != NULL)
        {
            st.push(pr->rchild);
        }

        pr = pr->lchild;
        if(pr == NULL)
        {
            pr = st.top();
            st.pop();
        }
    }while(pr != NULL);

    return sum;
}

//求二叉树的深度
int search_depth(BSTNode *p)
{
    if(p == NULL)
        return 0;
    queue<BSTNode *> qt;
    BSTNode *pr = p;
    BSTNode *re = p;             //用来保存本行的最后一个结点
    BSTNode *bl = NULL;          //用来记录队列里元素的变化
    int sum = 0;
    qt.push(pr);

    do
    {
        if(!qt.empty())
        {
            pr = qt.front();
            qt.pop();
        }
        if(pr->lchild != NULL)
        {
            qt.push(pr->lchild);
            bl = pr->lchild;
        }
        if(pr->rchild != NULL)
        {
            qt.push(pr->rchild);
            bl = pr->rchild;
        }

        if(pr == re)
        {
            sum++;
            re = bl;
        }

    }while(!qt.empty());

    return sum;
}

//二叉树的查找
BSTNode *search_node(BSTNode *current, int item)
{
    if(item < current->item)
    {
        if(current->lchild == NULL)
        {
            return NULL;
        }
        return search_node(current->lchild, item);
    }else if(item > current->item)
    {
        if(current->rchild == NULL)
        {
            return NULL;
        }
        return search_node(current->rchild, item);
    }

    return current;
}
/*
    二叉树结点的删除
*/
//查找要删除的结点的父节点
BSTNode *btree_find(BSTNode *p, int value, int *pos)
{
    BSTNode *backfather = NULL;
    BSTNode *pr = p;

    backfather = p;
    *pos = 0;

    while(pr != NULL)
    {
        if(pr->item == value)
        {
            return backfather;
        }else
        {
            backfather = pr;
            if(pr->item > value)
            {
                pr = pr->lchild;
                *pos = -1;
            }else
            {
                pr = pr->rchild;
                *pos = 1;
            }
        }
    }

    return NULL;
}

//二叉树结点删除
void delete_node(BSTNode *p, int value)
{
    BSTNode *backfather = NULL;
    BSTNode *pr = p;
    BSTNode *next = NULL;
    int pos;

    backfather = btree_find(p, value, &pos);
    if(backfather == NULL)
        return ;

    switch(pos)
    {
        case -1: pr = backfather->lchild; break;
        case  1; pr = backfather->rchild; break;
        case  0; pr = backfather;         break;
    }

    if(pr->lchild == NULL || pr->rchild == NULL)
    {
        if(pos == 0)
        {
            if(pr->rchild != NULL)
            {
                p = p->rchild;
            }else
            {
                p = p->lchild;
            }
        }else if(pos < 0)
        {
            if(pr->lchild == NULL)
            {
                backfather->lchild = pr->rchild;
            }else
            {
                backfather->lchild = pr->lchild;
            }
        }else
        {
            if(pr->lchild == NULL)
            {
                backfather->rchild = pr->rchild;
            }else
            {
                backfather->rchild = pr->lchild;
            }
        }

        free(pr);
        return;
    }

    /*有左子树也有右子树的情况 */
    backfather = pr;  //父节点指向当前节点
    next = pr->lchild;   //设置子节点
    while (next->rchild != NULL)
    {
        backfather = next;
        next = next->rchild;
    }
    pr->item = next->item;  //替换数据

	//把最右面的结点删除
    if (backfather->lchild == next)
    {
        backfather->lchild = next->lchild;
    }
    else
    {
        backfather->rchild = next->lchild;
    }

    free(next);

    return;
}


//二叉树的销毁
void destroy_btree(BSTNode *p)
{
    if(p == NULL)
        return;
    destroy_btree(p->lchild);
    destroy_btree(p->rchild);

    free(p);
}


int main()
{

    return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值