数据结构_一般二叉树_链式结构_非递归遍历(C语言)

目录

  • (一)图文解析
  • (二) 代码解析
    • (1) 二叉树的基本操作
      • 1.0 二叉树的存储结构
      • 1.2 先序递归创建二叉树
      • 1.3 先序非递归遍历二叉树
      • 1.4 中序非递归遍历二叉树
      • 1.5 后序非递归遍历二叉树
      • 1.6 层序非递归遍历二叉树
    • (2) 二叉树源代码及测试
      • 2.1 源代码:
      • 2.2 测试结果:

(一)图文解析

一般二叉树采用的是链式存储结构,也就是单链表的结构,但二叉树的结点包括俩个指针域,一个指向左结点,一个指右结点,即二叉;
1、树的度: 不管哪个结点,二叉树都只能最多分出两个分支,所以二叉树的度为2;
2、树的叶子: 二叉树像树木一样分叉成两根树枝,直到树木分叉到最后不再分叉的结点,就叫做树的叶子结点。
数据结构_一般二叉树_链式结构_非递归遍历(C语言)_第1张图片

二叉树的性质

特殊形态 特点
满二叉树 深度为k且含有2k - 1个结点的二叉树(每个结点都有左右子结点)
完全二叉树 对满二叉树的最后一层,从右往左依次删除结点后,形成的二叉树都是完全二叉树
性质 特性
性质1 在二叉树的第n层上最多有2(n-1)个结点
性质2 深度为k的二叉树最多有2(k-1)个结点
性质3 对任何一棵二叉树T,如果其叶子结点数为N0,度为2的结点数为N2,则N0 = N2+1
性质4 具有n个结点的完全二叉树的深度为 (log2n)+1
性质5 (性质5应用于顺序结构的二叉树,参考二叉树的顺序结构)

(二) 代码解析

(1) 二叉树的基本操作

1.0 二叉树的存储结构

typedef struct BiTNode
{
     
	char data;//结点数据域
	struct BiTNode *Lchild, *Rchild;//左指针和右指针
}BiTNode, *BiTree;

1.2 先序递归创建二叉树

void CreatBiTree(BiTree &T)
{
     
	char ch;
	scanf("%c", &ch);//输入结点数据
	if(ch == '#')//输入为#代表结点为空,不再创建新结点
		T = NULL;
	else
	{
     
		T = (BiTNode *)malloc(sizeof(BiTNode));//为结点分配空间
		T->data = ch;//结点数据域为ch
		CreatBiTree(T->Lchild);//递归创建左结点
		CreatBiTree(T->Rchild);//递归创建右结点
	}
}

1.3 先序非递归遍历二叉树

void PreOrderTraverse(BiTree T)//先序
{
     
	LinkStack S;//定义一个栈
	BiTree p = T, q;
	InitStack(S);//初始化栈
	q =	(BiTNode *)malloc(sizeof(BiTNode));//用于存储出栈结点
	while(p || S)
	{
     
		if(p)
		{
     
			printf("%c ", p->data);//输出根结点数据
			Push(S, p);		//入栈
			p = p->Lchild;	//遍历左子树
		}
		else
		{
     
			Pop(S, q);		//出栈
			p = q->Rchild;	//遍历右子树
		}
	}
}

1.4 中序非递归遍历二叉树

void InOrderTraverse(BiTree T)//中序
{
     
	LinkStack S;
	BiTree p = T, q;
	InitStack(S);//初始化栈
	q =	(BiTNode *)malloc(sizeof(BiTNode));//存储出栈结点
	while(p || S)
	{
     
		if(p)
		{
     
			Push(S, p);		//先入栈
			p = p->Lchild;	//遍历左子树
		}
		else
		{
     
			Pop(S, q);		//出栈
			printf("%c ", q->data);//输出左结点数据
			p = q->Rchild;	//遍历右子树
		}
	}
}

1.5 后序非递归遍历二叉树

void PostOrderTraverse(BiTree T)//后序
{
     
	LinkStack S;
	BiTree p = T, q, top;
	InitStack(S);
	q =	(BiTNode *)malloc(sizeof(BiTNode));
	while(p || S)
	{
     
		while(p)//左子结点依次入栈
		{
     
			Push(S, p);		//入栈
			p = p->Lchild;	//遍历左子树
		}
		if(S)
		{
     
			top = S->Tree;		//取栈顶元素回溯到前一个结点
			if(top->Rchild && top->Rchild != T)	//回溯右子树的限制T
				p = top->Rchild;//回溯结点的右子节点入栈
			else
			{
     
				printf("%c ",top->data);
				T = top;	//设置回溯限制T,因为回溯到前一个结点的右结点可能已经遍历了
				Pop(S, q);	//出栈
			}
		}
	}
}

1.6 层序非递归遍历二叉树

void LevelOrderTraverse(BiTree T)//层序
{
     
	LinkQueue Q;
	InitQueue(Q);//初始化队列

	BiTree p = T, q;
	q = (BiTNode *)malloc(sizeof(BiTNode));//存储出队结点
	
	printf("%c ", p->data);	//输出根结点数据
	EnQueue(Q, p->Lchild);	//左子结点入队
	EnQueue(Q, p->Rchild);	//右子结点入队
	DeQueue(Q, q);			//出队
	while(q)				//当出队结点不为空
	{
     
		printf("%c ", q->data);		//输出出队结点数据
		if(q->Lchild)
			EnQueue(Q, q->Lchild);	//出队结点的左子结点入队
		if(q->Rchild)
			EnQueue(Q, q->Rchild);	//出队结点的右子结点入队
		DeQueue(Q, q);				//依次出队
	}
}

