二叉查找树

简介: 二叉查找树,也称二叉排序树,二叉搜索树。 它或者是一棵空树;或者是具有下列性质的二叉树: 若左子树不空,则左子树上所有结点的值均小于它的根结点的值; 若右子树不空,则右子树上所有结点的值均大于它的根结点的值; 左、右子树也分别为二叉排序树查找操作步骤:若根结点的关键字值等于查找的关键字,成功。否则,若小于根结点的关键字值,递归查左子树;若大于根结点

二叉查找树,也称二叉排序树,二叉搜索树。
它或者是一棵空树;或者是具有下列性质的二叉树:

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

查找操作

步骤:

  • 若根结点的关键字值等于查找的关键字,成功。
  • 否则,若小于根结点的关键字值,递归查左子树;若大于根结点的关键字值,递归查右子树。
  • 若子树为空,查找不成功。

插入操作

步骤:

  • 首先执行查找算法,找出被插结点的父亲结点。
  • 判断被插结点是其父亲结点的左、右儿子。将被插结点作为叶子结点插入。
  • 若二叉树为空,则首先单独生成根结点。
    注意:新插入的结点总是叶子结点。

删除操作

假设被删结点是*p,其双亲是*f,不失一般性,设*p是*f的左孩子,下面分三种情况讨论:

  • 若结点*p是叶子结点,则只需修改其双亲结点*f的指针即可。
  • 若结点*p只有左子树PL或者只有右子树PR,则只要使PL或PR 成为其双亲结点的左子树即可。
  • 若结点*p的左、右子树均非空,先找到*p的中序前趋结点*s(注意*s是*p的左子树中的最右下的结点,它的右链域为空),然后有两种做法:
    • 令*p的左子树直接链到*p的双亲结点*f的左链上,而*p的右子树链到*p的中序前趋结点*s的右链上。
    • 以*p的中序前趋结点*s代替*p(即把*s的数据复制到*p中),将*s的左子树链到*s的双亲结点*q的左(或右)链上。

C++实现代码:

#include <iostream>
#include <cstring>
#include <cstdlib>
using namespace std;

struct TreeNode
{
    int val;
    TreeNode *left;
    TreeNode *right;
    TreeNode *parent;
    TreeNode(int x) : val(x), left(NULL), right(NULL), parent(NULL) {}
};

TreeNode* minNode(TreeNode *root)
{
//    if (root != NULL && root->left != NULL)
//    {
//        return minNode(root->left);
//    }
    while (root != NULL && root->left != NULL)
    {
        root = root->left;
    }

    return root;
}

TreeNode* maxNode(TreeNode *root)
{
    if (root != NULL && root->right != NULL)
    {
        return maxNode(root->right);
    }

    return root;
}

TreeNode* search(TreeNode *root, int value)
{
    if (root == NULL || root->val == value)
    {
        return root;
    }
    else if (root->val > value)
    {
        return search(root->left, value);
    }
    else if (root->val < value)
    {
        return search(root->right, value);
    }
}

void insertNode(TreeNode*& root, int value)
{
    if (search(root, value) != NULL)
    {
        return;
    }

    TreeNode *newnode = new TreeNode(value);
    TreeNode *temp = root;
    TreeNode *parentNode = NULL;
    if (root == NULL)
    {
        root = newnode; //新插入结点成为根结点
        return;
    }

    while (temp != NULL)
    {
        parentNode = temp;
        if (temp->val > value)
        {
            temp = temp->left;
        }
        else
        {
            temp = temp->right;
        }
    }

    if (value < parentNode->val)
    {
        parentNode->left = newnode;
    }
    else
    {
        parentNode->right = newnode;
    }
    newnode->parent = parentNode;
}

