• 算法学习记录二叉树


    树:

    是n(n>=0)个节点的有限集。n=0时称为空树。

    在任意一颗非空树中:

        (1)有且仅有一个特定的称为根的节点;

        (2)当n>1时,其余节点可分为m(m>0)个互不相交的有限集T1,T2、...、Tm,其中

            每一个集合本身又是一棵树,并且称为根的子树。

    节点:

    a.根节点

    b.内部节点

    c.叶结点

    度:一个节点拥有的子节点个数。

    深度:树的层数。

    二叉树

    特点:

    a.每个节点最多两个子树。度<=2

    b.左子树和右子树是有顺序的,不能随意颠倒。

    c.即使树中某节点只有一棵子树,也要区分左右子树。

    特殊二叉树:

    1.斜树:

    链表是特殊的二叉树(斜树)。

    2.满二叉树

    3.完全二叉树

    性质:

    1.第i层上至多有2i-1 个节点(i>=1)

    2.深度为k的二叉树至多有2k-1个节点(k>=1)

    3.任意二叉树,终端节点为n0,度为2的节点数位n2;则n0=n2+1

    4.具有n个节点的完全二叉树的深度为【log2n】+1

    5.如果对一颗有n个结点的完全二叉树的结点按层序编号,对任意i:

      a.如果i=1,则结点i是二叉树的根,无双亲;如果i>1,则其双亲是结点【i/2】

      b.如果2i>n,则结点i无左孩子,否则其左孩子的结点2i

      c.如果2i+1>n,则结点i无右孩子;否则其右孩子是结点2i+1.

    顺序存储适用性不强,考虑使用链式存储结构。

    二叉链表:

    数据结构:

    typedef char dataType;
    
    typedef struct bintree{
        dataType data;
        struct bintree* lch;
        struct bintree* rch;
    }BiTNode,*pBiTNode;

    一个数据域,两个孩子指针域。

    建立二叉树(前序):

    void createBinTreeByPre(pBiTNode* T,char ch)
    {
        if (ch == '#')
        {
            *T = NULL;
        }
        else
        {
            *T = (pBiTNode)malloc(sizeof(BiTNode));
            (*T)->data = ch;
            g_p++;
            createBinTreeByPre(&((*T)->lch),*g_p);
            g_p++;
            createBinTreeByPre(&((*T)->rch),*g_p);
        }
    }


    前序建立二叉树,实质上是将树按照前序方式输入,

    比如:

     

    这样的一颗二叉树的前序遍历为:ABDGHCEIF

    但是在建立二叉树的时候,我们要引入一个符号来表示这个树结束,即叶子的两个指针应该为NULL。

    一般引入‘#’作为结束,所以对于上面那幅图 我们要将它补全。

     

    对于G H I 这有的结点,同样和F一样。

    建立二叉树的时候,输入方式为:

    char *g_ary = "ABDG##H###CE#I##F##";

    这有就建立如pic:tree-1所示的树了。

    访问树:

    对于我们人,可以形象的看到树的结构,但是在计算机中存储是按线性方式,要想遍历,只能按照一个规定的顺序遍历。

    对于二叉树,我们分为 前序遍历,中序遍历,后序遍历,层次遍历。

    前中后是对根节点(或者子树的根)为对象而区分的。

    前序:先访问中,然后对左右索引。

    中序:先索引左,访问中,索引右。

    后序:先索引左,索引右,访问中。

    这里索引和访问换个词语解释:

    索引:移动。

    访问:得到该节点信息。

    代码:

    //前序遍历
    void preVisitTree(pBiTNode r) 
    {
        
        if(r == NULL)
        {
            return ;
        }
        printf(" %c ",r->data);
        
        preVisitTree(r->lch);
        preVisitTree(r->rch);
    }
    
    
    //中序遍历
    void midVistitTree(pBiTNode r)
    {
        if (r == NULL)
        {
            return ;
        }
        
        midVistitTree(r->lch);
        printf(" %c ",r->data);
        midVistitTree(r->rch);
    
    }
    
    
    //后序遍历
    void nextVistitTree(pBiTNode r)
    {
        if (r == NULL)
        {
            return ;
        }
    
        nextVistitTree(r->lch);
        nextVistitTree(r->rch);
        printf(" %c ",r->data);
    
    }


    测试:

    int _tmain(int argc, _TCHAR* argv[])
    {
        
        pBiTNode root=NULL;
        createBinTreeByPre(&root,*g_p);
    
        printf("pre:");
        preVisitTree(root);
        printf("\n");
    
        printf("mid:");
        midVistitTree(root);
        printf("\n");
    
        printf("next:");
        nextVistitTree(root);
        printf("\n");
    
        getchar();
        return 0;
    }

    代码中的g_p是全局指针变量:(只能想到这个比较不好的方法,如果有人知道好的,请告诉我)

    char *g_p = g_ary;


    结果:

    完整代码:

    // tree.cpp : 定义控制台应用程序的入口点。
    //
    
    #include "stdafx.h"
    #include <stdlib.h>
    
    
    //char g_ary[] = {'3','4','#','7','#','#','5','#','#'};
    //char *g_ary = "ABDG##H###CE#I##F##";
    char *g_ary = "ABDH##I##EJ###CF##G##";
    char *g_p = g_ary;
    typedef char dataType;
    
    typedef struct bintree{
        dataType data;
        struct bintree* lch;
        struct bintree* rch;
    }BiTNode,*pBiTNode;
    
    void createBinTreeByPre(pBiTNode* T,char ch)
    {
        if (ch == '#')
        {
            *T = NULL;
        }
        else
        {
            *T = (pBiTNode)malloc(sizeof(BiTNode));
            (*T)->data = ch;
            g_p++;
            createBinTreeByPre(&((*T)->lch),*g_p);
            g_p++;
            createBinTreeByPre(&((*T)->rch),*g_p);
        }
    }
    
    
    //前序遍历
    void preVisitTree(pBiTNode r) 
    {
        
        if(r == NULL)
        {
            return ;
        }
        printf(" %c ",r->data);
        
        preVisitTree(r->lch);
        preVisitTree(r->rch);
    }
    
    
    //中序遍历
    void midVistitTree(pBiTNode r)
    {
        if (r == NULL)
        {
            return ;
        }
        
        midVistitTree(r->lch);
        printf(" %c ",r->data);
        midVistitTree(r->rch);
    
    }
    
    
    //后序遍历
    void nextVistitTree(pBiTNode r)
    {
        if (r == NULL)
        {
            return ;
        }
    
        nextVistitTree(r->lch);
        nextVistitTree(r->rch);
        printf(" %c ",r->data);
    
    }
    
    int _tmain(int argc, _TCHAR* argv[])
    {
        
        pBiTNode root=NULL;
        createBinTreeByPre(&root,*g_p);
    
        printf("pre:");
        preVisitTree(root);
        printf("\n");
    
        printf("mid:");
        midVistitTree(root);
        printf("\n");
    
        printf("nxt:");
        nextVistitTree(root);
        printf("\n");
    
        getchar();
        return 0;
    }
  • 相关阅读:
    PHP配置文件处理类
    PHP中实现图片上传的类库
    在PHP中实现StringBuilder类
    微软官方及第三方SDK http://msdn.microsoft.com/zhcn/jj923044
    在PHP中模拟asp的response类
    Atitit.并发测试解决方案(2) 获取随机数据库记录 随机抽取数据 随机排序 原理and实现
    atitit. access token是什么??微信平台公众号开发access_token and Web session保持状态机制
    atitit.二进制数据无损转字符串网络传输
    atitit.重装系统需要备份的资料总结 o84..
    atitit.web ui 结构建模工具总结
  • 原文地址:https://www.cnblogs.com/jsgnadsj/p/3411099.html
Copyright © 2020-2023  润新知