二叉树的前中后递归与非递归遍历算法实现

(1) 二叉树的前序遍历程序,包含递归、非递归。
(2) 二叉树的中序遍历程序,包含递归、非递归。
(3) 二叉树的后序遍历程序,包含递归、非递归。
代码如下

#include <stdio.h>
#include <stdlib.h>


// 定义节点
typedef struct Node {
	char data;
	struct Node* lChild;
	struct Node* rChild;
} BinTNode;

// 根据广义表表示二叉树结构来创建二叉树链表
BinTNode* createTree(char *str) {
	// 用指针数组st存放双亲节点
	BinTNode *st[100];
	// 用来一生成节点时用的
	BinTNode *p = NULL;
	// 二叉树链表的头节点
	BinTNode *b = NULL;
	// top用来记录st的栈顶,key用来记录下一个节点是当前节点的左子树(用1表示)还是右子树(用2表示),j是用来遍历str字符串用的
	int top = -1, key, j = 0;
	// 取得第一个字符
	char ch = str[j];
	// 当字符串没有结束,就继续循环,'\0'是字符串的结束标记
	while (ch != '\0') {
		// 在遍历广义表表示二叉树结构过程中,会遇到'(',',',')'和字母
		switch (ch) {
			// 遇到'(',就是左子树,将key标记为1,以作记录,将当前节点记录到栈st中
		case '(':
			top++;
			st[top] = p;
			key = 1;
			break;
			// 遇到',',就是右子树,将key标记为1,以作记录
		case ',':
			key = 2;
			break;
			// 遇到')',说明此子树已遍历完成,要返回到上一个双亲节点,准备遍历双亲节点的另一棵子树
		case ')':
			top--;
			break;
			// 遇到节点,为节点申请内存,并初始化节点
		default:
			p = (BinTNode*)malloc(sizeof(BinTNode));
			p->data = ch;
			p->lChild = p->rChild = NULL;
			// 记录头结点
			if (b == NULL) {
				b = p;
			}
			else {
				// 如果是非头结点,那么就根据key的值,将节点添加到双亲节点的子树上去
				switch (key) {
				case 1:
					st[top]->lChild = p;
					break;
				case 2:
					st[top]->rChild = p;
					break;
				}
			}
		}
		// 遍历下一个字符
		j++;
		ch = str[j];
	}
	// 返回头结点
	return b;
}

void preOrder(Node* root)
{
	Node* stack[100], *curr;
	int top, end;

	if (root == NULL)
		return;

	top = end = 0;

	//根结点入栈
	stack[top++] = root;

	while (top > 0)
	{
		//取栈顶
		curr = stack[--top];
		printf("%c ", curr->data);
		//右子树入栈
		if (curr->rChild)
			stack[top++] = curr->rChild;

		//左子树入栈	
		if (curr->lChild)
			stack[top++] = curr->lChild;

		//访问节点	

	}
	printf("\n");
	return;
}


//中序遍历,非递归
void inorder(Node *root)
{
	Node *stack[1000], *curr;
	int top, end;

	if (root == NULL)
		return;

	top = end = 0;
	//根结点进栈
	stack[top++] = root;

	//当前节点指向左孩子
	curr = root->lChild;

	while (curr || top > 0)
	{
		//节点存在,则父节点进栈,指向左孩子
		if (curr)
		{
			if (curr->lChild)
			{
				stack[top++] = curr;
				curr = curr->lChild;
				continue;
			}
		}
		else
		{
			curr = stack[--top];
		}

		//取栈顶,访问后,指向右孩子
		printf("%c ", curr->data);
		curr = curr->rChild;
	}
	printf("\n");

	return;
}


//后序遍历,非递归
void postOrder(Node* root)
{
	Node* stack[1000], *curr,*prev=NULL;
	int top, end;

	if (root == NULL)
		return;

	top = end = 0;

	//根结点入栈
	stack[top++] = root;

	//指向左孩子
	curr = root->lChild;

	while (curr || top > 0)
	{
		//只要存在孩子节点,则父节点进栈,指向其孩子节点。
		if (curr)
		{
			if (curr->lChild|| curr->rChild)
			{
				stack[top++] = curr;
				if (curr->lChild)
					curr = curr->lChild;
				else
					curr = curr->rChild;
				continue;
			}
		}
		else
		{
			//取栈顶,如果存在右孩子且和上一个访问节点不一样,则父节点
			//继续进栈,指向右孩子。
			curr = stack[--top];

			if (curr->rChild && curr->rChild != prev)
			{
				stack[top++] = curr;
				curr = curr->rChild;
				continue;
			}
		}

		//访问节点同时保存访问的位置。
		printf("%c ", curr->data);
		prev = curr;
		curr = NULL;
	}
	printf("\n");
	return;
}
//前序递归遍历
void preTraverse(Node* T)
{
	if (T)
	{
	 printf("%c  ",T->data);
		preTraverse(T->lChild);
		preTraverse(T->rChild);
	}
}

//中序递归遍历
void midTraverse(Node *T)
{
	if (T)
	{
		midTraverse(T->lChild);
		printf("%c  ", T->data);
		midTraverse(T->rChild);
	}
}

//后序递归遍历
void postTraverse(Node* T)
{
	if (T)
	{
		postTraverse(T->lChild);
		postTraverse(T->rChild);
		printf("%c  ", T->data);
	}
}

int main() {
	char str[] = "(a(b(,d(e,f)),c))";

 Node* tree = createTree(str);
 printf("前序非递归遍历为\n");
 preOrder(tree);
 printf("中序非递归遍历为\n");
 inorder(tree);
 printf("后序非递归遍历为\n");
 postOrder(tree);
 printf("前序递归遍历为\n");
 preTraverse(tree);
 printf("\n");
 printf("中序递归遍历为\n");
 midTraverse(tree);
 printf("\n");
 printf("后序递归遍历为\n");
 postTraverse(tree);
	return 0;
}

运行截图如下
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值