bool deleteNode(TreeNode*& root, int value)
{
    TreeNode *cur = search(root, value);
    TreeNode *temp;
    if (cur == NULL)
    {
        return false; //未找到结点
    }
    if (cur->left != NULL && cur->right != NULL)
    {
        TreeNode *max_node = maxNode(cur->left);
        cur->val = max_node->val;
        deleteNode(max_node, max_node->val);
    }
    else
    {
        if (cur->left == NULL && cur->right == NULL) //删除叶子结点
        {
            temp = NULL;
        }
        else if (cur->left == NULL) //要删除结点的左结点为空
        {
            temp = cur->right;
        }
        else if (cur->right == NULL) //要删除结点的右结点为空
        {
            temp = cur->left;
        }

        if (cur->parent == NULL)
        {
            root = temp;
            if (temp != NULL) temp->parent = NULL;
        }
        else
        {
            if (cur->parent->left == cur)
            {
                cur->parent->left = temp;
            }
            else
            {
                cur->parent->right = temp;
            }

            if (temp != NULL)
            {
                temp->parent = cur->parent;
            }

        }

        delete cur;
    }

    return true;
}

void preTraverse(TreeNode *root)
{
    if (root != NULL)
    {
        cout<<root->val<<" ";
        preTraverse(root->left);
        preTraverse(root->right);
    }
}

void inTraverse(TreeNode *root)
{
    if (root != NULL)
    {
        inTraverse(root->left);
        cout<<root->val<<" ";
        inTraverse(root->right);
    }
}

void postTraverse(TreeNode *root)
{
    if (root != NULL)
    {
        postTraverse(root->left);
        postTraverse(root->right);
        cout<<root->val<<" ";
    }
}

int main()
{
    TreeNode *root = NULL;
    for (int i = 0; i < 20; i++)
    {
        insertNode(root, rand() % 100);
    }

    cout<<"先序遍历:";preTraverse(root);cout<<" END"<<endl;
    cout<<"中序遍历:";inTraverse(root);cout<<" END"<<endl;
    cout<<"后序遍历:";postTraverse(root);cout<<" END"<<endl;

    for (int  i = 0; i < 20; i++)
    {
        deleteNode(root, i);
    }
    cout<<"先序遍历:";preTraverse(root);cout<<" END"<<endl;

    TreeNode *temp = minNode(root);
    temp != NULL ? cout<<temp->val<<endl : cout<<"null"<<endl;
    temp = maxNode(root);
    temp != NULL ? cout<<temp->val<<endl : cout<<"null"<<endl;

    return 0;
}

Java实现代码:

package test;

class TreeNode{
    int val;
    TreeNode left;
    TreeNode right;
    TreeNode parent;
    TreeNode(int x){
        this.val = x;
    }
}

public class BinarySearchTree {
    TreeNode root;
    TreeNode maxElem(TreeNode node){
        while (node != null && node.right != null){
            node = node.right;
        }

        return node;
    }

    TreeNode minElem(TreeNode node){
        while (node != null && node.left != null){
            node = node.left;
        }

        return node;
    }

    TreeNode search(int key){
        TreeNode temp = root;
        while (temp != null && temp.val != key){
            if (temp.val > key){
                temp = temp.left;
            }else{
                temp = temp.right;
            }
        }

        return temp;
    }

    boolean insert(int key){
        if (search(key) != null){
            return false;
        }

        TreeNode newnode = new TreeNode(key);
        TreeNode temp = root;
        if (temp == null){
            this.root = newnode;
            return true;
        }

        TreeNode parentNode = null;
        while (temp != null){
            parentNode = temp;
            if (temp.val > key){
                temp = temp.left;
            }else{
                temp = temp.right;
            }
        }
        if (parentNode.val > key){
            parentNode.left = newnode;
        }else{
            parentNode.right = newnode;
        }
        newnode.parent = parentNode;

        return true;
    }

    boolean delete(int key){
        TreeNode cur = search(key);
        if (cur == null){
            return false;
        }

        TreeNode temp = null;
        if (cur.left != null && cur.right != null){
            TreeNode leftMax = maxElem(cur.left);
            cur.val = leftMax.val;
            delete(leftMax.val);
        }else if (cur.left == null && cur.right == null){
            temp = null;
        }else if (cur.left != null && cur.right == null){
            temp = cur.left;
        }else if (cur.left == null && cur.right != null){
            temp = cur.right;
        }

        if (cur.parent == null){
            this.root = temp;
            if (temp != null){
                temp.parent = null;
            }
        }
        else{
            if (cur.parent.left == cur){
                cur.parent.left = temp;
            }else{
                cur.parent.right = temp;
            }

            if (temp != null){
                temp.parent = cur.parent;
            }
        }

        return true;
    }

