二叉树遍历

有二叉树如下图:

 

实现前序遍历(根左右): 1       2       4       3       5       7       8       9       6

实现中序遍历(左根右): 4       2       1       7       5       9       8       3       6

实现后序遍历(左右根): 4       2       7       9       8       5       6       3       1

实现层次遍历:                   1       2       3       4       5       6       7       8       9

代码实现:

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

/*
	二叉树前序遍历:根左右
		  中序遍历:左根右
		  后序遍历:左右根
*/
// 创建二叉树的节点结构体
struct treeNode
{
	int a;					// 数据域
	struct treeNode* pLeft;	// 左子树指针
	struct treeNode* pRight;// 右子树指针
};
// 创建节点
struct treeNode* CreateNode(int a);
// 连接节点
void InsertNode(struct treeNode* curNode, struct treeNode* leftNode, struct treeNode* rightNode);

// 打印数据
void Print(struct treeNode* root);

// 递归 前序遍历
void PreOrder(struct treeNode* curNode);
// 栈实现 前序遍历
void PreOrderByStack(struct treeNode* curNode);

// 递归 中序遍历
void MidOrder(struct treeNode* curNode);
// 栈实现 中序遍历
void MidOrderByStack(struct treeNode* curNode);

// 递归 后序遍历
void LastOrder(struct treeNode* curNode);
// 栈实现 后序遍历
void LastOrderByStack(struct treeNode* curNode);

// 利用队列实现层次遍历
void LayerOrder(struct treeNode* curNode);


int main()
{
	// 创建二叉树节点
	struct treeNode* T1 = CreateNode(1);
	struct treeNode* T2 = CreateNode(2);
	struct treeNode* T3 = CreateNode(3);
	struct treeNode* T4 = CreateNode(4);
	struct treeNode* T5 = CreateNode(5);
	struct treeNode* T6 = CreateNode(6);
	struct treeNode* T7 = CreateNode(7);
	struct treeNode* T8 = CreateNode(8);
	struct treeNode* T9 = CreateNode(9);

	// 连接节点
	InsertNode(T1, T2, T3);
	InsertNode(T2, T4, NULL);
	InsertNode(T4, NULL, NULL);
	InsertNode(T3, T5, T6);
	InsertNode(T6, NULL, NULL);
	InsertNode(T5, T7, T8);
	InsertNode(T7, NULL, NULL);
	InsertNode(T8, T9, NULL);
	InsertNode(T9, NULL, NULL);

	// 遍历
	printf("前序遍历\n");
	// 前
	PreOrder(T1);
	printf("\n");
	PreOrderByStack(T1);

	// 中
	printf("\n中序遍历\n");
	MidOrder(T1);
	printf("\n");
	MidOrderByStack(T1);

	// 后
	printf("\n后序遍历\n");
	LastOrder(T1);
	printf("\n");
	LastOrderByStack(T1);

	// 利用队列实现层次遍历
	printf("\n层次遍历\n");
	LayerOrder(T1);

	system("pause>0");
	return 0;
}  
// 创建节点
struct treeNode* CreateNode(int a)
{
	// 动态申请内存空间 创建节点
	struct treeNode* newNode = (struct treeNode*)malloc(sizeof(struct treeNode));
	// 判空
	if (NULL == newNode)
	{
		return NULL;
	}
	// 给节点结构体赋值
	newNode->a = a;
	newNode->pLeft = NULL;
	newNode->pRight = NULL;
	return newNode;
}
// 连接节点
void InsertNode(struct treeNode* curNode, struct treeNode* leftNode, struct treeNode* rightNode)
{
	// 判断当前父节点否为空
	if (NULL == curNode)
	{
		return;
	}
	// 当前节点左指针指向左子树节点
	curNode->pLeft = leftNode;
	// 当前节点右指针指向右子树节点
	curNode->pRight = rightNode;
}
// 打印数据
void Print(struct treeNode* root)
{
	// 当节点不为空时,进行打印数据
	if (NULL != root)
	{
		// 打印数据
		printf("%d\t", root->a);
	}
}
// 递归 前序遍历
void PreOrder(struct treeNode* curNode)
{
	// 检验参数
	if (NULL == curNode)
	{
		return;
	}
	// 根
	Print(curNode);
	// 左
	PreOrder(curNode->pLeft);
	// 右
	PreOrder(curNode->pRight);
}
// 递归 中序遍历
void MidOrder(struct treeNode* curNode)
{
	// 检验参数
	if (NULL == curNode)
	{
		return;
	}
	
	// 左
	MidOrder(curNode->pLeft);
	// 根
	Print(curNode);
	// 右
	MidOrder(curNode->pRight);
}
// 递归 后序遍历
void LastOrder(struct treeNode* curNode)
{
	// 检验参数
	if (NULL == curNode)
	{
		return;
	}
	
	// 左
	LastOrder(curNode->pLeft);
	// 右
	LastOrder(curNode->pRight);
	// 根
	Print(curNode);
}

