二叉排序树的插入和删除

二叉排序树:又称“二叉查找树”,“二叉搜索树”。

二叉排序树是一颗空树,或者具有以下性质:

1. 若它的左子树不空,则左子树上所有结点的值均小于它的根结点的值.

2.若它的右子树不空,则右子树上所有结点的值均大于它的根结点的值.

3.它的左、右子树也分别为二叉排序树。

//二叉排序树结构

typedef int ElemType;

typedef struct BstNode

{

ElemType data;

struct BstNode* parent; //双亲域

struct BstNode* leftchild; //左孩子

struct BstNode* rightchild; //右孩子

}BstNode, *BSTree;

插入思想:从根开始,用插入的值和当前指针的数据域比较, 如果相等, 则不能插入, 如果插入的值大于当前指针的数据域, 指针想右跑,否则, 指针向左跑。

删除思想:分三种情况:

1. 删除叶子和单分支, 只需调整相应的leftchild和rightchild即可.

2. 删除双分支, 需要找到其后继, 将两者数据交换,转化成删除其后继。

3. 删除的既是根结点,又是叶子结点,则要调整相应的根。

其思想总结成对所有节点的删除都归根于对叶子的删除,这一点很重要。

static BstNode* BuyNode()
{
    BstNode *s = (BstNode*)malloc(sizeof(BstNode));
    assert(s != NULL);
    memset(s, 0, sizeof(BstNode));

    return s;
}

static void FreeNode(BstNode *p)
{
    if (p == NULL)
    {
        return ;
    }
    free(p);
    p = NULL;
}

static BstNode* FindVal(BstNode *ptr, const ElemType x)
{
    if(ptr == NULL || x == END)
    {
        return NULL;
    }

    if(x == ptr->data)
    {
        return ptr;
    }
    else if(x > ptr->data)
    {
        return FindVal(ptr->rightchild, x);
    }
    else
    {
        return FindVal(ptr->leftchild, x);
    }
}

/**递归实现*/
bool Insert(BSTree *ptree, const ElemType x, BstNode *pa)
{
    if(ptree == NULL) return false;
    if(*ptree == NULL)
    {
        BstNode *s = BuyNode();
        s->data = x;
        s->leftchild = s->rightchild = NULL;
        *ptree = s;
        s->parent = pa;

        if(pa != NULL)
        {
            if(x > pa->data)
            {
                pa->rightchild = s;
            }
            else
            {
                pa->leftchild = s;
            }
        }

        return true;
    }

    BstNode *ptr = *ptree;

    if(x == ptr->data)
    {
        return false;
    }
    else if(x < ptr->data)
    {
        return Insert(&ptr->leftchild, x, ptr);
    }
    else
    {
        return Insert(&ptr->rightchild, x, ptr);
    }
}
/**迭代实现*/
bool InsertBST(BSTree *ptree,const ElemType val)
{
    if(ptree == NULL) return false;
    if(*ptree == NULL)
    {
        BstNode *s = BuyNode();
        s->data = val;
        s->leftchild = s->rightchild = NULL;
        *ptree = s;
        s->parent = NULL;

        return true;
    }

    BstNode *ptr = *ptree;
    BstNode *pa = ptr;

    while(ptr != NULL)
    {
        if(ptr->data == val)
        {
            return false;
        }
        else if(val > ptr->data)
        {
            pa = ptr;
            ptr = ptr->rightchild;
        }
        else
        {
            pa = ptr;
            ptr = ptr->leftchild;
        }
    }

    ptr = BuyNode();
    ptr->data = val;
    ptr->parent = pa;

    if(val > pa->data)
    {
        pa->rightchild = ptr;
    }
    else
    {
        pa->leftchild = ptr;
    }

    return true;
}

static BstNode *Next(BstNode *ptr)
{
    if(ptr->parent != NULL && ptr == ptr->parent->leftchild)
    {
        return ptr->parent;
    }
    else
    {
        ptr = ptr->rightchild;
        while(ptr != NULL && ptr->leftchild != NULL)
        {
            ptr = ptr->leftchild;
        }

        return ptr;
    }
}

static bool DeleteBST(BSTree *ptree, BstNode *ptr, const ElemType x)
{
    if(ptr->leftchild != NULL && ptr->rightchild != NULL)
    {
        BstNode *res = Next(ptr);
        ptr->data = res->data;
        ptr = res;
    }

    BstNode *pa = ptr->parent;
    BstNode *child = ptr->leftchild == NULL ? ptr->rightchild : ptr->leftchild;

    if(pa == NULL)
    {
        *ptree = child;
        if(child != NULL)
        {
            child->parent = NULL;
        }
    }
    else
    {
        if(ptr == pa->leftchild)
        {
            pa->leftchild = child;
        }
        else
        {
            pa->rightchild = child;
        }
    }

    FreeNode(ptr);

    return true;
}

bool RemoveBST(BSTree *ptree, const ElemType x)
{
    BstNode *ptr = NULL;
    if(ptree == NULL || *ptree == NULL||
      (ptr=FindVal(*ptree, x)) == NULL)
    {
        return false;
    }

    return DeleteBST(ptree, ptr, x);
}
时间: 2024-10-12 08:06:23

二叉排序树的插入和删除的相关文章

