算法学习记录-二叉树

树:

是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;
}

 

 

 

 

 

 

 

 

 

 

    原文作者:sjdang
    原文地址: https://www.cnblogs.com/jsgnadsj/p/3411099.html
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