数据结构-----二叉树的遍历

数据结构学完有好长时间了。渐渐忘记了很多,在此机会以做笔记的形式将其复习一般,同时熟悉敲点代码熟悉VIM。

一,基本概念

1,二叉树是节点的有限集合,该集合或者为空(而树不允许为空)或者是由一个根和两棵互不相交的、称为该根的左子树和右子树组成。

2,几种特殊的二叉树

满二叉树:高度为h的二叉树敲好有2h -1个结点时称为满二叉树

完全二叉树:一个二叉树中,只有最下面两层结点的度(一个结点拥有的子树)小于2,并且最下一层的叶结点集中靠在左侧的若干位置上

扩充二叉树:也称2-树,扩充二叉树除叶子结点外,其余结点都必须有两个孩子。

如下图所示,显示集中特殊的二叉树。

二,二叉树的存储

1)完全二叉树可以采用顺序存储。

2)一般二叉树采用链式存储

lchilddatarchild
lchild和rchild分别为指向左右孩子的指针,data为数据域。

三,二叉树的遍历

统称分为深度遍历和广度遍历,深度遍历即:先序、中序、后续。而广度即按层次遍历

先序:若二叉树为空,则空操作,否则先访问根节点,再遍历先序左子树,最后先序右子树

中序:若二叉树为空,则空操作,否则先中序遍历左子树,再先访问根节点,最后中序遍历右子树

后序:若二叉树为空,则空操作,否则先后序遍历左子树,再后序遍历右子树,最后访问根结点

四、程序的具体实现

/*
 * =====================================================================================
 *
 *       Filename:  bttree.c
 *
 *    Description:  实现二叉树的各种遍历
 *
 *        Version:  1.0
 *        Created:  2012年08月08日 00时38分11秒
 *       Revision:  none
 *       Compiler:  gcc
 *
 * =====================================================================================
 */
#include <stdlib.h>
#include <stdio.h>
/*二叉树节点的定义*/
typedef struct BiTNode{
	int data;
	struct BiTNode *lchild,*rchild;
}BiTNode;
/*处理后序遍历的数据结构 */
typedef struct Pstack{
	BiTNode *p;
	int flag;
}Pstack;
/*队列结构*/
typedef struct Queue{
    BiTNode * arry[20];	
	int front;
	int tail;
}Queue;
static BiTNode *stack[20];
static Pstack pstack[20];
/* 处理函数,完成打印工作 */
void visit(int e)
{
	printf("%d  ",e);
	return ;
}
/* 创建二叉树 */
BiTNode * CreateBiTree()
{
	int ch;
	BiTNode *T;
	scanf("%d",&ch);
	if (ch==0)
		T=NULL;
	else
	{
		if(!(T=(BiTNode*)malloc(sizeof(BiTNode))))
			exit(1);
		T->data=ch;
		printf("请输入节点%d的左孩子\n",ch);
		T->lchild=CreateBiTree();/*构造左子树*/
		printf("请输入节点%d的右孩子\n",ch);
		T->rchild=CreateBiTree();/*构造右子树*/
	}
	return T;
}
/* 前序遍历的递归算法 */
void PreOrder(BiTNode *T,void(*visit)(int e))
{
	if (T==NULL)
	{
		return ;
	}
	else
	{
		visit(T->data);
		PreOrder(T->lchild,visit);/*遍历左子树*/
		PreOrder(T->rchild,visit);/*遍历右子树*/
	}
}
/* 前序遍历的非递归算法 */
int PreOrderTraverse(BiTNode *T, void (*visit)(int e))
{
	BiTNode *temp;
	int i=0;
	stack[i]=T;
	while(i!=-1)
	{
		while(stack[i])/*完成打印根节点现将右孩子入栈,再将左孩子入栈*/
		{
			temp=stack[i];
			visit(temp->data);
			stack[i]=temp->rchild;
			stack[++i]=temp->lchild;
		}
       while((stack[i])==NULL&&(i!=-1))	i--;/*空指针退栈 */
	}
	return 1;

}
/*中序遍历递归算法*/
int InOrder(BiTNode *T,void (*visit)(int e))
{
	if (T==NULL)
		return;
	else
	{
		InOrder(T->lchild,visit);/*遍历左子树 */
		visit(T->data);/* 输出根节点 */
		InOrder(T->rchild,visit);/* 遍历右子树 */
	}

}
/* 中序遍历非递归算法 */
int InOrderTraverse(BiTNode *T ,void (*visit)(int e))
{
	BiTNode *temp;
	int i=0;
	stack[i]=T;
	while(i!=-1)
	{
		while(stack[i])/*找到最左下的节点 */
		{
			stack[++i]=stack[i-1]->lchild;
		}
		i--;/*空指针退栈 */
		if(i!=-1)
		{
			visit(stack[i]->data);/*打印关键 */
			temp=stack[i--];/*栈顶元素退栈退栈*/
			stack[++i]=temp->rchild;/*将栈顶元素的右孩子压入堆栈*/
		}
	}
	return 1;
}
/* 后续遍历递归算法 */
int PostOrder(BiTNode *T,void (*visit)(int e))
{
	if(T==NULL)
		return;
	else
	{
		PostOrder(T->lchild,visit);
		PostOrder(T->rchild,visit);
		visit(T->data);
	}
}
/*后续遍历非递归算法 */
int PostOrderTraverse(BiTNode *T,void (*visit)(int e))
{
	BiTNode *temp;
	int i=0;
	pstack[i].p=T;
	while(i!=-1)
	{
		while(pstack[i].p&&(pstack[i].flag!=1))/*先将右孩子压栈,再将左孩子入栈*/
		{
			temp=pstack[i].p;
			pstack[i].flag=1;
			pstack[++i].p=temp->rchild;
			pstack[i].flag=2;
			pstack[++i].p=temp->lchild;
		}
       while((pstack[i].p)==NULL&&(i!=-1))	i--;/*空指针退栈 */
	   temp=pstack[i].p;
	   if(pstack[i].flag==1/*表示左右孩子都已经处理 */)
	   {
	  	    visit(temp->data);
			i--;
	   }
	}
	return 1;
}
/*按层编历二叉树 */
int LevelOrderTraverse(BiTNode *T,void (*visit)(int e))
{
	Queue queue;
	queue.tail=queue.front=0;
	BiTNode *temp;
	queue.arry[queue.tail++]=T;
	while(queue.front != queue.tail)
	{
		temp=queue.arry[queue.front++];
		if(temp!=NULL)
		{
			visit(temp->data);
			queue.arry[queue.tail++]=temp->lchild;
			queue.arry[queue.tail++]=temp->rchild;
		}

	}

	
}
int main()
{
	BiTNode *bitree;
        bitree=CreateBiTree();
	printf("前序遍历\n");
	printf("递归  :");
	PreOrder(bitree,visit);
	printf("\n非递归:");
	PreOrderTraverse(bitree,visit);
	printf("\n中序遍历\n");
	printf("递归  :");
	InOrder(bitree,visit);
	printf("\n非递归:");
	InOrderTraverse(bitree,visit);
        printf("\n后序遍历\n");
	printf("递归  :");
	PostOrder(bitree,visit);
	printf("\n非递归:");
	PostOrderTraverse(bitree,visit);
	printf("\n");
	printf("按层次遍历\n");
        LevelOrderTraverse(bitree,visit);
	printf("\n");
	return 0;
}
测试结果如下:


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值