    void preTraverse(TreeNode node){
        if (node != null){
            System.out.print(node.val + " ");
            preTraverse(node.left);
            preTraverse(node.right);
        }
    }

    void inTraverse(TreeNode node){
        if (node != null){
            inTraverse(node.left);
            System.out.print(node.val + " ");
            inTraverse(node.right);
        }
    }

    void postTraverse(TreeNode node){
        if (node != null){
            postTraverse(node.left);
            postTraverse(node.right);
            System.out.print(node.val + " ");
        }
    }

    public static void main(String[] args){
        BinarySearchTree bst = new BinarySearchTree();
        for (int i = 0; i < 20; i++){
            bst.insert((int)(Math.random() * 100));
            //bst.insert(i);
        }
        System.out.print("前序遍历:"); bst.preTraverse(bst.root); System.out.println();
        System.out.print("中序遍历:"); bst.inTraverse(bst.root); System.out.println();
        System.out.print("后序遍历:"); bst.postTraverse(bst.root); System.out.println();

        for (int i = 0; i < 20; i++){
            bst.delete(i);
        }
        System.out.print("前序遍历:"); bst.preTraverse(bst.root); System.out.println();
        System.out.println("Max:" + bst.maxElem(bst.root).val);
        System.out.println("Min:" + bst.minElem(bst.root).val);
    }
}

Python实现代码:

from random import random
class TreeNode:
    def __init__(self, x):
        self.val = x
        self.left = None
        self.right = None
        self.parent = None

class BinarySearchTree:   
    def __init__(self, root = None):
        self.root = root

    def minElem(self, node):
        temp = node
        while temp and temp.left:
            temp = temp.left
        return temp;

    def maxElem(self, node):
        temp = node
        while temp and temp.right:
            temp = temp.right
        return temp;

    def search(self, node, key):
        if not node:
            return None
        if node.val == key:
            return node
        elif node.val > key:
            return self.search(node.left, key)
        else:
            return self.search(node.right, key)

    def insert(self, key):
        if self.search(self.root, key):
            return
        newnode = TreeNode(key)
        if not self.root:
            self.root = newnode
            return
        parentNode = None
        temp = self.root
        while temp:
            parentNode = temp
            if temp.val > key:
                temp = temp.left
            else:
                temp = temp.right
        if parentNode.val > key:
            parentNode.left = newnode
        else:
            parentNode.right = newnode
        newnode.parent = parentNode

    def delete(self, key):
        cur = self.search(self.root, key)
        if not cur:
            return
        if cur.left and cur.right:
            leftMax = self.maxElem(cur.left)
            n = leftMax.val
            self.delete(leftMax)
            cur.val = n
        else:
            temp = None
            if cur.left:
                temp = cur.left
            elif cur.left:
                temp = cur.right

            if not cur.parent:
                self.root = temp
                temp.parent = None
            else:
                if cur.parent.left == cur:
                    cur.parent.left = temp
                else:
                    cur.parent.right = temp
                if temp:
                    temp.parent = cur.parent

    def preorderTraverse(self, node):
        if node:
            print(node.val,end = ' ')
            self.preorderTraverse(node.left)
            self.preorderTraverse(node.right)

bst = BinarySearchTree();
for i in range(0, 20):
    bst.insert(int(random()*100))
bst.preorderTraverse(bst.root)   
print()
for i in range(0, 20):
    bst.delete(i);
bst.preorderTraverse(bst.root)   
print('\nThe smallest element is %d.' % bst.minElem(bst.root).val)
print('The largest element is %d.' % bst.maxElem(bst.root).val)

没有父亲指针的C++实现代码:

#include <iostream>
#include <algorithm>
using namespace std;

struct TreeNode
{
    int val;
    TreeNode *left;
    TreeNode *right;
    TreeNode(int x) : val(x), left(NULL), right(NULL) {}
};

TreeNode* search(TreeNode *root, int key)
{
    while (root != NULL)
    {
        if (root->val > key)
        {
            root = root->left;
        }
        else if (root->val < key)
        {
            root = root->right;
        }
        else
        {
            break;
        }
    }

    return root;
}

