数据结构二叉树的建立(先序)和读取(后序)

一、二叉树的性质

  • 二叉树的第i层上最多有2i-1个结点(i≥1)。
  • 深度为k的二叉树最多有2k-1个结点(k≥1 )
  • 一棵非空二叉树,若叶子结点数为n0,度数为2的结点数为n2,则n0=n2+1。

1.1 完全二叉树特有性质

  • 具有n个结点的完全二叉树的深度必为log2n+1
  • 对于具有n个结点的完全二叉树,如果按照从上到下和从左到右的顺序对二叉树中的所有结点从1开始顺序编号,则对于任意的序号为i的结点有如下性质:
  • 对于具有n个结点的完全二叉树,如果按照从上到下和从左到右的顺序对二叉树中的所有结点从1开始顺序编号,则对于任意的序号为i的结点有如下性质:
       (1)如i=1,则序号为i的结点是根结点,无双亲结点;如i>1,则序号为i的结点的双亲结点序号为i/2
      (2)如2i>n,则序号为i的结点无左孩子;如2i≤n,则序号为i的结点的左孩子结点的序号为2i
      (3)如2i+1>n,则序号为i的结点无右孩子;如2i+1≤n,则序号为i的结点的右孩子结点的序号为2i+1

完全二叉树性质1

1.2满二叉树特殊性质

  • 深度为k时,结点数n=2k-1
  • 不存在度为1的结点
  • 每个结点都有两棵高度相同的子树
  • 深度为k的完全二叉树,前k-1层构成一棵深度为k-1的满二叉树

二、二叉树的存储

2.1顺序存储

不常用,局限性比较大,不写了。

2.2链式存储

链表中每个结点由 三个区域组成:

名称意义
data数据:存放节点的数据信息
lchild存放指向左孩子的指针
rchild存放指向右孩子的指针

结点数据类型定义:

typedef  struct  BiTNode{
			DataType data;   
 			structBiTNode *lchild, *rchild;
 			 } BiTNode, *BiTree;

说明: 在n个结点的二叉链表中,有n+1个空指针域。 1

2.3二叉树的遍历

2.3.1 遍历的方法

先序:
若二叉树为空,则遍历结束,否则依次执行如下3个操作:
1.访问根结点
2.先序遍历根结点的左子树
3.先序遍历根结点的右子树

void  PreOrder(BiTreebt) 
/*先序遍历二叉树,  bt为指向二叉树(或某一子树)根结点的指针*/
{ 
	 if (bt==NULL)   
		 return ;
	 Visit(bt->data);         /*访问根结点*/
     PreOrder(bt->lchild);    /*先序遍历左子树*/
     PreOrder(bt->rchild);    /*先序遍历右子树*/
} 

中序:
若二叉树为空,则遍历结束,否则依次执行如下3个操作:
1.中序遍历根结点的左子树
2.访问根结点
3.中序遍历根结点的右子树

void  InOrder(BiTreebt) 
/*中序遍历二叉树,  bt为指向二叉树(或某一子树)根结点的指针*/
{ 
	if (bt=NULL)   
	 return ;
	 InOrder(bt->lchild);    /*中序遍历左子树*/ 
	 Visit(bt->data);       /*访问根结点*/
	 InOrder(bt->rchild);   /*中序遍历右子树*/
 } 

后序:
若二叉树为空,则遍历结束,否则依次执行如下3个操作:
1.后序遍历根结点左子树
2.后序遍历根结点右子树
3.访问根结点

void  PostOrder(BiTreebt)
 /*后序遍历二叉树,  bt为指向二叉树(或某一子树)根结点的指针*/
 {
	 if (bt=NULL)  
	  return ;
	  Post Order (bt->lchild);      /*后序遍历左子树*/ 
	  PostOrder(bt->rchild);        /*后序遍历右子树*/
	  Visit(bt->data);              /*访问根结点*/
   } 

小结

已知一棵二叉树的先序序列和中序序列,构造该二叉树的过程如下:

  1. 根据先序序列的第一个元素建立根结点;
  2. 在中序序列中找到该元素,确定根结点的左右子树的中序序列;.
  3. 在先序序列中确定左右子树的先序序列;
  4. 由左子树的先序序列和中序序列建立左子树;
  5. 由右子树的先序序列和中序序列建立右子树。

上机实验报告代码:
   先序建立二叉树,后序打印;

#include "stdio.h"    //设数据域类型为字符型

typedef struct node{
	char data;
	struct node *lchild,*rchild;
}BiTNode, *BiTree;      //指向二叉树结点的指针类型

void CreateBiTree(BiTree *t);   //构造二叉链表
void PostOrder(BiTree p);    //后序遍历
void main( )   //主函数
{
	BiTree T;
	char ch1,ch2;
	printf("\n请选择:\n");
	ch1='y';
	while(ch1=='y'||ch1=='Y')
	{
		printf("\n1------------------二叉树建立-------------");
		printf("\n2------------------后序遍历---------------");
		printf("\n3------------------退出-------------------\n");
		scanf("\n%c",&ch2);
		switch(ch2) 
		{
			case '1':printf("请按先序输入建立二叉树存储的结点序列:\n");
					 CreateBiTree(&T);
					 break;
			case '2':printf("该二叉树的后序遍历序列为:\n");  //调用后序遍历函数
					 PostOrder(T);
					 break;
			case '3':printf("Thank you.\n");
					 ch1 = 'n';
					 break;
			default: printf("输入有误,请重新选择");
		}
	}
}
void CreateBiTree( BiTree *t)  //构造二叉链表
{
	char ch;
	scanf("\n%c",&ch);
	if(ch=='0') *t=NULL;  //读入0时,将相应结点置空
	else 
	{
		*t=new BiTNode;   //生成结点空间
		(*t)->data=ch;
		CreateBiTree(&(*t)->lchild);  //构造二叉树的左子树
		CreateBiTree(&(*t)->rchild);  //构造二叉树的右子树
	}
}

void PostOrder(BiTree p) //后序遍历
{
	if(p != NULL) 
	{
		PostOrder(p->lchild);  
		PostOrder(p->rchild);  
		printf(" %c",p->data);
	}
}

效果图


  1. 全部的结点为2n,其中被占用n-1,所以2n-(n-1)=n+1; ↩︎

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值