数据结构 树(二叉树 链式存储)

#include "stdio.h"
#include "malloc.h"
#include "stdlib.h"

#define MAXNODE 100
typedef char TElemType;
typedef struct BiTNode
{
	TElemType data;
	struct BiTNode *lchild,*rchild;
}BiTNode,*BiTree;

//先序遍历(递归)
void PreOrder(BiTree T)
{
	if(T!=NULL)
	{
		printf("%c",T->data);
		PreOrder(T->lchild);
		PreOrder(T->rchild);
	}
}

//中序遍历(递归)
void InOrderTraverse(BiTree T)
{
	if(T==NULL)
	{
		return;
	}
	InOrderTraverse(T->lchild);
	printf("%c",T->data);
	InOrderTraverse(T->rchild);
}
//后序递归
void PostOrderTraverse(BiTree T)
{
	if(T==NULL)
	{
		return ;
	}
	else
	{
		PostOrderTraverse(T->lchild);
		PostOrderTraverse(T->rchild);
		printf("%c",T->data);
	}
}


//非递归遍历

/*
非递归遍历的先序和中序基本类似

先序在入栈前输出元素

后续再出栈后输出元素
*/

//非递归先序遍历
void NRPreOrder(BiTree bt)
{
	BiTree stack[MAXNODE],p;
	int top;
	if(!bt)//bt==NULL
	{
		return;
	}
	else
	{
		top = -1;
		p = bt;
		while(!(p == NULL&&top==-1))  //p!=NULL||top!=-1  p top同时为NULL或0时才结束即:有一个不为NULL或0都要执行
		{
			//while(p!=NULL) //p不为NULL一直向下
			if(p!=NULL)
			{
				printf("%c",p->data); //打印节点的值
				if(top<MAXNODE-1)
				{
					stack[++top]=p; //节点入栈
				}
				else
				{
					printf("栈溢出\n");
					return ;				
				}
				p= p->lchild; //不断进入左子树
			}
			else
			{
				if(top<0)
				{
					return ;
				}
				else
				{
					p=stack[top--];//出栈
					p=p->rchild;  //出栈之后指向右子树
				}
			}
		}
	}
	
}

//非递归中序遍历
void NRInOrder(BiTree bt)
{
	BiTree stack[MAXNODE],p;
	int top;
	if(!bt)//bt==NULL
	{
		return;
	}
	else
	{
		top = -1;
		p = bt;
		while(!(p == NULL&&top==-1))  //p!=NULL||top!=-1  p top同时为NULL或0时才结束即:有一个不为NULL或0都要执行
		{
			//while(p!=NULL) //p不为NULL一直向下
			if(p!=NULL)
			{
				if(top<MAXNODE-1)
				{
					stack[++top]=p; //节点入栈
				}
				else
				{
					printf("栈溢出\n");
					return ;				
				}
				p= p->lchild; //不断进入左子树
			}
			else
			{
				if(top<0)
				{
					return ;
				}
				else
				{
					p=stack[top--];//出栈
					printf("%c",p->data); //打印节点的值    
					p=p->rchild;  //出栈之后指向右子树
				}
			}
		}
	}
	
}


//后序遍历非递归
/*
后序遍历非递归
结点在第一次出栈之后,还需要进栈,也就是说,结点需要进两次栈,出两次栈
而第二次出栈时才访问结点元素,栈中设置标志
flag =1 第一次出栈,结点不访问,falg=2 第二次出栈,结点访问
*/
typedef struct 
{
	BiTree link;
	int flag;
}StackType;

void NRPostOrder(BiTree bt)
{
	StackType stack[MAXNODE];
	BiTree p;
	int sign;  //得到stacl[i].flag;
	int top;
	if(bt==NULL)
		return ;
	else
	{
		top = -1;
		p = bt;
		while(!(p==NULL&&top==-1))
		{
			if(p!=NULL)
			{
				top++;
				stack[top].link=p;
				stack[top].flag = 1;
				p=p->lchild;
			}
			else
			{
				if(top<0)
				{
					return ;
				}
				else//出栈
				{
					p=stack[top].link;
					sign = stack[top].flag;
					top--;
					if(sign == 1)
					{
						top++;
						stack[top].link=p;
						stack[top].flag = 2;
						p=p->rchild;
					}
					else
					{
						printf("%c",p->data);
						p=NULL;
					}
				}
			}
		}
	}
	
}



//层次遍历

/*
先访问指定结点
访问完之后,如果左后孩子不为空访问左右孩子进队列

*/
void LevelOrder(BiTree T)
{
	BiTree queue[MAXNODE];
	int front ,rear;
	if(T==NULL)
		return ;
	else
	{
		front =-1; //队头指针
		rear = 0;  //队尾指针
		queue[rear]=T;
		while(front!= rear)
		{
			front ++;//出队列
			printf("%c",queue[front]->data);
			if(queue[front]->lchild!=NULL)
			{
				rear++;
				queue[rear]=queue[front]->lchild;
			}
			if(queue[front]->rchild!=NULL)
			{
				rear++;
				queue[rear]=queue[front]->rchild;
			}
		}
	}
}


//创建二叉树
void CreateBiTree(BiTree *T)//按先序遍历创建二叉树   T为bt的地址  *T为bt
{
	TElemType ch;
	scanf("%c",&ch);
	//ch = getchar();
	if(ch=='#'){
		*T = NULL;
	}else
	{
		*T= (BiTree)malloc(sizeof(BiTNode));
		if((*T)==NULL)//和(!(*T))一样都是T为空时 表达式true,执行
		{
			exit(1);
		}
		else
		{
			(*T)->data = ch;
			CreateBiTree(&((*T)->lchild)); //bt->lchild是一个指针,参数要为指针的地址,故取地址
			CreateBiTree(&((*T)->rchild));
		}
	}
}


void main()
{
	BiTree bt;  //指针
	/*ABDH#K###E##CFI###G#J##*/
	CreateBiTree(&bt);//初始化指针,传参数必须为指针的地址 ,故CreateBiTree1(BiTree *bt);//指向指针的指针

	//先序
	printf("  递归先序遍历:");
	PreOrder(bt);
	printf("\n非递归先序遍历:");
	NRPreOrder(bt);

	//中序
	printf("\n\n  递归中序遍历:");
	InOrderTraverse(bt);
	printf("\n非递归中序遍历:");
	NRInOrder(bt);

	//后序
	printf("\n\n  递归后序遍历:");
	PostOrderTraverse(bt);
	printf("\n非递归后序遍历:");
	NRPostOrder(bt);

	//层次遍历
	printf("\n\n      层次遍历:");
	LevelOrder(bt);
	printf("\n");
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值