二叉查找树 - 删除、查找

2017-07-23 09:09:19

writer:pprp

二叉查找树,删除的功能,分为三种情况,

  1. 没有子节点
  2. 有一个子节点
  3. 有两个子节点 (有两种方法,具体见代码)

代码如下:

#include <iostream>

using namespace std;

struct tree
{
    tree*left;
    int date;
    tree*right;
};

void print(tree * root)   //用中序打印出来
{
    if(root!=NULL)
    {
        print(root->left);
        cout << root->date << endl;
        print(root->right);
    }
}
tree* insert(tree * root,int key);
tree * create(int *node,int len)    //建立一个二叉树
{
    tree *root = NULL;
    for(int i = 0 ; i< len ; i++ )
    {
        root = insert(root,node[i]);
    }
    return root;
}

tree* insert(tree * root,int key)   //在二叉树中根据规则插入一个数
{
    tree*current;
    tree*parent;
    tree*newval=new tree();

    newval->left = NULL;
    newval->right = NULL;
    newval->date = key;

    if(root == NULL)
    {
        root = newval;
    }
    else
    {
        current = root;
        while(current!=NULL)
        {
            parent = current;
            if(current->date>key)
            {
                current  = current->left;
            }
            else
            {
                current = current->right;
            }
        }
        if(parent->date > key)
        {
            parent->left = newval;
        }
        else
        {
            parent->right = newval;
        }
    }
    return root;
}

tree * bisearch(tree* root,int x)    //在二叉树中查找一个数
{
//    if(root!=NULL)
//    {
//        if(root->date == x)
//        {
//            return root;
//        }
//        else if(root->date > x)
//        {
//            root = bisearch(root->left,x);
//        }
//        else
//        {
//            root = bisearch(root->right,x);
//        }
//    }
//    return NULL;
    bool solve = false;
    while(root && !solve)
    {
        if(x == root->date)
            solve = true;
        else if(x < root->date)
            root = root->left;
        else
            root = root->right;
    }
    if(root == NULL)
        cout <<"can‘t find it" << endl;
    return root;

}

bool Delete(tree*root,int x)     //从二叉树中删除一个数
{
    bool find = false;

    tree*parent = NULL;
    tree*current = NULL;

    current = root;
    while(current&&!find)     //用parent记录下来现在节点的父节点,通过这个while循环找到x
    {
        if(current->date < x)
        {
            parent = current;
            current = current->right;
        }

        else if(current->date > x)
        {
            parent = current;
            current = current->left;
        }
        else if(current->date == x)
        {
            find = true;
        }
    }
    if(current == NULL)
        cout << "can‘t find " << x << endl;
    if(current->left == NULL && current->right == NULL)  //第一种情况,如果没有子节点
    {
        if( current == root)
            root = NULL;
        if(parent->left == current)
            parent->left = NULL;
        else
            parent->right = NULL;
        delete current;
    }
    else if(current->right == NULL || current->left == NULL)   //第二种情况,如果只有一个子节点
    {
        if(current == root)
        {
            if(current->left == NULL)
                root = current->right;
            else
                root = current->left;
        }
        else                                       //分四种情况,手动画图看看
        {
            if(parent->left == current && current->left)
                parent->left = current->left;
            else if(parent->left == current && current->right)
                parent->left = current->right;
            else if(parent->right == current && current->right)
                parent->right = current->right;
            else
                parent->right = current->left;
        }
        delete current;
    }
    else  //有两个子节点,可以有两种方法,
        //1,找到前继忠最大的点,交换;
        //2,找到后集中最小的点,交换;
        //这里采用的是第一种方案
    {
        tree * par = current;
        tree * kid = current->left;
        while(kid->right)
        {
            par = kid;
            kid = kid->right;
        }
        current->date = kid->date;
        if(par == current)
            current->left = kid->left;
        else
            par->right = kid->left;
        delete kid;
    }
    return find;
}

int main()
{
    int x;
    tree * root = NULL;
    tree * point = NULL;
    int node[11] = {1,2,3,4,5,6,7,8,9,10,11};
    root = create(node,11);

    print(root);

    cout << "您想查找的节点的值:" << endl;
    cin >> x;

    point = bisearch(root,x);

    if(point == NULL)
        cout <<"没有您要的数" << endl;
    else
        cout <<point->date<< endl;

    cout << "您想删除的数: " << endl;

    cin >> x;
    if(Delete(root,x) == true)
        cout <<"the number "<<x << " has been delete successfully!" << endl;
    else
        cout <<"can‘t find the number " <<x << endl;

    print(root);
    return 0;
}
时间: 2024-10-13 06:52:46