(2) 二叉树源代码及测试

2.1 源代码:

#include
#include

typedef char TElemType;

typedef struct BiTNode	//二叉树结点结构
{
     
	TElemType data;
	struct BiTNode *Lchild, *Rchild;
}BiTNode, *BiTree;

typedef struct StackNode//链栈结点结构
{
     
	BiTree Tree;
	struct StackNode *next;
}StackNode, *LinkStack;

typedef struct QNode//链队结点结构
{
     
	BiTree Tree;
	struct QNode *next;
}QNode, *QueuePoint;

typedef struct //链队结构
{
     
	QueuePoint front;
	QueuePoint rear;
}LinkQueue;

void InitStack(LinkStack &S)//初始化栈
{
     
	S = NULL;
}

void InitQueue(LinkQueue &Q)
{
     
	Q.front = Q.rear = (QNode *)malloc(sizeof(QNode));
	Q.front->next = NULL;
}

void Push(LinkStack &S, BiTree e)//入栈
{
     
	LinkStack p;
	p = (StackNode *)malloc(sizeof(StackNode));
	p->Tree = e;
	p->next = S;
	S = p;
}

void EnQueue(LinkQueue &Q, BiTree e)//入队
{
     
	QueuePoint p;
	p = (QNode *)malloc(sizeof(QNode));
	p->Tree = e;
	p->next = NULL;
	Q.rear->next = p;
	Q.rear = p;
}

void Pop(LinkStack &S, BiTree &e)//出栈
{
     
	LinkStack p;
	if(S)
	{
     
		e = S->Tree;
		p = S;
		S = S->next;
		free(p);
	}
}

void DeQueue(LinkQueue &Q, BiTree &e)//出队
{
     
	QueuePoint p;
	if(Q.front != Q.rear)
	{
     
		p = Q.front->next;
		e = p->Tree;
		Q.front->next = p->next;
		if(Q.rear == p)
			Q.rear = Q.front;
		free(p);
	}
	else
		e = NULL;
}

void CreateBiTree(BiTree &T)//创建二叉树
{
     
	char ch;
	scanf("%c", &ch);
	if(ch == '#')
		T = NULL;
	else
	{
     
		T = (BiTNode *)malloc(sizeof(BiTNode));
		T->data = ch;
		CreateBiTree(T->Lchild);
		CreateBiTree(T->Rchild);
	}
}

void PreOrderTraverse(BiTree T)//先序
{
     
	LinkStack S;
	BiTree p = T, q;
	InitStack(S);
	q =	(BiTNode *)malloc(sizeof(BiTNode));
	while(p || S)
	{
     
		if(p)
		{
     
			printf("%c ", p->data);
			Push(S, p);
			p = p->Lchild;
		}
		else
		{
     
			Pop(S, q);
			p = q->Rchild;
		}
	}
}

void InOrderTraverse(BiTree T)//中序
{
     
	LinkStack S;
	BiTree p = T, q;
	InitStack(S);
	q =	(BiTNode *)malloc(sizeof(BiTNode));
	while(p || S)
	{
     
		if(p)
		{
     
			Push(S, p);
			p = p->Lchild;
		}
		else
		{
     
			Pop(S, q);
			printf("%c ", q->data);
			p = q->Rchild;
		}
	}
}
void PostOrderTraverse(BiTree T)//后序
{
     
	LinkStack S;
	BiTree p = T, q, top;
	InitStack(S);
	q =	(BiTNode *)malloc(sizeof(BiTNode));
	while(p || S)
	{
     
		while(p)
		{
     
			Push(S, p);
			p = p->Lchild;
		}
		if(S)
		{
     
			top = S->Tree;
			if(top->Rchild && top->Rchild != T)
				p = top->Rchild;
			else
			{
     
				printf("%c ",top->data);
				T = top;	
				Pop(S, q);
			}
		}
	}
}

void LevelOrderTraverse(BiTree T)//层序
{
     
	LinkQueue Q;
	InitQueue(Q);

	BiTree p = T, q;
	q = (BiTNode *)malloc(sizeof(BiTNode));
	
	printf("%c ", p->data);
	EnQueue(Q, p->Lchild);
	EnQueue(Q, p->Rchild);
	DeQueue(Q, q);
	while(q)
	{
     
		printf("%c ", q->data);
		if(q->Lchild)
			EnQueue(Q, q->Lchild);
		if(q->Rchild)
			EnQueue(Q, q->Rchild);
		DeQueue(Q, q);
	}

}

int main()
{
     	
	BiTree T;
	printf("请输入数据('#'为空):");
	//测试用例:ABC#D###E#FG###
	CreateBiTree(T);
	printf("\n");

	printf("非递归前序遍历:");
	PreOrderTraverse(T);
	printf("\n\n");

	printf("非递归中序遍历:");
	InOrderTraverse(T);
	printf("\n\n");
	
	printf("非递归后序遍历:");
	PostOrderTraverse(T);
	printf("\n\n");

	printf("非递归层序遍历:");
	LevelOrderTraverse(T);
	printf("\n\n");
	
	return 0;
}

2.2 测试结果:

测试环境 : Windows 10
编译软件 : Visual C++ 6.0

数据结构_一般二叉树_链式结构_非递归遍历(C语言)_第2张图片
数据结构_一般二叉树_链式结构_非递归遍历(C语言)_第3张图片

你可能感兴趣的:(#,数据结构,二叉树,数据结构,c语言)