BST树

BST树

BST树,二叉查找树(Binary Search Tree),又叫二叉搜索树、二叉排序树。
它或者是一颗空树,或者是具有以下性质的二叉树:

  • 若它的左子树不为空,则左子树上所有的结点的值均小于它的根结点的值;
  • 若它的右子树不为空,则右子树上所有结点的值均大于它的根结点的值;
  • 它的左右子树也分别为二叉排序树

二叉搜索树作为一种经典的数据结构,它既有链表的快速插入与删除操作的特点,又有数组快速查找的优势;所以应用十分广泛,例如在文件系统和数据库系统一般会采用这种数据结构进行高效率的排序与检索操作。

这张图片是BST树的一个简单示例
在这里插入图片描述

BST树的构造

二叉搜索树(BST)又称二叉查找树或二叉排序树。一棵二叉搜索树是以二叉树来组织的,可以使用一个链表数据结构来表示,其中每一个结点就是一个对象。一般地,除了key之外,每个结点还包含属性lchild、rchild和parent,分别指向结点的左孩子、右孩子和双亲(父结点)。如果某个孩子结点或父结点不存在,则相应属性的值为空(NIL)。根结点是树中唯一父指针为NIL的结点,而叶子结点的孩子结点指针也为NIL。

class BSTree {
    class BstNode {
        int key;
        BstNode leftchild;
        BstNode parent;
        BstNode rightchild;

        public BstNode() {
            key = 0;
            leftchild = parent = leftchild = null;
        }
        public BstNode(int x) {
            key = x;
            leftchild = parent = leftchild = null;
        }
        public BstNode(int x,BstNode left,BstNode pa,BstNode right) {
            key = x;
            leftchild = left;
            parent = pa;
            rightchild = right;
        }

    }

    BstNode root; //根节点
    BstNode cur;   //指向当前节点
    public BSTree() {
        root = null;
        cur = null;
    }
}

BST习题

BST树的查询

1.查询否存在值为kx的Node,并返回。

private BstNode Search(BstNode ptr,int kx) {
        if(ptr == null || ptr.key == kx) {
            return ptr;
        }
        else if(kx < ptr.key) {
            return Search(ptr.leftchild, kx);
        }else {
            return Search(ptr.rightchild, kx);
        }
    }

2.查询是否存在值为kx的结点

    public boolean SearchValue(int kx) {
        boolean res = false;
        cur = Search(root,kx);
        if(cur != null) {
            res = true;
        }
        return res;
    }

    public boolean FindValue(int kx) {
        cur = root;
        boolean res = false;
        while(cur != null && cur.key != kx) {
            cur = kx < cur.key ? cur.leftchild : cur.rightchild;
        }
        if(cur != null && cur.key == kx) {
            res = true;
        }
        return res;
    }

BST树的插入

在插入时,将所插入的节点值分别比较,如果小就往左子树找,大就往右子树找。

    public boolean Insert(int kx)//插入
    {
        boolean res = true;
        if(root == null)
        {
            root = new BstNode(kx);
            return res;
        }
        cur = root;
        BstNode pa = null;
        while(cur != null && cur.key != kx) {
            pa = cur;
            cur = kx < cur.key ? cur.leftchild : cur.rightchild;
        }
        if(cur != null && cur.key == kx) {
            res = false;
        }
        else
        {
            cur = new BstNode(kx);
            cur.parent = pa;
            if(cur.key < pa.key)
            {
                pa.leftchild = cur;
            }
            else
            {
                pa.rightchild = cur;
            }
        }
        return res;
    }

BST树的中序遍历

其实,BST最简单的标志就是它的中序遍历序列是有序的。

  public void NiceInOrder()  //非递归中序遍历
    {
        if(root == null) return ;
        Stack<BstNode> st = new Stack<>();
        cur = root;
        while(cur != null || !st.isEmpty())
        {
            while(cur != null)
            {
                st.push(cur);
                cur = cur.leftchild;
            }
            cur = st.pop();
            System.out.print(cur.key+ " ");
            cur = cur.rightchild;
        }
        System.out.println();
    }

判断是否为BST树

