码迷,mamicode.com
首页 > 其他好文 > 详细

二叉查找树

时间:2015-06-27 16:26:58      阅读:140      评论:0      收藏:0      [点我收藏+]

标签:二叉查找树   bst   

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

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

查找操作

步骤:

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

插入操作

步骤:

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

删除操作

假设被删结点是*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);
    }
}

版权声明:本文为博主原创文章,未经博主允许不得转载。

二叉查找树

标签:二叉查找树   bst   

原文地址:http://blog.csdn.net/foreverling/article/details/46661937

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!