数据结构 ~ 二叉搜索树

百度定义

二叉排序树(Binary Sort Tree),又称二叉查找树(Binary Search Tree),亦称二叉搜索树。

二叉排序树或者是一棵空树,或者是具有下列性质的二叉树:
(1)若左子树不空,则左子树上所有结 点的值均小于或等于它的根结点的值;
(2)若右子树不空,则右子树上所有结点的值均大于或等于它的根结点的值;
(3)左、右子树也分别为二叉排序树;

如下便是一颗二叉排序树:
这里写图片描述

定义一个二叉搜索树

typedef struct BSearchTree {
    int data;
    BSearchTree *lchild;
    BSearchTree *rchild;
}BST_T, *BST_P;

二叉排序树查找

递归实现~

BST_P Search_BST(BST_P root, int key)
{
    if (root == NULL) {
         return NULL;
    }
    if (key > root->data) {//查找右子树  
        return Search_BST(root->rchild, key);
    }

    else if (key < root->data) {//查找左子树  
        return Search_BST(root->lchild, key);
    }
    else {
        return root;
    }
}

非递归实现

BST_P Search_BST(BST_P root, int key)
{
    BST_P p = root;
    while (p) {       
        if (p->data == key) {
            return p;
        }
        p = (key < p->data) ? p->lchild : p->rchild;
    }
    return NULL;
}

二叉搜索树的插入

插入新元素时,可以从根节点开始,和根节点的键值比较,键值相比较大就访问左儿子,键值相比较小就访问右儿子,一直到末端,就是插入点。

这里写图片描述

void Insert_BST(BST_P *root, DataType data)
{
    //初始化插入节点
    BST_P p = (BST_P)malloc(sizeof(BSearchTree ));
    if (NULL == p) {
        return;
    }
    p->data = data;
    p->lchild = p->rchild = NULL;

    //空树时,直接作为根节点
    if (*root == NULL) {
        *root = p;
        return;
    }
    //是否存在,已存在则返回,不插入
    if (Search_BST(root, data) != NULL) {
        return;
    } 
    //进行插入,首先找到要插入的位置的父节点
    BST_P tnode = NULL, troot = root;
    while (troot) {       
        tnode = troot;
        troot = (data < troot->data) ? troot->lchild : troot->rchild;
    }
    if (data < tnode->data) {
        tnode->lchild = p;
    }   
    else {
        tnode->rchild = p;
    }
}

二叉树的删除

void DeleteBSTNode(BST_P *root, int data)
{
    BST_P p = *root, parent = NULL, s = NULL;

    if (!p) {
        return;
    }

    if (p->data == data) {//找到要删除的节点了
        if (!p->rchild && !p->lchild) {
            *root = NULL;
        }

        // 只有一个左节点
        else if (!p->rchild&&p->lchild) {
            *root = p->lchild;
        }

        // 只有一个右节点
        else if (!p->lchild&&p->rchild) {
            *root = p->rchild;
        }

        //左右节点都不空
        else {
            s = p->rchild;

            if (!s->lchild) {
                s->lchild = p->lchild;
            }
            else {
                while (s->lchild) {
                    parent = s;
                    s = s->lchild;
                }
                parent->lchild = s->rchild;
                s->lchild = p->lchild;
                s->rchild = p->rchild;
            }
            *root = s;
        }
        free(p);
    }
    else if (data > p->data) {//向右找
        DeleteBSTNode(&(p->rchild), data);
    }
    else if (data < p->data) {//向左找
        DeleteBSTNode(&(p->lchild), data);
    }
}

二叉树搜索树的遍历同二叉树的遍历,上一篇文章有递归与非递归的代码。

以上~欢迎留言交流!

猜你喜欢

转载自blog.csdn.net/breakpoints_/article/details/80509634
今日推荐