二叉查找树 - 删除、查找的相关文章

顺序表 初始化 插入 删除 查找 合并 交换 判断为空 求长度

#include <stdio.h> #include <stdlib.h> #define OK 1 #define TRUE 1 #define ERROR -1 #define FALSE -1 #define OVERFLOW -2 #define ElemType int #define Status int typedef int ElemType typedef int Status #define LEN sizeof(SqList) #define MLC (Li

单链表 初始化 创建 头插法 尾插法 插入 删除 查找 合并 长度

#include <stdio.h> #include <stdlib.h> #define OK 1 #define ERROR -1 #define TRUE 1 #define FALSE -1 #define NULL 0 #define OVERFLOW -2 #define ElemType int #define Status int typedef int ElemType typedef int Status #define LEN sizeof(LNode) #

在二叉查找树中查找不小于某个值的最小数值

给定一颗二叉查找树,给定一个值value,求该二叉查找树中不小于某个值value的最小数值. 思考:二叉查找树的特征就是左子节点比父节点值小,右子节点比父节点值大.在获得该二叉查找树根节点的情况下,想要得到该二叉查找树中不小于某个值得最小数值,分以下几点考虑: 1.如果currentNode.getData() == value , 则currentNode节点即为所求节点. 2.如果currentNode.getData() < value , 则当前节点的左子树所有节点的值均小于value,

LeetCode 530. Minimum Absolute Difference in BST(在二叉查找树中查找两个节点之差的最小绝对值)

题意:在二叉查找树中查找两个节点之差的最小绝对值 /** * Definition for a binary tree node. * struct TreeNode { * int val; * TreeNode *left; * TreeNode *right; * TreeNode(int x) : val(x), left(NULL), right(NULL) {} * }; */ class Solution { public: int ans = 0x3f3f3f3f; TreeNo

二叉查找树的查找、插入和删除 - Java实现

http://www.cnblogs.com/yangecnu/p/Introduce-Binary-Search-Tree.html 作者: yangecnu(yangecnu's Blog on 博客园) 出处:http://www.cnblogs.com/yangecnu/ 英文原文的出处:http://algs4.cs.princeton.edu/32bst/ 前文介绍了符号表的两种实现,无序链表和有序数组,无序链表在插入的时候具有较高的灵活性,而有序数组在查找时具有较高的效率,本文介绍

二叉查找树(1) - 查找以及插入

在WikiPedia中,对二叉查找树的定义如下: 二叉查找树,是一种基于节点的二叉树,有下面的性质: 节点的左子树中任意节点值小于根节点 节点的右子树中任意节点值大于根节点 左右子树都必须是二叉查找树,不允许存在重复节点. 二叉查找树的上述性质,保证了各节点值的顺序,这样进行查找,求最大值最小值时,会效率更高.如果没有这种顺序,则可能需要将树中的每个节点与指定的查找值进行比较. 查找一个节点值 二叉树中查找一个节点值时,首先与根节点比较,相等则返回根节点.如果根节点小于指定值,则递归的查找右子树

二叉查找树-删除的函数

数的构造同插入函数那篇文章的构造. 主要增加了查找父节点和删除的函数,同时为了方便删除了插入的函数. 获取父节点的函数如下: 1 BTree *getFather(BTree *root,BTree *child) 2 { 3 if (root == child) 4 return nullptr; 5 if (root->left == child || root->right == child) 6 return root; 7 if (root->data > child-&

wust oj 1635 线性表的删除查找增添

输入数据只有一组,有很多行.每行的格式可能是下列一种: insert a name delete name show search name 其中:a 是一个整数(≥1),name是一个姓名(由长度不超过20的英文字母组成). insert a name表示在第a个名字前插入名字name,如果a>线性表的长度,则表示在尾部插入. delete name表示删除姓名name的所有结点,线性表中允许同名情况出现. show列出线性表中所有姓名,如果表为空,则输出"0" search

ios 字符串的插入删除查找与替换,删除空格

NSString *str1 = @"This is a example.";  NSMutableString *mstr = [[NSMutableString alloc] init]; //创建可变字符串  NSRange substr; //子字符串的范围mstr = [NSMutableString stringWithString:str1];  //插入字符  [mstr insertString:@"very easy " atIndex:10];