利用栈,每次去比较当前节点的右子节点的大小。

 public boolean Is_BSTree()  //是否为bst树
    {
        boolean res = true;
        if(root == null) return res;
        Stack<BstNode> st = new Stack<>();
        cur = root;
        BstNode pre = null;
        while(cur != null || !st.isEmpty())
        {
            while(cur != null)
            {
                st.push(cur);
                cur = cur.leftchild;
            }
            cur = st.pop();
            if(pre != null && pre.key >= cur.key)
            {
                res = false;
                break;
            }
            pre = cur;
            cur = cur.rightchild;
        }
        return res;
    }

BST的删除

private BstNode Next(BstNode ptr)
    {
        while(ptr != null && ptr.leftchild != null)
        {
            ptr = ptr.leftchild;
        }
        return ptr;
    }
    public boolean Remove(int kx)
    {
        boolean res = false;
        if(root == null) return res;
        BstNode pa = null;
        cur = root;
        while(cur != null && cur.key == kx)
        {
            pa = cur;
            cur = kx < cur.key ? cur.leftchild:cur.rightchild;
        }
        if(cur == null) return res;
        if(cur.leftchild != null && cur.rightchild != null)
        {
            BstNode nt = Next(cur.rightchild);
            cur.key = nt.key;
            pa = nt.parent;
            cur = nt;
        }
        BstNode child = cur.leftchild != null ? cur.leftchild:cur.rightchild;
        if(child != null) child.parent = pa;
        //leaf // one brch
        if(pa == null)
        {
            root = child;
        }
        else {
            if (cur.key < pa.key) {
                pa.leftchild = child;
            } else {
                pa.rightchild = child;
            }
        }
        return true;
    }
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
好的,下面是我重新设计的C语言版本的BST模块: ``` // bst.h // 定义二叉搜索节点类型 typedef struct bst_node { int key; struct bst_node* left; struct bst_node* right; } BSTNode; // 创建一个新的节点 BSTNode* create_node(int key); // 插入一个节点,返回根节点 BSTNode* insert_node(BSTNode* root, int key); // 删除一个节点,返回根节点 BSTNode* delete_node(BSTNode* root, int key); // 查找一个节点,返回指向该节点的指针 BSTNode** search_node(BSTNode** root, int key); // 遍历二叉搜索,并将节点的key值存储到数组中 void traverse_bst(BSTNode* root, int* arr, int* index); // 释放二叉搜索的内存 void free_bst(BSTNode* root); ``` ```c // bst.c #include "bst.h" #include <stdlib.h> // 创建一个新的节点 BSTNode* create_node(int key) { BSTNode* node = (BSTNode*)malloc(sizeof(BSTNode)); node->key = key; node->left = NULL; node->right = NULL; return node; } // 插入一个节点,返回根节点 BSTNode* insert_node(BSTNode* root, int key) { if (root == NULL) { return create_node(key); } if (key < root->key) { root->left = insert_node(root->left, key); } else if (key > root->key) { root->right = insert_node(root->right, key); } return root; } // 删除一个节点,返回根节点 BSTNode* delete_node(BSTNode* root, int key) { if (root == NULL) { return NULL; } if (key < root->key) { root->left = delete_node(root->left, key); } else if (key > root->key) { root->right = delete_node(root->right, key); } else { if (root->left == NULL) { BSTNode* temp = root->right; free(root); return temp; } else if (root->right == NULL) { BSTNode* temp = root->left; free(root); return temp; } BSTNode* temp = root->right; while (temp->left != NULL) { temp = temp->left; } root->key = temp->key; root->right = delete_node(root->right, temp->key); } return root; } // 查找一个节点,返回指向该节点的指针 BSTNode** search_node(BSTNode** root, int key) { if (*root == NULL || (*root)->key == key) { return root; } if (key < (*root)->key) { return search_node(&((*root)->left), key); } else { return search_node(&((*root)->right), key); } } // 遍历二叉搜索,并将节点的key值存储到数组中 void traverse_bst(BSTNode* root, int* arr, int* index) { if (root == NULL) { return; } traverse_bst(root->left, arr, index); arr[*index] = root->key; (*index)++; traverse_bst(root->right, arr, index); } // 释放二叉搜索的内存 void free_bst(BSTNode* root) { if (root == NULL) { return; } free_bst(root->left); free_bst(root->right); free(root); } ``` 这个BST模块包含了创建节点、插入节点、删除节点、查找节点、遍历和释放内存等基本操作。在使用时,可以通过调用这些函数来实现对BST的操作。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

降温vae+

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值