zoukankan      html  css  js  c++  java
  • 二叉查找树的基本操作例程

    对于二叉查找树的最大难处,我觉得是在于删除,当删除一个元素时,简单地说有两种情况,一种是节点,一种是叶子。假设被删除值为D

    1.叶子,很简单,找到叶子的父节点,然后将这个父节点指向该叶子的树枝赋为0;有一种特殊情况是就一个根,那么释放根,然后返回0。

    2.节点,需要做两步,找到该节点的左子树的最大值或者右子树的最小值,假设为F,用F替代被删除节点的值D,然后再删除F,而F肯定是叶子,采用1中的方法。

    这种算法删除时最坏的情况就是删除点是一个节点,首先遍历一遍找到该节点D,然后再遍历该节点的某个子树找到F,再遍历一遍找到F的父节点,logn1+2logn2,小于3logn,可以再提高的是叶子节点和它的父亲可以一次性完成,而不需要两次,那么算法复杂度是2logn。当然写的复杂一些的话,可以一遍遍历就将所有要改变的节点保留下来,此时算法复杂度是logn.

    修正:

      之前的代码是因为自己对这个递归的理解不够到位,应用数据结构与算法分析中的思路,可以简化删除这个操作。在算法时间复杂度上,最大为两遍遍历。2logn。

      个人对递归也有了更好的理解,对递归表达式的展开,递归表达式很重要。

    node *delele(node *t,int element)
    {
        if(t == 0)
            return 0;
        else if(t->element > element)
            t->lefttree = delele(t->lefttree,element);
        else if(t->element < element)
            t->righttree = delele(t->righttree,element);
        else
        {
            if(t->lefttree && t->righttree)
            {
                node *tmp;
                tmp = findmin(t->righttree);
                t->element = tmp->element;
                t->righttree = delele(t->righttree,tmp->element);
            }
            else
            {
                node *tmp;
                tmp = t->lefttree?t->lefttree:t->righttree;
                free(t);
                t = tmp;
            }
        }
        return t;
    }

    以下是实现代码:

      

    typedef struct _node
    {
        int element;
        struct _node *lefttree;
        struct _node *righttree;
    }node;
    
    node * insert(node * root,int element)
    {
        if(root == 0)
        {
            root = (node *)malloc(sizeof(node));
            if(root == 0)
                return 0;
            root->element = element;
            root->lefttree = root->righttree = 0;
        }
        else if(root->element > element)
        {
            root->lefttree = insert(root->lefttree,element);
        }
        else if(root->element < element)
        {
            root->righttree = insert(root->righttree,element);
        }
        return root;
    }
    
    node * find(node * root,int element)
    {
        if(root == 0)
            return 0;
        if(root->element > element)
            return find(root->lefttree,element);
        else if(root->element < element)
            return find(root->righttree,element);
        return root;
    }
    
    void printtree(node * root)
    {
        if(root == 0)
            return 0;
        printtree(root->lefttree);
        printf("%d	",root->element);
        printtree(root->righttree);
    }
    node* destroytree(node *root)
    {
        if(root == 0)
            return 0;
        root->lefttree = destroytree(root->lefttree);
        root->righttree = destroytree(root->righttree);
        free(root);
        return 0;
    }
    
    node *findmax(node *root)
    {
        if(root == 0)
            return 0;
        if(root->righttree == 0)
            return root;
        return findmax(root->righttree);
    }
    node *findmin(node *root)
    {
        if(root == 0)
            return 0;
        if(root->lefttree == 0)
            return root;
        return findmin(root->lefttree);
    }
    node *findparent(node *root,int element)
    {
        if(root == 0)
            return 0;
        else if(root->lefttree && root->lefttree->element == element)
            return root;
        else if(root->righttree && root->righttree->element == element)
            return root;
        else if(root->element > element)
            return findparent(root->lefttree,element);
        else if(root->element < element)
            return findparent(root->righttree,element);
        else
            return 0xffffffff;
    }
    node* deleteelement(node *root,int element)
    {
        node *parent;
        node *self;
        if(root == 0)
            return -1;
        self = find(root,element);
        if(self == 0)
            return 0;
        if(self->lefttree)
        {
            node *tmp = findmax(self->lefttree);
            self->element = tmp->element;
            parent = findparent(self->lefttree,tmp->element);
            if(parent == 0xffffffff)
            {
                self->lefttree = 0;
            }
            else
            {
                parent->righttree = 0;
            }
            free(tmp);
        }
        else if(self->righttree)
        {
            node *tmp = findmin(self->righttree);
            self->element = tmp->element;
            parent = findparent(self->righttree,tmp->element);
            if(parent == 0xffffffff)
            {
                self->righttree = 0;
            }
            else
            {
                parent->lefttree = 0;
            }
            free(tmp);
        }
        else
        {
            parent = findparent(root,self->element);
            if(parent == 0xffffffff)
            {
                free(root);
            }
            else
            {
                if(parent->lefttree&&parent->lefttree->element == element)
                    parent->lefttree = 0;
                else 
                    parent->righttree = 0;
                free(self);
            }
        }
        return root;
    }
    int main()
    {
        int a[10] = {5,6,8,1,2,9,3,7,4,0};
        int i = 0;
        node *root = 0;
        node *parent = 0;
        root = insert(root,a[0]);
        for(i = 1;i<10;i++)
            insert(root,a[i]);
        root = deleteelement(root,0);
        /*for(i = 0;i<11;i++)
        {
            parent = findparent(root,i);
            if(parent == 0xffffffff)
                printf("root = %d
    ",i);
            else if(parent == 0)
                printf("not exist = %d
    ",i);
            else
                printf("%d's parent = %d
    ",i,parent->element);
        }*/
        printtree(root);
        destroytree(root);
        return 1;
    }
  • 相关阅读:
    Compiling Open Source Software for UNIX using Configure Script
    vlcandroid 移植live555到android
    xcode中armv6与armv7的困惑
    ZOJ 3204 Connect them (最小生成树,输出字典序最小的解)
    POJ 3133 Manhattan Wiring (插头DP)
    HDU 4419 Colourful Rectangle 第37届ACM/ICPC 杭州赛区网络赛 1010题 (线段树)
    HDU 3829 Cat VS Dog (二分匹配求最大独立集)
    最大流模板(SAP算法)(邻接表形式)
    HDU 4417 Super Mario 第37届ACM/ICPC 杭州赛区网络赛第1008题 (划分树)
    ZOJ 3203 Light Bulb (数学直接推公式 或者 三分法)
  • 原文地址:https://www.cnblogs.com/leo0000/p/5667677.html
Copyright © 2011-2022 走看看