二叉樹遍歷(前序遍歷、中序遍歷、後序遍歷、層次遍歷)C/C++

二叉樹的遍歷方式有四種:遍歷的時候記住,左子樹一定是先於右子樹遍歷的,根最先遍歷就是先序遍歷,根在中間就是中序遍歷,根在最後遍歷就是後序遍歷。並且,遍歷左子樹和右子樹的時候,遍歷的方式也是遵循大的遍歷規則,比如二叉樹遍歷方式爲先序遍歷,那麼左子樹和右子樹遍歷的時候,也是按照這種方式進行遍歷。

  1. DLR – 先序遍歷:(先根遍歷)先根  再左  再右
  2. LDR – 中序遍歷:(中根遍歷)先左  再根  再右
  3. LRD – 後序遍歷:(後跟遍歷)先左  再右  再根
  4. 層次遍歷 –        :一層一層往下遍歷(這個用的比較少)

對於上面這棵二叉樹,它的遍歷結果爲:

先序遍歷:ABDECFG

中序遍歷:DBEAFCG

後續遍歷:DEBFGCA

層次遍歷:ABCDEFG

 

二叉樹自身具有遞歸特性,所以可以利用遞歸對二叉樹進行遍歷。

先定義一個結構體:

//二叉樹節點結構體
typedef struct BinaryTreeNode
{
	char data;  //數據 假設爲char類型
	BinaryTreeNode *left;  //左孩子節點
	BinaryTreeNode *right;  //右孩子節點
}Node;

一、先序遍歷

//先序遍歷
void preOrder(const Node*root)
{
	if (NULL == root)
	{
		return;
	}

	printf("%c ", root->data);
	preOrder(root->left);
	preOrder(root->right);
}

二、中序遍歷

//中序遍歷
void inOrder(const Node*root)
{
	if (NULL == root)
	{
		return;
	}

	
	inOrder(root->left);
	printf("%c ", root->data);
	inOrder(root->right);
}

三、後序遍歷

//後序遍歷
void  laOrder(const Node *root)
{
	if (NULL == root)
	{
		return;
	}

	laOrder(root->left);
	laOrder(root->right);
	printf("%c ", root->data);
}

綜合三種遍歷方式,發現在遞歸的方式中

laOrder(root->left);
laOrder(root->right);
printf("%c ", root->data);  //這條語句在第一行就是先序遍歷,中間就是中序遍歷,最後就是後序遍歷

四、層次遍歷

因爲層次遍歷是從上到下,從左到右 逐行遍歷的,這種類型爲廣度遍歷。而前三個遍歷方式,爲深度遍歷。所以對於層次遍歷不建議用遞歸的方式。但是爲了統一,我這裏也寫一個遞歸的層次遍歷。

//層次遍歷
void leOrder(const Node *root,const int depth,int once = 0)
{
	if (NULL == root || 0 == depth)
	{
		return;
	}
	
	if(once)
		printf("%c ", root->data);
	if (NULL != root->left)
		printf("%c ", root->left->data);
	if (NULL != root->right)
		printf("%c ", root->right->data);
	leOrder(root->left, depth - 1);
	leOrder(root->right, depth - 1);
	
}

這個遞歸看上去也挺像的。

 

看一下自己的main函數,測試的代碼:

int main()
{
	//準備數據
	Node nodeA = { 'A',NULL,NULL };
	Node nodeB = { 'B',NULL,NULL };
	Node nodeC = { 'C',NULL,NULL };
	Node nodeD = { 'D',NULL,NULL };
	Node nodeE = { 'E',NULL,NULL };
	Node nodeF = { 'F',NULL,NULL };
	Node nodeG = { 'G',NULL,NULL };

	//建立關係
	nodeA.left = &nodeB;
	nodeA.right = &nodeC;

	nodeB.left = &nodeD;
	nodeB.right = &nodeE;

	nodeC.left = &nodeF;
	nodeC.right = &nodeG;


	//調用遞歸函數
	preOrder(&nodeA);
	printf("\n");
	inOrder(&nodeA);
	printf("\n");
	laOrder(&nodeA);
	printf("\n");
	leOrder(&nodeA,3,1);
	printf("\n");


	system("pause");
	return 0;
}

運行的結果也看一下:

 

遞歸挺佔用資源的,所以可以用棧的方式實現前、中、後序遍歷,用隊列或者數組什麼的實現層次遍歷。這個實現後面在寫了。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章