数据结构之树和二叉树及其遍历,包括先序中序求后序和中序后序求先序

目录

 二叉树的遍历:

先序、中序求后序和中序、后序求先序的简单方法:根据坐标画图便可 

:1对多,其关系有祖先、双亲、兄弟、子孙等等,其属性有树、结点、路径、高度、深度

结点的度:孩子结点的个数(仅下一辈)

树的度:各结点度的最大值

树的深度:层级

二叉树:由一个根结点以及两颗互不相交的,分别称为左子树和右子树的二叉树组成。

二叉树的性质

第i(i>=1)层上的结点最多位2^(i-1)个

深度为k(k>=1)的二叉树最多有2^k-1个结点

叶子的数目比度数为2的结点的数目多1

        总结点树为各类结点之和:n=n0+n1+n2

        总结点数为所有子结点树加1:n=n1+2n2+1

        故得:n0=n2+1

满二叉树:深度为k(k>=1)时有2^k-1个结点的二叉树

完全二叉树:只有最下面两层有度数小于2的结点,且最下面一层的叶子结点集中在最左边的若干位置上。

        具有n个结点的完全二叉树的深度为:

                                        log2n +1  或者  log2(n+1)

二叉排序树(二叉查找树):

                        1)若左子树不为空,则左子树上所有结点的值均小于根结点的值。

                        2)若右子树不为空,则右子树上所有结点的值均小于根节点的值。

                        3)左右子树也为二叉排序树。

平衡二叉树(AVL树):是一种二叉查找树,当且仅当两个子树的高度差不超过1时,这个树是平衡二叉树。

红黑树:是许多二叉查找树中的一种,它能保证在最坏的情况下,基本动态集合操作时间为O(lgn).

B树, B-树,B+树:B树为磁盘或其他直接存取辅助设备设计的一种多路查找树,每个节点中关键字非降序排列,搜索时每个节点所作的不是二叉或者“两路”分支,而是根据该节点子女数的多路分支;

B-和B+是B树变种,为平衡的多路查找树。

B+树是应文件系统所需而出的一种B-树的变型树。

B+树是对B-树的改进,要求所有的信息都在叶子节点上,且叶子节点都在同一深度,而B-树的叶子节点为空,查找成功时到非叶子节点结束,查找失败时总是在叶子节点结束,叶子节点可以在任意深度。 

认识各种“树”的关系_G_BrightBoy的博客-CSDN博客_树的关系

 二叉树的遍历

btree.h:

#ifndef _BTREE_H_
#define _BTREE_H_
#include <stdio.h>
#include <stdlib.h>

typedef struct node{
    char data;
    struct node *lchild,*rchild;
}Btree,*pBtree;
#if 1
//参数初始化二叉树
pBtree btree_create();
#else
//返回值初始化二叉树
int btree_create(pBtree *B);
#endif
//前序遍历
void btree_preorder(pBtree t);
//中序遍历
void btree_cenorder(pBtree t);
//后序遍历
void btree_latorder(pBtree t);
//层次遍历
int btree_levelorder(pBtree t);
//释放二叉树
int btree_destory(pBtree *B);

#endif

btree.c:

