[数据结构] ——搜索二叉树的插入,查找和删除(递归&非递归)

2018-02-26 21:47:06 +08:00
 bigshot

一、搜索二叉树的插入,查找,删除 简单说说搜索二叉树概念: 二叉搜索树又称二叉排序树,它或者是一棵空树,或者是具有以下性质的二叉树 若它的左子树不为空,则左子树上所有节点的值都小于根节点的值 若它的右子树不为空,则右子树上所有节点的值都大于根节点的值 它的左右子树也分别为二叉搜索树 例如:int a [] = {5,3,4,1,7,8,2,6,0,9}; 二叉树结构

typedef struct BSTreeNode 
{
    struct BSTreeNode *_left;
    struct BSTreeNode *_right;
    DataType _data;
}BSTreeNode;

二叉树节点创建

BSTreeNode *BuyTreeNode(DataType x) //创建节点
{
    BSTreeNode *node = (BSTreeNode*)malloc(sizeof(BSTreeNode));
    assert(node);

    node->_data = x;
    node->_left = NULL;
    node->_right = NULL;

    return node;
}

二叉搜索树操作: 1、搜索二叉树的插入:在二叉搜索树中插入新元素时,必须先检测该元素是否在树中已经存在。如果已经存在,则不进行插入;否则将新元素加入到搜索停止的地方。 非递归代码

int BSTreeNodeInsert(BSTreeNode **pptree,DataType x) //搜索树的插入
{
    BSTreeNode *parent = NULL;
    BSTreeNode *cur = *pptree;
    if (*pptree == NULL)
    {
        *pptree = BuyTreeNode(x);
        return 0;
    }
    while (cur)
    {
      parent = cur;
      if (cur->_data > x)
          cur = cur->_left;
      else if (cur->_data < x)
          cur = cur->_right;
      else
          return -1;
    }

    if (parent->_data > x)
        parent->_left = BuyTreeNode(x);
    else 
        parent->_right = BuyTreeNode(x);

    return 0;
}

递归代码 :

int BSTreeNodeInsertR(BSTreeNode **tree,DataType x) //搜索树的插入
{
    if(*tree == NULL)
    {
        *tree = BuyTreeNode(x);
        return 0;
    }

    if ((*tree)->_data > x)
        return BSTreeNodeInsertR(&(*tree)->_left,x);
    else if ((*tree)->_data < x)
        return BSTreeNodeInsertR(&(*tree)->_right,x);
    else
        return -1;
}

2、搜索二叉树的查找

非递归代码

BSTreeNode *BSTreeNodeFind(BSTreeNode *tree,DataType x) //查找
{
    while (tree)
    {
        if (tree->_data == x)
            return tree;
        else if (tree->_data < x)
            tree = tree->_right;
        else 
            tree = tree->_left;
    }

    return NULL;
}

递归代码

BSTreeNode *BSTreeNodeFindR(BSTreeNode *tree,DataType x) //查找
{
    if (!tree)
        return NULL;

    if (tree->_data > x)
        BSTreeNodeFindR(tree->_left,x);
    else if (tree->_data < x)
        BSTreeNodeFindR(tree->_right,x);
    else
        return tree;
}

3、搜索二叉树的删除: 首先查找元素是否在二叉搜索树中,如果不存在,则返回, 否则要删除的结点可能分下面四种情况: a. 要删除的结点无孩子结点 b. 要删除的结点只有左孩子结点 c. 要删除的结点只有右孩子结点 d. 要删除的结点有左、右孩子结点 情况 1 可以归类到 2 或者 3 对于上述情况,相应的删除方法如下: a. 直接删除该结点 b. 删除该结点且使被删除节点的双亲结点指向被删除节点的左孩子结点 c. 删除该结点且使被删除节点的双亲结点指向被删除结点的右孩子结点 d. 在它的右子树中寻找中序下的第一个结点(关键码最小),用它的值填补到被删除节点中,在来处理该结点的删除问题 代码实现:

int BSTreeNodeDel(BSTreeNode **tree,DataType x) //删除
{

    BSTreeNode *cur = *tree;
    BSTreeNode *parent = *tree;
    BSTreeNode *del = NULL;
    
    while (cur)
    {
        if (cur->_data > x)
        {
            parent = cur;
            cur = cur->_left;
        }
        else if (cur->_data < x)
        {
            parent = cur;
            cur = cur->_right;
        }
        else
        {
            del = cur;

            if (cur->_left == NULL) //1、左孩子为空
            {
                if (parent->_left == cur)
                    parent->_left = cur->_right;
                else if (parent->_right == cur)
                    parent->_right = cur->_right;
                else if (parent == cur) //没有父亲节点时
                   *tree = parent->_right;
            }
            else if (cur->_right == NULL) //2、右孩子为空
            {
                if (parent->_left == cur)
                    parent->_left = cur->_left;
                else if (parent->_right == cur)
                    parent->_right = cur->_left;
                else if (parent == cur) //没有父亲节点时
                    *tree = parent->_left;
            }
            else//3、左右孩子都不为空
            {
                BSTreeNode *sub = cur->_right;
                while (sub->_left)
                {
                    parent = sub;
                    sub = sub->_left;
                }
                   
                del = sub;
                cur->_data = sub->_data;

                if (parent->_left == sub)
                    parent->_left = sub->_right;
                else 
                    parent->_right = sub->_right;
            }

            free(del);
            del = NULL;
            return 0;

        }
    }

    return -1;
}

完整代码请私信或者点此链接下载 [数据结构] ——搜索二叉树的插入,查找和删除(递归&非递归)

2304 次点击
所在节点    程序员
0 条回复

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/432927

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX