慕课(3)

树:
树状图是一种数据结构,它是由n(n>=1)个有限结点组成一个具有层次关系的集合。把它叫做“树”是因为它看起来像一棵倒挂的树,也就是说它是根朝上,而叶朝下的。它具有以下的特点:
每个结点有零个或多个子结点;没有父结点的结点称为根结点;每一个非根结点有且只有一个父结点;除了根结点外,每个子结点可以分为多个不相交的子树。

定义:
(1)每个元素称为结点(node);
(2)有一个特定的结点被称为根结点或树根(root)。
(3)除根结点之外的其余数据元素被分为m(m≥0)个互不相交的集合T1,T2,……Tm-1,其中每一个集合Ti(1<=i<=m)本身也是一棵树,被称作原树的子树(subtree)。

种类:
无序树:树中任意节点的子结点之间没有顺序关系,这种树称为无序树,也称为自由树;
有序树:树中任意节点的子结点之间有顺序关系,这种树称为有序树;
二叉树:每个节点最多含有两个子树的树称为二叉树;
完全二叉树
满二叉树
哈夫曼树:带权路径最短的二叉树称为哈夫曼树或最优二叉树;

二叉树:
在计算机科学中,二叉树是每个结点最多有两个子树的树结构。通常子树被称作“左子树”(left subtree)和“右子树”(right subtree)。二叉树常被用于实现二叉查找树和二叉堆。
一棵深度为k,且有2^k-1个结点的二叉树,称为满二叉树。这种树的特点是每一层上的结点数都是最大结点数。而在一棵二叉树中,除最后一层外,若其余层都是满的,并且或者最后一层是满的,或者是在右边缺少连续若干结点,则此二叉树为完全二叉树。具有n个结点的完全二叉树的深度为floor(log2n)+1。深度为k的完全二叉树,至少有2k-1个叶子结点,至多有2k-1个结点。

类型
(1)完全二叉树——若设二叉树的高度为h,除第 h 层外,其它各层 (1~h-1) 的结点数都达到最大个数,第h层有叶子结点,并且叶子结点都是从左到右依次排布,这就是完全二叉树。
(2)满二叉树——除了叶结点外每一个结点都有左右子叶且叶子结点都处在最底层的二叉树。
(3)平衡二叉树——平衡二叉树又被称为AVL树(区别于AVL算法),它是一棵二叉排序树,且具有以下性质:它是一棵空树或它的左右两个子树的高度差的绝对值不超过1,并且左右两个子树都是一棵平衡二叉树。

二叉树有两种存储结构:
顺序存储方式:

typenode=record
data:datatype
l,r:integer;
end;
vartr:array[1..n]ofnode;

链表存储方式:

typebtree=^node;
node=record
data:datatye;
lchild,rchild:btree;
end;

二叉树的遍历:
遍历是对树的一种最基本的运算,所谓遍历二叉树,就是按一定的规则和顺序走遍二叉树的所有结点,使每一个结点都被访问一次,而且只被访问一次。由于二叉树是非线性结构,因此,树的遍历实质上是将二叉树的各个结点转换成为一个线性序列来表示。
设L、D、R分别表示遍历左子树、访问根结点和遍历右子树, 则对一棵二叉树的遍历有三种情况:DLR(称为先根次序遍历),LDR(称为中根次序遍历),LRD (称为后根次序遍历)。

先序遍历:

void print(struct node *root){
    if(root!=NULL){
        printf("%c",root->data);
        print(root->l);
        print(root->r);
    }
}

中序遍历:

void print(struct node *root){
    if(root!=NULL){
        print(root->l);
        printf("%c",root->data);
        print(root->r);
    }
}

后序遍历:

void print(struct node *root){
    if(root!=NULL){
        print(root->l);
        print(root->r);
        printf("%c",root->data);
    }
}

层次遍历:
即按照层次访问,通常用队列来做。访问根,访问子女,再访问子女的子女(越往后的层次越低)(两个子女的级别相同)。

关于先中后序遍历唯一不同的就是这个输出的位置所在。

放一个例题:
描述
给定一个序列,按先序序列建立二叉树。输出建立后的二叉树的从上到下层次遍历序列。

格式
输入格式
一个序列

输出格式
从上之下层次序列

样例
样例输入 Copy
ABC##DE#G##F###
样例输出 Copy
ABCDEFG

#include<stdio.h>
#include<stdlib.h>
struct node
{
    char data;
    struct node *l;
    struct node *r;
}*p,*q[1000];
struct node *creat()
{
    char ch;
    struct node *head;
    scanf("%c",&ch);
    if(ch=='#')
    {
        head=NULL;
    }
    else
    {
        head=(struct node *)malloc(sizeof(struct node));
        head->data=ch;
        head->l=creat();
        head->r=creat();
    }
    return head;
}
void print(struct node *root)
{
    if(root==NULL)
        return;
    q[0]=root;
    int n,m;
    n=0;
    m=1;
    while(n<m)
    {
        printf("%c",q[n]->data);
        if(q[n]->l)
        {
            q[m]=q[n]->l;
            m++;
        }
        if(q[n]->r)
        {
            q[m]=q[n]->r;
            m++;
        }
        ++n;
    }
}
int main()
{
    p=creat();
    print(p);
    printf("\n");
    return 0;
}

发布了13 篇原创文章 · 获赞 0 · 访问量 344

猜你喜欢

转载自blog.csdn.net/JSUChengyuezhen/article/details/104407138
今日推荐