void insertNode(TreeNode*& root, int key)
{
    TreeNode *p = root;
    TreeNode *q;
    while (p != NULL)
    {
        if (p->val > key)
        {
            q = p;
            p = p->left;
        }
        else if (p->val < key)
        {
            q = p;
            p = p->right;
        }
        else
        {
            break;
        }
    }

    if (p != NULL)
    {
        return;
    }

    TreeNode *newnode = new TreeNode(key);
    if (root == NULL)
    {
        root = newnode;
        return;
    }

    if (q->val > key)
    {
        q->left = newnode;
    }
    else
    {
        q->right = newnode;
    }
}

void deleteNode(TreeNode*& root, int key)
{
    TreeNode *p = root;
    TreeNode *q;
    while (p != NULL)
    {
        if (p->val > key)
        {
            q = p;
            p = p->left;
        }
        else if (p->val < key)
        {
            q = p;
            p = p->right;
        }
        else
        {
            break;
        }
    }

    if (p == NULL)
    {
        return;
    }

    if (p->left != NULL && p->right != NULL)
    {
        TreeNode *s = p->left;
        TreeNode *t = p;
        while (s->right != NULL)
        {
            t = s;
            s = s->right;
        }

        p->val = s->val;
        if (t == p)
        {
            p->left = s->left;
        }
        else
        {
            t->right = s->left;
        }

        delete s;
    }
    else
    {
        TreeNode *temp;
        if (p->left == NULL && p->right == NULL)
        {
            temp = NULL;
        }
        else if (p->left == NULL)
        {
            temp = p->right;
        }
        else
        {
            temp = p->left;
        }

        if (p == root)
        {
            root = temp;
        }
        else
        {
            if (q->left == p)
            {
                q->left = temp;
            }
            else
            {
                q->right = temp;
            }
        }

        delete p;
    }
}

void preorderTraverse(TreeNode *root)
{
    if (root != NULL)
    {
        cout<<root->val<<" ";
        preorderTraverse(root->left);
        preorderTraverse(root->right);
    }
}

int main()
{
    TreeNode *root = NULL;
    for (int i = 0; i < 20; i++)
    {
        insertNode(root, rand() % 50);
    }
    preorderTraverse(root); cout<<endl;

    for (int i = 0; i < 20; i++)
    {
        deleteNode(root, i);
    }
    preorderTraverse(root); cout<<endl;
}
目录
相关文章
|
7月前
|
C++
平衡二叉树(C++)
平衡二叉树(C++)
35 1
|
算法
二叉搜索树、平衡二叉树
一、二叉搜索树 这里我们不用太多书面化的语言来定义,笔者认为在讨论数据结构、算法相关的内容时用太多书面化、学术化的语言是一种让人很烦的事情。咬文嚼字,不便于读者理解。 简单来说二叉树搜索树,其实就是用来做二分查找的一种二叉树。 特点是:根节点的左子树值均小于根节点的值,根节点的右子树值均大于根节点的值。 比如123 4 567建树的结果就是
57 0
二叉查找树的认识
二叉查找树的认识
二叉查找树的认识
|
存储
红黑树、平衡二叉查找树
红黑树、平衡二叉查找树 平衡二叉查找树 非常常用的查找结构,各操作的时间复杂度与树的高度成正比
101 0
红黑树、平衡二叉查找树
|
存储 算法 Linux
【红黑树】【一种自平衡二叉查找树】
【红黑树】【一种自平衡二叉查找树】
110.平衡二叉树
110.平衡二叉树
111 0
110.平衡二叉树
|
算法 C语言
Algorithm:树相关算法(BBT/BST/B树/R树)简介(二叉查找树、二叉查找树的插入节点、二叉查找树的删除、二叉树的遍历、平衡二叉树)C 语言实现
Algorithm:树相关算法(BBT/BST/B树/R树)简介(二叉查找树、二叉查找树的插入节点、二叉查找树的删除、二叉树的遍历、平衡二叉树)C 语言实现
Algorithm:树相关算法(BBT/BST/B树/R树)简介(二叉查找树、二叉查找树的插入节点、二叉查找树的删除、二叉树的遍历、平衡二叉树)C 语言实现