二叉树的存储和遍历

#include<stdio.h>
#include<stdlib.h>
/*
	1.了解二叉树
		1.1 基本概念 
			
	2.二叉树的遍历
*/
//描述单一个体
typedef struct treeNode
{
	char data;				//数据域字符表示
	struct treeNode* LChild;
	struct treeNode* RChild;
}TREE,*LPTREE;
//创建二叉树
LPTREE createNode(char data)
{
	LPTREE newNode = (LPTREE)malloc(sizeof(TREE));
	newNode->data = data;
	newNode->LChild = NULL;
	newNode->RChild = NULL;
	return newNode;
}
//没有规律的树
void insertNode(LPTREE parentNode, LPTREE LChild, LPTREE RChild)
{
	parentNode->LChild = LChild;
	parentNode->RChild = RChild;
}
//打印当前结点中的元素
void printCurNodeData(LPTREE curData)
{
	printf("%c\t", curData->data);
}
//递归遍历
//先序:根  左  右
void  preOrder(LPTREE root)
{
	if (root != NULL)
	{
		printCurNodeData(root);
		preOrder(root->LChild);
		preOrder(root->RChild);
	}
}
//中序
void  midOrder(LPTREE root)
{
	if (root != NULL)
	{
		midOrder(root->LChild);
		printCurNodeData(root);
		midOrder(root->RChild);
	}
}
//后序
void  lastOrder(LPTREE root)
{
	if (root != NULL)
	{
		lastOrder(root->LChild);
		lastOrder(root->RChild);
		printCurNodeData(root);
	}
}

//非递归的遍历
/*
	把走过的结点位置入栈,并且打印走过的结点
	无路可走的时候出栈,回退
	找当前结点右边是否存在结点
*/
void preOderByStack(LPTREE root)
{
	if (root == nullptr)		//空树
		return;
	LPTREE stack[10];			//存储每次打印的位置
	int stackTop = -1;			//栈顶标记
	LPTREE pMove = root;		//从根结点开始做打印
	while (stackTop != -1 || pMove)
	{
		//根 左 右
		//找到最左边
		while (pMove)
		{
			//把路径入栈 + 打印走过的结点
			printf("%c\t", pMove->data);
			stack[++stackTop] = pMove;
			pMove = pMove->LChild;
		}
		//无路可走的处理
		if (stackTop != -1)
		{
			pMove = stack[stackTop--];	//获取栈顶元素并出栈
			pMove = pMove->RChild;		//去到右边结点
		}
	}
}
//中序非递归
//左 根 右
/*
	1.定义一个移动的指针,移动到最左边,把走过的地方入栈
	2.无路的时候,出栈,打印当前结点中的元素
	3.出栈后打印当前结点元素,判断当前结点是否存在右边,如果存在就去右边
*/
void minOrderByStack(LPTREE root)
{
	if (!root) return;
	LPTREE stack[10];
	int stackTop = -1;
	LPTREE pMove = root;
	while (stackTop != -1||pMove)
	{
		//走到最左边,把走过的节点入栈
		while (pMove)
		{
			stack[++stackTop] = pMove;
			pMove = pMove->LChild;
		}
		//无路可走的时候出栈
		if (stackTop != -1)
		{
			pMove = stack[stackTop--];	//出栈,获取栈顶元素
			printf("%c\t", pMove->data);
			pMove = pMove->RChild;
		}
	}
}
//后序非递归
//左 右 根
void lastOrderByStack(LPTREE root)
{
	if (!root) return;
	LPTREE stack[10];
	int stackTop = -1;
	LPTREE pMove = root;
	LPTREE pLastVisit = NULL;	//访问标记
	//pMove走到最左边
	while (pMove)
	{
		stack[++stackTop] = pMove;
		pMove = pMove->LChild;
	}
	while (stackTop != -1)
	{
		pMove = stack[stackTop--];
		//当前结点左右是否被访问
		if (pMove->RChild == NULL || pMove->RChild == pLastVisit)
		{
			//如果被访问就打印当前结点中的数据
			printf("%c\t", pMove->data);
			pLastVisit = pMove;		//改变标记的位置
		}
		else
		{
			//右边没有被访问
			stack[++stackTop] = pMove;
			pMove = pMove->RChild;
			while (pMove)
			{
				stack[++stackTop] = pMove;
				pMove = pMove->LChild;
			}
		}
	}
}

int main()
{
	//创建各个结点
	LPTREE A = createNode('A');
	LPTREE B = createNode('B');
	LPTREE C = createNode('C');
	LPTREE D = createNode('D');
	LPTREE E = createNode('E');
	LPTREE F = createNode('F');
	LPTREE G = createNode('G');
	//连接结点,构成二叉树
	insertNode(A, B, C);
	insertNode(B, D, NULL);
	insertNode(C, E, F);
	insertNode(D, NULL, G);
	printf("先序遍历:\n");
	preOrder(A);
	printf("\n");
	preOderByStack(A);

	printf("\n中序遍历:\n");
	midOrder(A);
	printf("\n");
	minOrderByStack(A);

	printf("\n后序遍历:\n");
	lastOrder(A);
	printf("\n");
	lastOrderByStack(A);
	printf("\n");
	system("pause");
	return 0;
}
发布了68 篇原创文章 · 获赞 12 · 访问量 3531

猜你喜欢

转载自blog.csdn.net/weixin_44795839/article/details/104295664