#include "btree.h"
#if 1
pBtree btree_create()
{
    pBtree ta = malloc(sizeof(Btree));
    pBtree tb = malloc(sizeof(Btree));
    pBtree tc = malloc(sizeof(Btree));
    pBtree td = malloc(sizeof(Btree));
    pBtree te = malloc(sizeof(Btree));
    pBtree tf = malloc(sizeof(Btree));
    pBtree tg = malloc(sizeof(Btree));
    pBtree th = malloc(sizeof(Btree));

    ta->data = 'A';
    tb->data = 'B';
    tc->data = 'C';
    td->data = 'D';
    te->data = 'E';
    tf->data = 'F';
    tg->data = 'G';
    th->data = 'H';

    ta->lchild = tb;
    ta->rchild = te;

    tb->lchild = NULL;
    tb->rchild = tc;

    tc->lchild = td;
    tc->rchild = NULL;

    td->lchild = NULL;
    td->rchild = NULL;

    te->lchild = NULL;
    te->rchild = tf;

    tf->lchild = tg;
    tf->rchild = NULL;

    tg->lchild = th;
    tg->rchild = NULL;

    th->lchild = NULL;
    th->rchild = NULL;
    
    return ta;
}
#else
int btree_create(pBtree *B)
{
    char ch;  
    scanf("%c",&ch);
    //'#'为结束标志
    if('#' == ch)
        return -1;
    *B = malloc(sizeof(Btree));
    if(NULL == *B)
        exit(0);
    (*B)->data = ch;
    //递归创建左右孩子
    btree_create(&((*B)->lchild));
    btree_create(&((*B)->rchild));
    return 0;
}
#endif
//先序遍历
void btree_preorder(pBtree t)
{
    if(NULL == t)
        return;
    //第一次经过就打印其数据
    printf("%c\n",t->data);
    //再遍历左孩子
    btree_preorder(t->lchild);
    //最后遍历右孩子 
    btree_preorder(t->rchild);
}
//中序遍历
void btree_cenorder(pBtree t)
{
    if(NULL == t)
        return;
    btree_cenorder(t->lchild);
    printf("%c\n",t->data);
    btree_cenorder(t->rchild);
}
//后序遍历
void btree_latorder(pBtree t)
{
    if(NULL == t)
        return;
    btree_cenorder(t->lchild);
    btree_cenorder(t->rchild);
    printf("%c\n",t->data);
}
//释放二叉树
int btree_destory(pBtree *B)
{
    if(NULL == *B)
        return -1;
    btree_destory(&((*B)->lchild));
    btree_destory(&((*B)->rchild));
    free(*B);
    *B = NULL;
    return 0;
}

main.c:

#include "btree.h"

int main(int argc, char *argv[])
{ 
    pBtree t = btree_create();
    //btree_create(&t);
    btree_preorder(t);
    printf("==========\n");
    btree_cenorder(t);
    printf("==========\n");
    btree_latorder(t);
    printf("==========\n");
/*    默认*号为NULL值,且为退出条件
 *    while(1){
        printf("please input head->data:");
        scanf("%c%*c",&(t->data));
        if('*' == t->data)
            break;
        btree_create(&t);
    };
*/
    btree_destory(&t);
    if(NULL == t)
        fputs("this is NULL.\n",stdout);
    return 0;
} 

结果:

root@ubuntu:/mnt/U_share/DATA/tree/btree# make
gcc ./src/*.c -o btree -I ./inc/
root@ubuntu:/mnt/U_share/DATA/tree/btree# ./btree 
A
B
C
D
E
F
G
H
==========
B
D
C
A
E
H
G
F
==========
B
D
C
E
H
G
F
A
==========
this is NULL.

总结:二叉树的遍历一般是看顺序,如果打印字符在遍历左子树前、遍历右子树后,便是先序,中序,后序类似,这里面用到了递归的思想,有递归创建二叉树,递归遍历二叉树,递归释放二叉树,也有普通一步步创建二叉树。

循环,goto语句
二叉树循环创建
perror
return
上述两者无意义,因为已经错了,而且还是处于递归创建中,①不清楚是那次malloc错误②既然创建失败,那么就算递归创建,也基本都会错误
释放不能先、中序,①释放根节点②释放左、根结点
先遍历,再释放
能插入、不过要约定插入规则,左孩子和右孩子为NULL的地方
遍历:

先序、中序、后序、层次遍历
层次遍历不采用递归的方法(传左右孩子),深度
栈:先进后出
队列:先进先出

⭐⭐⭐用队列来层次遍历、最好用链式队列⭐⭐⭐递归创建、层次遍历

=====================================================================

先序、中序求后序和中序、后序求先序的简单方法
根据坐标画图便可

先序:4 8 7 5 2 1 3 6
中序:5 7 2 8 4 3 1 6
后序:5 2 7 8 3 6 1 4
①先序、中序求后序
4|          4
8|       8
7|     7
5|  5
2|        2
1|              1
3|            3
6|                6
   ————————————————
    5 7 8 2 4 3 1 6
②中序、后序求先序
    5 7 8 2 4 3 1 6
  ----------------
4|          4
1|              1
6|                6
3|            3
8|      8
7|    7
2|        2
5|  5
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值