二叉排序树的插入与删除

一.二叉排序树的插入 首先检查要插入的数据是否已存在,若存在则不插入,若不存在,则把元素插入到在二叉树上查找失败时的结点的左孩子和右孩子上.需要考虑的特殊情况是插入第一个元素前,二叉树为空. 1 bool insert(BiTreeNode *&root,DataType *item) { 2 BiTreeNode *current = NULL,*parent = NULL,*p = NULL; 3 current = root; 4 while(current != NULL) { 5 if

二叉排序树(插入、删除、更新、遍历、搜索、求树高。。。)

#include <iostream> using namespace std; // 有序二叉树(二叉搜索树) class Tree { public: // 构造过程中初始化为空树 Tree (void) : m_root (NULL), m_size (0) {} // 析构过程中销毁剩余节点 ~Tree (void) { clear (); } // 插入数据 void insert (int data) { insert (new Node (data), m_root); ++m_

重温数据结构:二叉排序树的查找、插入、删除

读完本文你将了解到: 什么是二叉排序树 Binary Sort Tree BST 二叉排序树的关键操作 查找 插入 删除 运行代码测试 一道面试题 总结 Thanks 我们知道,二分查找可以缩短查找的时间,但是有个要求就是 查找的数据必须是有序的.每次查找.操作时都要维护一个有序的数据集,于是有了二叉排序树这个概念. 上篇文章 我们介绍了 二叉树 的概念,二叉树有左右子树之分,想必在区分左右子树时有一定的规则. 现在我们来介绍二叉树的一种特殊形式 - 二叉排序树,了解它的区分策略及常用操作. 什

二叉查找树(二叉排序树)创建,插入,删除操作。

二叉排序树 二叉排序树是一个基础的树的数据结构.应用非常多. 它的特性就是,左孩子小于parent,右孩子大于parent. 寻找节点 寻找节点就是直接根据数值的大小,从root节点开始遍历,大于当前遍历节点就向它的右子树查找,相反则查找它的左子树.然后返回. 查找最大最小节点 直接根据root节点,遍历到最右就是最大节点,遍历到最左,就是最小节点. 插入节点 插入节点我这里插入的节点都会成为叶子节点.根据大小的关系向下遍历,遍历到最后的节点,然后插入就可以了. 删除节点 这里删除节点是相对麻烦

二叉排序树(BST):创建、查找、插入与删除

删除结点的相关操作(左右子树均为非空的删除结点的方法): 算法分析: 下面以实例来说明二叉排序树的创建.查找.插入和删除等相关操作: 如输入关键字序列(45,24,37,12,54,93),然后对其进行相应的操作,程序如下: #include <iostream> #include <stdio.h> #include <stdlib.h> using namespace std; typedef struct BiTNode { int value; struct B

Java实现二叉排序树的插入、查找、删除

import java.util.Random; /** * 二叉排序树(又称二叉查找树) * (1)可以是一颗空树 * (2)若左子树不空,则左子树上所有的结点的值均小于她的根节点的值 * (3)若右子树不空,则右子树上所有的结点的值均大于她的根节点的值 * (4)左.右子树也分别为二叉排序树 * * * 性能分析: * 查找性能: * 含有n个结点的二叉排序树的平均查找长度和树的形态有关, * (最坏情况)当先后插入的关键字有序时,构成的二叉排序树蜕变为单枝树.查找性能为O(n) * (最好

二叉排序树的查找、插入和删除

1.      二叉排序树 二叉排序树(Binary Sort Tree)或者是一棵空树,或者是具有下列性质的二叉树: (1)若左子树不空,则左子树上所有结点的值均小于它的根结点的值: (2)若右子树不空,则右子树上所有结点的值均大于它的根结点的值: (3)左.右子树也分别为二叉排序树: (4)没有结点值相同的结点. 二叉排序树又称二叉查找树(Binary Search Tree),亦称二叉搜索树.通常采用二叉链表作为二叉排序树的存储结构.中序遍历二叉排序树可以得到关键字有序的序列,即一个无序序

二叉平衡树的插入和删除操作

1.      二叉平衡树 二叉排序树的时间复杂度和树的深度n有关.当先后插入的结点按关键字有序时,二叉排序树退化为单枝树,平均查找长度为(n+1)/2,查找效率比较低.提高查找效率,关键在于最大限度地降低树的深度n.因此需要在构成二叉排序树的过程中进行“平衡化”处理,使之成为二叉平衡树. 二叉平衡树,又称AVL树.它或者是一棵空树,或者是具有下列性质的树: 1)      具备二叉排序树的所有性质: 2)      左子树和右子树深度差的绝对值不超过1: 3)      左子树和右子树都是二叉

BST二叉排序树的查找和删除的完整C代码

二叉排序树的查找算法 假定二叉排序树的根节点指针为root,给定的关键字值为key,则查找算法可描述为: 置初值:p = root : 如果 key = p -> data ,则查找成功,算法结束: 否则,如果key < p->data ,而且 p 的左子树非空,则将 p 的左子树根送 p ,转步骤 2 :否则,查找失败,算法结束: 否则,如果 key > p->data ,而且 p 的右子树非空,则将 p 的右子树根送 p ,转步骤 2 :否则,查找失败,算法结束. //B