• 二叉查找树


    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;
    }
  • 相关阅读:
    未来 3-5 年信息安全行业会如何变化,目前可以观察到的变化有哪些?
    信息安全经典书籍
    Apparmor——Linux内核中的强制访问控制系统
    深入理解SELinux
    FreebuF黑客专访系列之吴翰清(刺):接下来几年,有两样东西必定会火
    Security Checklist (路由器安全checklist)
    CPU MPU MCU SOC SOPC关系及区别
    军火库(第一期):无线电硬件安全大牛都用哪些利器?
    华为V-ISA信誉安全体系:对付新型DDoS攻击的利器
    物联网兴起 嵌入式系统安全日益受关注
  • 原文地址:https://www.cnblogs.com/pprp/p/7223673.html
Copyright © 2020-2023  润新知