• 二叉树


    一:二叉树的基本知识:

    二叉树是每个节点最多有两个子树的树结构。通常子树被称作“左子树”(left subtree)和“右子树”(right subtree)。二叉树常被用于实现二叉查找树和二叉堆。

    二叉树的每个结点至多只有二棵子树(不存在度大于2的结点),二叉树的子树有左右之分,次序不能颠倒。二叉树的第i层至多有2^{i-1}个结点;深度为k的二叉树至多有2^k-1个结点;对任何一棵二叉树T,如果其终端结点数为n_0,度为2的结点数为n_2,则n_0=n_2+1

    满二叉树:在一棵二叉树中,如果所有的分支结点都存在左子树和右子树,并且所有的叶子结点都在同一层上。

    完全二叉树:一棵深度为K的n个结点的二叉树,对树中的结点从上到下,从左到右编号,如果编号为i的结点与满二叉树中的编号为i的结点在二叉树中的位置相同,称这颗树为完全二叉树。

    二:二叉树的构建及遍历:

    顺序树:abd,,e,,cf,,g,,
    先序遍历打印:abdecfg
    中序遍历打印:dbeafcg
    后序遍历打印:dbefcga

    已知一个按先序序列输入的字符序列,如abc,,de,g,,f,,,(其中逗号表示空节点)。

     

    #include <stdio.h>
    #include <stdlib.h>
    #include <iostream>
    struct tree 
    {
        char data;
        struct  tree *l,*r;
    };
    //构建二叉树
    tree *build(tree *t)
    {
        char ch;
        if((ch=getchar())==',') //如果输入为',' 则指针悬空
        {
            t=NULL;
        }
        else
        {
            t=(struct tree *)malloc(sizeof(struct tree));
            t->data=ch;
            t->l =build(t->l);//建立左子树
            t->r =build(t->r);//建立右子树
        }
        return t;
    }
    //访问根 按照先序遍历访问左子树 按照先序遍历访问右子树
    void pre(tree *t)
    {
        if(t!=NULL)
        {
            printf("%c",t->data);
            pre(t->l);
            pre(t->r);
        }
    }
    //按中序遍历左子树;访问根;按中序遍历右子树
    void inprime(tree *t)
    {
        if(t!=NULL)
        {
            inprime(t->l);
            printf("%c",t->data);
            inprime(t->r);
        }
    }
    //按后序遍历左子树;按后序遍历右子树;访问根
    void outprime(tree *t)
    {
        if(t!=NULL)
        {
            outprime(t->l);
            outprime(t->r);
            printf("%c",t->data);
        }
    }
    //计算树叶数
    int count=0;
    void leaves (tree *t)
    {
        if(t!=NULL)
        {
            if(t->l==NULL && t->r==NULL)
            {
                count ++;
            }
            leaves(t->l);
            leaves(t->r);
        }
    }
    // 计算树的深度
    int deep(tree *t)
    {
        int lch,rch;
        if(!t)//t为空时返回值0
        {
            return 0;
        }
        else
        {
            lch = deep(t->l);
            rch = deep(t->r);
            if(lch>rch)
            {
                return lch+1;
            }
            else
                return rch+1;
        }
    }
    int main ()
    {
        int n;
        struct tree *t;
        t=build(t);//构建二叉树
        pre(t);//按先序遍历
        printf("
    ");
        inprime(t);//按中序遍历
        printf("
    ");
        outprime(t);//按后序遍历
        printf("
    ");
        leaves(t);//计算树叶数
        printf("%d
    ",count);
        n=deep(t);//计算树的深度
        printf("%d
    ",n);
        return 0;
    }

     

    三:二叉树的层次遍历:(参考http://www.cnblogs.com/pony1993/archive/2012/02/28/2371900.html

    当输入ABC,,DE G,,F,,结果是ABCDEFG              “   ,”代表空

    #include <stdio.h>
    #include <stdlib.h>
    #include <iostream>
    struct tree 
    {
        char data;
        struct  tree *l,*r;
    };
    //构建二叉树
    tree *build(tree *t)
    {
        char ch;
        if((ch=getchar())==',') //如果输入为',' 则指针悬空
        {
            t=NULL;
        }
        else
        {
            t=(struct tree *)malloc(sizeof(struct tree));
            t->data=ch;
            t->l =build(t->l);//建立左子树
            t->r =build(t->r);//建立右子树
        }
        return t;
    }
    //用队列 实现层次遍历
    void cheep(tree *t)
    {
        int front=0,rear=1;//front下标跟踪输出 rear记录子树
        tree *q[100];//建立队列
        q[0]=t;
        while(front <rear)
        {
            if(q[front])
            {
                printf("%c",q[front]->data);
                q[rear++]=q[front]->l;//如果存在右子树,右子树进队列
                q[rear++]=q[front]->r;//如果存在左子树,左子树进队列
                front++;
            }
            else
                front++;
        }
    }
    int main ()
    {
        int n;
        struct tree *t;
        t=build(t);//构建二叉树
        cheep(t);
    
        return 0;
    }

    四:如何由先序遍历,中序遍历还原二叉树:

    tree *creat(char *pre,char *in,int len)
    {
        int k;
        if(len<=0)
            return NULL;
        tree*head;
        head=(tree*)malloc(sizeof(tree));
        head->data=*pre;
        char *p;
        for(p=in;p!=NULL;p++) 
            if(*p==*pre)
                break;// 在中序遍历的序列中得到与先序相同的节点 
        k=p-in;
        head->l=creat(pre+1,in,k);//递归得到左子树 
        head->r=creat(pre+k+1,p+1,len-k-1);//得到右子树 
        return head;
    }

     

  • 相关阅读:
    如何写出无法维护的代码
    阅读优秀代码是提高开发人员修为的一种捷径
    防止代码变质的思考与方法
    干掉你程序中的僵尸代码
    如何防止代码腐烂
    迈出单元测试的第一步
    使用VC6.0编译C++代码的时候报错:fatal error C1071: unexpected end of file found in comment(Mark ZZ)
    Android中onTouch方法的执行过程以及和onClick执行发生冲突的解决办法
    Java中JNI的使用详解第三篇:JNIEnv类型中方法的使用
    Java中JNI的使用详解第二篇:JNIEnv类型和jobject类型的解释
  • 原文地址:https://www.cnblogs.com/pangrourou/p/3234428.html
Copyright © 2020-2023  润新知