• C 二叉查找树的基本操作


    最近研究一下二叉树排序问题,找到的资料还真是五花八门,说得也是千奇百怪。

    分析一下原因,还是因为数的特性,造成结果的不唯一性造成的大家看了很多,似乎都有理,好像明白了,一综合又糊涂了的结果。

    我这里给出一个我自认为很完整,也很精简,也容易理解和应用的框架,可以方便于应用在实际工程里的代码。

    ————————————————————————————————————————————————————————

    排序二叉树的建立、插入、删除、查找

    对于排序二叉树,其创建、插入和查找的算法差不多:小了往左,大了往右。

    对于二叉排序树,其删除要稍微复杂一点,分成3种基本情况,即
    1)删除的结点是叶子节点
    2)删除结点只有左子树或者只有右子树
    3)删除的结点既有左子树、又有右子树

    //bstTest.c

    //本例程里采用的是前继承元素替代法实现左右子结点都存在的情况时的删除

    // 删除节点左子树的最右边的元素替代之,相当于用前继节点替代

    #include "stdio.h"     

    #include "stdlib.h"

    typedef struct _BSTNode 

    {

        int key;

        int value;

        struct _BSTNode *lchild,*rchild;

    }BSTNode,*PBSTNode;

    int bst_insert(PBSTNode *pr, int key, int value)

    {

        if (!*pr)

        {

            *pr = (PBSTNode)malloc(sizeof(BSTNode));

            if (!*pr)

            {

                return -1;

            }

            (*pr)->key = key;

            (*pr)->value = value;

            (*pr)->lchild=(*pr)->rchild=NULL;

            return 0;

        }

        else if (key==(*pr)->key)

        {

            return -1;

        }

        else if (key<(*pr)->key)

        {

            return bst_insert(&(*pr)->lchild, key, value);

        }

        else

        {

            return bst_insert(&(*pr)->rchild, key, value);

        }

    }

    PBSTNode bst_search(PBSTNode r, int key)

    {

        if (!r)

        {

            return NULL;

        }

        PBSTNode p = r;

       

        while (p)

        {

            if (key<p->key)

            {

                p = p->lchild;

            }

            else if (key>p->key)

            {

                p = p->rchild;

            }

            else

            {

                return p;

            }

        }

        return NULL;

    }

    int bst_remove(PBSTNode *pr, int key)

    {

        if (!*pr)

        {

            return -1;

        }

       

        if (key==(*pr)->key)

        {

            PBSTNode p;

            if (!(*pr)->lchild&&!(*pr)->rchild)

            {

                p = *pr;

                *pr = NULL;

                free(p);

            }

            else if (!(*pr)->lchild)

            {

                p = *pr;

                *pr = (*pr)->rchild;

                free(p);

            }

            else if (!(*pr)->rchild)

            {

                p = *pr;

                *pr = (*pr)->lchild;

                free(p);

            }

            else

            {

                // r is just replace with

                //  max node leftchild tree in value,

                //  truely, s is the free node.

                PBSTNode pre = *pr;

                PBSTNode s = (*pr)->lchild; 

                while (s->rchild)

                {

                    pre = s;

                    s = s->rchild;

                }

                (*pr)->key = s->key;

                (*pr)->value = s->value;

                if (pre==*pr)

                {

                   (*pr)->lchild = s->lchild;

                }

                else

                {

                    pre->rchild = s->lchild;

                }

                free(s);

            }

            return 0;

        }

        else if (key<(*pr)->key)

        {

            return bst_remove(&(*pr)->lchild, key);

        }

        else

        {

            return bst_remove(&(*pr)->rchild, key);

        }

    }

    void PreOrderTraverse(PBSTNode r)

    {

        if (!r)

        {

            return;

        }

        printf("%d", r->value);

        PreOrderTraverse(r->lchild);

        PreOrderTraverse(r->rchild);

    }

    void MidOrderTraverse(PBSTNode r)

    {

        if (!r)

        {

            return;

        }

        MidOrderTraverse(r->lchild);

        printf("%d", r->value);

        MidOrderTraverse(r->rchild);

    }

    void PostOrderTraverse(PBSTNode r)

    {

        if (!r)

        {

            return;

        }

        PostOrderTraverse(r->lchild);

        PostOrderTraverse(r->rchild);

        printf("%d", r->value);

    }

    int main()

    {

        PBSTNode root = NULL;

        // build binary search tree

        bst_insert(&root, 7, 0);

        bst_insert(&root, 3, 1);

        bst_insert(&root, 8, 2);

        bst_insert(&root, 5, 3);

        bst_insert(&root, 9, 4);

        bst_insert(&root, 1, 5);

        bst_insert(&root, 2, 6);

        bst_insert(&root, 4, 7);

        bst_insert(&root, 6, 8);

        bst_insert(&root, 0, 9);

        // mid order traverse

        MidOrderTraverse(root);

        printf(" ");

        // remove node with key to equal 1

        if (0==bst_remove(&root, 1))

        {

            // search node with key to equal 3

            PBSTNode p = bst_search(root, 3);

            if (p)

            {

                printf("root %p, 3 node is at %p ", root, p);

            }

        }

    }

    //result

    Finally:

    在有序结构的查找方面,排序二叉树是效率远高于线性数组的技术,还是非常有用的。

    比如,在TCPServer里,因为epoll模型只记录socket,所以在SSL链接里,我们自己的工程里就要建立排序二叉树记录SSL socket,便于高效映射socket。

    还是要靠大家自己理解啊!!!“如人饮水,冷暖自知。”

      

  • 相关阅读:
    Neo4j学习案例【转】
    Genymotion安装总结
    软件工程实践总结
    Markdown中的缩进
    Beta Daily Scrum 第七天
    随堂软工团队小测
    PMD(Put Me Down)用例测试
    第三次作业——个人作业——软件产品案例分析
    用例图
    毕设导师智能匹配
  • 原文地址:https://www.cnblogs.com/woodzcl/p/8007581.html
Copyright © 2020-2023  润新知