1. 程式人生 > >(C語言版)二叉樹遍歷演算法——包含遞迴前、中、後序和層次,非遞迴前、中、後序和層次遍歷共八種

(C語言版)二叉樹遍歷演算法——包含遞迴前、中、後序和層次,非遞迴前、中、後序和層次遍歷共八種

#include <stdlib.h>
#include <stdio.h>
#include "BiTree.h"
#include "LinkStack.h"
#include "LinkQueue.h"


//初始化二叉樹(含根節點)
void InitBiTree(pBiTree &bt, int ele)
{
	bt = (BiNode *)malloc(sizeof(BiNode));
	if (bt == NULL)
	{
		printf("記憶體分配失敗!\n");
		exit(EXIT_FAILURE);
	}

	bt->ele = ele;
	bt->plchild = NULL;
	bt->prchild = NULL;
}

//建立二叉樹節點
BiNode *CreateBiTreeNode(pBiTree lchild, pBiTree rchild, int ele)
{
	BiNode *pnew = (BiNode *)malloc(sizeof(BiNode));
	if (pnew == NULL)
	{
		printf("記憶體分配失敗!\n");
		exit(EXIT_FAILURE);
	}

	pnew->ele = ele;
	pnew->plchild = lchild;
	pnew->prchild = rchild;

	return pnew;
}

//插入左子二叉樹
void InsertLChild(pBiTree parent, pBiTree lchild)
{
	parent->plchild = lchild;
}

//插入右子二叉樹
void InsertRChild(pBiTree parent, pBiTree rchild)
{
	parent->prchild = rchild;
}

//用遞迴的方法計算二叉樹的深度
int DeepBiTree(pBiTree bt)
{
	int ldeep = 0, rdeep = 0;

	if (bt)
	{
		ldeep = DeepBiTree(bt->plchild);
		rdeep = DeepBiTree(bt->prchild);
		return (ldeep > rdeep ? ldeep : rdeep) + 1;
	}
	else
		return 0;
}

//(一)遞迴先序遍歷
void RePreOrderTraverse(pBiTree bt)
{
	if(bt != NULL)
	{
		printf("%d ", bt->ele);
		RePreOrderTraverse(bt->plchild);
		RePreOrderTraverse(bt->prchild);
	}
}

//(二)遞迴中序遍歷
void ReInOrderTraverse(pBiTree bt)
{
	if(bt != NULL)
	{
		ReInOrderTraverse(bt->plchild);
		printf("%d ", bt->ele);
		ReInOrderTraverse(bt->prchild);
	}
}

//(三)遞迴後序遍歷
void RePostOrderTraverse(pBiTree bt)
{
	if(bt != NULL)
	{
		RePostOrderTraverse(bt->plchild);
		RePostOrderTraverse(bt->prchild);
		printf("%d ", bt->ele);
	}
}

//(四)非遞迴先序遍歷
void NonRePreOrderTraverse(pBiTree bt)
{
	LStack s;
	InitLinkStack(s);

	while (bt != NULL || !IsemptyLinkStack(s))
	{
		while ( bt != NULL)
		{
			printf("%d ", bt->ele);
			PushLinkStack(s, bt);
			bt = bt->plchild;
		}

		if (!IsemptyLinkStack(s))
		{
			PopLinkStack(s, bt);
			bt = bt->prchild;
		}
	}
}

//(五)非遞迴中序遍歷
void NonReInOrderTraverse(pBiTree bt)
{
	LStack s;
	InitLinkStack(s);

	while (bt != NULL || !IsemptyLinkStack(s))
	{
		while (bt != NULL)
		{
			PushLinkStack(s, bt);
			bt = bt->plchild;
		}

		if (!IsemptyLinkStack(s))
		{
			PopLinkStack(s, bt);
			printf("%d ", bt->ele);
			bt = bt->prchild;
		}
	}
}

//(六)非遞迴後序遍歷
void NonRePostOrderTraverse(pBiTree bt)
{
	LStack s;
	InitLinkStack(s);
	BiNode * pt = NULL;

	while (bt != NULL || !IsemptyLinkStack(s))
	{
		while (bt != NULL)
		{
			PushLinkStack(s, bt);
			bt = bt->plchild;
		}

		if (!IsemptyLinkStack(s))
		{
			PopLinkStack(s, bt);

			if (bt->prchild == NULL || bt->prchild == pt)
			{
				printf("%d ", bt->ele);
				pt = bt;
				bt = NULL;
			}
			else
			{
				PushLinkStack(s, bt);
				bt = bt->prchild;
			}
		}
	}
}

//(七)非遞迴層次遍歷
void NonReLevelOrderTraverse(pBiTree bt)
{
	LQueue q;
	InitLinkQueue(q);
	BiNode *pt = NULL;

	if (bt != NULL)
	{
		EnLinkQueue(q, bt);

		while (!IsemptyLinkQueue(q))
		{
			DeLinkQueue(q, pt);
			printf("%d ", pt->ele);
			if (pt->plchild != NULL)
				EnLinkQueue(q, pt->plchild);
			if (pt->prchild != NULL)
				EnLinkQueue(q, pt->prchild);
		}
	}
}

//(八)遞迴層級遍歷
void ReLevelOrderTraverse(pBiTree bt)
{
	int i, deep;

	if (bt != NULL)
	{
		deep = DeepBiTree(bt);
		for(i=1; i<deep+1; i++)
			PrintLevelNode(bt, i);
	}
}

void PrintLevelNode(pBiTree bt, int level)
{
	if (bt != NULL && level > 0)
	{
		if (level == 1)
			printf("%d ", bt->ele);
		PrintLevelNode(bt->plchild, level - 1);
		PrintLevelNode(bt->prchild, level - 1);
	}
}

main.cpp測試程式原始檔