// 栈实现 前序遍历
void PreOrderByStack(struct treeNode* curNode)
{
	// 检验参数
	if (NULL == curNode)
	{
		return;
	}
	// 声明数组 栈 类型struct treeNode*
	struct treeNode* Stack[100];
	// 定义变量用于记录数组下标
	int stackTop = -1;
	// 定义移动指针
	struct treeNode* pMove = curNode;
	// 当记录数组下标的变量不为-1 或是 移动指针不为空
	while (-1 != stackTop || NULL != pMove)
	{
		// 入栈 根 左
		while (NULL != pMove)
		{
			// 前序遍历根
			// 打印数据
			printf("%d\t", pMove->a);

			// 将移动指针记录到数组(栈中)
			Stack[++stackTop] = pMove;
			// 左移
			pMove = pMove->pLeft;
		}
		// 出栈 右
		if (-1 != stackTop)
		{
			// 将数组(栈)中的元素赋给移动指针
			pMove = Stack[stackTop--];
			// 移动指针右移
			pMove = pMove->pRight;
		}
	}
}
// 栈实现 中序遍历
void MidOrderByStack(struct treeNode* curNode)
{
	// 检验参数
	if (NULL == curNode)
	{
		return;
	}
	// 声明数组 栈 类型struct treeNode*
	struct treeNode* Stack[100];
	// 定义变量用于记录数组下标
	int stackTop = -1;
	// 定义移动指针
	struct treeNode* pMove = curNode;
	// 当记录数组下标的变量不为-1 或是 移动指针不为空
	while (-1 != stackTop || NULL != pMove)
	{
		// 入栈 根 左
		while (NULL != pMove)
		{
			// 中序遍历根
			// 将移动指针记录到数组(栈中)
			Stack[++stackTop] = pMove;
			// 左移
			pMove = pMove->pLeft;
		}
		// 出栈 左 根 右
		if (-1 != stackTop)
		{
			// 将数组(栈)中的元素赋给移动指针
			pMove = Stack[stackTop--];
			// 打印数据
			printf("%d\t", pMove->a);

			// 移动指针右移
			pMove = pMove->pRight;
		}
	}
}
// 栈实现 后序遍历
void LastOrderByStack(struct treeNode* curNode)
{
	// 检验参数
	if (NULL == curNode)
	{
		return;
	}
	// 创建数组(栈) 类型是struct treeNode*
	struct treeNode* Stack[100];
	// 定义移动指针
	int stackTop = -1;
	// 定义移动指针
	struct treeNode* pMove = curNode;
	// 定义一个记录节点是否已被访问的指针
	struct treeNode* pLastVisited = NULL;
	// 入栈
	while (NULL != pMove)
	{
		// 将移动指针装进数组中(栈)
		Stack[++stackTop] = pMove;
		// 指针左移
		pMove = pMove->pLeft;
	}
	// 出栈
	while (-1 != stackTop)
	{
		// 将数组中元素赋给移动指针
		pMove = Stack[stackTop--];
		// 判断是否进行打印数据
		// 当右节点为空,或是右节点已被访问,则进行打印数据操作
		if (NULL == pMove->pRight || pLastVisited == pMove->pRight)
		{
			// 打印数据
			printf("%d\t", pMove->a);
			// 记录已被访问(打印数据)的指针
			pLastVisited = pMove;
		}
		else
		{
			// 当右子树节点不为空 后序遍历 -> 左右根
			// 当节点不为空时进行入栈操作 移动指针右移
			if (NULL != pMove)
			{
				// 入栈操作 将移动指针装进数组中(栈)
				Stack[++stackTop] = pMove;
				// 右移
				pMove = pMove->pRight;
			}
			// 入栈 移动指针左移
			while (NULL != pMove)
			{
				// 将移动指针装进数组中(栈)
				Stack[++stackTop] = pMove;
				// 指针左移
				pMove = pMove->pLeft;
			}
		}
	}
}
// 利用队列实现层次遍历
void LayerOrder(struct treeNode* curNode)
{
	// 检验参数
	if (NULL == curNode)
	{
		return;
	}
	// 声明队列(数组) 类型 struct treeNode*
	struct treeNode* queue[100];
	// 定义队头(数组下标)出数据
	int front = 0;
	// 定义队尾(数组下标)存数据
	int back = 0;
	// 定义移动指针
	struct treeNode* pMove = curNode;

	// 入队 将移动指针装进数组中
	queue[back++] = pMove;
	// 直接打印数据
	printf("%d\t", pMove->a);
	// 循环遍历 当队头与队尾下标不同时
	while (front != back)
	{
		// 出队将队列中的元素赋给移动指针
		pMove = queue[front++];
		// 当左子树节点不为空时,打印左节点
		if (NULL != pMove->pLeft)
		{
			// 入队
			queue[back++] = pMove->pLeft;
			// 打印数据
			printf("%d\t", pMove->pLeft->a);
		}
		// 当右子树节点不为空时,打印右节点
		if (NULL != pMove->pRight)
		{
			// 入队
			queue[back++] = pMove->pRight;
			// 打印数据
			printf("%d\t", pMove->pRight->a);
		}
	}
}

 程序输出:

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值