1. 程式人生 > >二叉樹遞迴遍歷與非遞迴遍歷

二叉樹遞迴遍歷與非遞迴遍歷

  1. 遞迴前序遍歷

二叉樹的建立就是遞迴的思想,每個結點都可以看作一個樹。前序遍歷是根->左->右的順序,先列印根結點,分別將根的左右結點遞迴列印

#include <stdio.h>
#include<stdlib.h>
typedef struct node
{

	int value;
	struct node *pLeft;
	struct node *pRight;

}BinaryTree;

void RPreTraversal(BinaryTree * br)
{
	if(br==NULL)
		return;
	printf("%d\n",br->value);
	RPreTraversal(br->pLeft);
	RPreTraversal(br->pRight);

}

2.非遞迴前序遍歷

藉助輔助棧來進行非遞迴的前序遍歷

  • 結點非空,列印,入棧向左遍歷(迴圈)
  • 彈出棧頂元素
  • 判斷元素的的右結點,進入迴圈,執行第一步
//輔助棧
#include<stdio.h>
#include <stdlib.h>
#include<stdbool.h>
typedef struct node
{

	int value;
	struct node *pLeft;
	struct node *pRight;

}BinaryTree;
typedef struct Node
{
	BinaryTree* nValue;
	struct Node *pNext;
}Mystack;
typedef struct StackNode
{
	Mystack *pTop;
	int length;//棧元素長度
	bool flag;//棧標誌
}StackInt;
void Myinit(StackInt**s)
{
	*s=(StackInt*)malloc(sizeof(StackInt));
	if(*s == NULL)
	{
		printf("create stack failed");
		return;
	}
	(*s)->pTop = NULL;
	(*s)->length =0;
	(*s)->flag =true;

}
void listpush(StackInt *s,BinaryTree *n)
{
	if(s->flag==false)
		return;
	Mystack*pTemp = NULL;
	pTemp = (Mystack*)malloc(sizeof(Mystack));
	pTemp->nValue =n;
	pTemp->pNext = s->pTop;
	s->pTop = pTemp;
	s->length++;

}
BinaryTree* listpop(StackInt *s)
{
	if(s->flag == false)
		return NULL;
	if(s->pTop == NULL)
		return NULL;
	else
	{
		BinaryTree* n;
		Mystack*pTemp =NULL;
		pTemp =s->pTop;
		n=(s->pTop)-> nValue;
		s->pTop=(s->pTop)->pNext;
		s->length--;
		free(pTemp);
		pTemp = NULL;
		return n;
	}
}
void ClearStack(StackInt *s)
{
	if(s->flag == false)
		return;
	while(s->pTop!=NULL)
	{
		listpop(s);

	}


}
void DestoryStack(StackInt **s)
{
	ClearStack(*s);
	(*s)->flag=false;
	free(*s);
	(*s) =NULL;
	printf("stack destorystack!");

}
BinaryTree* GetTop(StackInt *s)
{
	BinaryTree* n;
	if(s->pTop == NULL)
	{
		printf("Top is null");
		return NULL;

	}
	n=(s->pTop)->nValue;
	return n;
}
int Getcount(StackInt *s)
{

	if(s == NULL ||s->pTop == NULL)
	{
		printf("stack is null");
		return -1;

	}
	return (s->length);
}
int isEmpty(StackInt *s)
{
	if(s== NULL||s->pTop == NULL)
		return 1;
	else
	{
		return 0;
	}

}
void URPreTraversal(BinaryTree *tree)
{
	if(tree ==NULL)
		return;
	//申請棧
	StackInt *s = NULL;
	Myinit(&s);
	//節點非空,列印,入棧,
	while(1)
	{
		while (tree!=NULL)
		{
			printf("%d ",tree->value);
			listpush(s,tree);
			tree=tree->pLeft;
		}
		//彈出
		tree =listpop(s);
		//判斷是否為空,當棧內元素為空時,結束迴圈
		if(tree == NULL)
			break;
		//向右遍歷
		tree = tree->pRight;

	}


}

3.遞迴中序遍歷

中序遍歷的順序是左->根->右

void RInorderTraversal(BinaryTree *br)
{
	if(br == NULL)
		return;
	RInorderTraversal(br->pLeft);
	printf("%d\n",br->value);
	RInorderTraversal(br->pRight);
}

4.非遞迴中序遍歷

void URInorderTraversal(BinaryTree *tree)
{
	if(tree ==NULL)
		return;
	StackInt *s = NULL;
	Myinit(&s);
	while(1)
	{
		while(tree !=NULL)
		{
			listpush(s,tree);
			tree =tree->pLeft;

		}
		tree =listpop(s);
		if(tree== NULL)
			break;
		printf("%d ",tree->value);
		tree=tree->pRight;
	}
}

5.遞迴後序遍歷

後序遍歷的順序是左->右->根

void RPostTraversal(BinaryTree *br)
{
	if(br == NULL)
		return;
	RPostTraversal(br->pLeft);
	RPostTraversal(br->pRight);
	printf("%d\n",br->value);
}

6.非遞迴後序遍歷

‘非遞迴後序遍歷不能直接彈出根節點,因為要通過根節點去找他的右結點,當根結點的右結點為空或者右結點為棧內剛剛上一次彈出的結點,就可以彈出根節點。

void URPostTraversal(BinaryTree *tree)
{
	if(tree==NULL)
		return;
	StackInt *s =NULL;
	Myinit(&s);
	BinaryTree *p = NULL;
	while(1)
	{
		while(tree !=NULL)
		{
			listpush(s,tree);
			tree=tree->pLeft;

		}
		if(s->pTop ==NULL)
			break;
		if(s->pTop->nValue->pRight==NULL||s->pTop->nValue->pRight==p)
		{
			p=listpop(s);
			printf("%d ",p->value);

		}
		else
			tree =s->pTop->nValue->pRight;
	}
}

相關推薦

C++的前序建立前中後

#include <iostream> using namespace std; struct BiTNode{ char data; struct BiTNode *l

BST叠代器(歸中序)——Binary Search Tree Iterator

tor col 初始化 turn clas return sta style stack 用棧來實現二叉樹的非遞歸中序遍歷 1、棧初始化:從根節點出發一路向左,將一路上的節點push到棧中 2、取next並進行棧的調整:從stack棧頂pop出來的節點即為要取的next

演算法學習之實現結點及其層數的輸出

背景 這半年在準備考研,所以沒有對技術棧進行更新或複習,部落格也沒有更新……但上週學院宣佈畢業設計(企業實習)開題了,要找老師找單位,這才不得不犧牲晚上下軍棋的時間,複習或學習程式設計的知識……   今天記錄一下解決這個問題: 非遞迴實現二叉樹的遍歷,以及輸出每一個結點和其

資料結構六:的先序建樹中序的演算法

         熟悉二叉樹的遍歷建樹過程有利於對後文線索化二叉樹的學習          對於資料結構中二叉樹特殊的結構,經過一段時間的溫習發現自己基礎並不是很牢靠,所以寫下這篇博文也是記錄一下自己

C++實現

基本上所有關於二叉樹的操作都是基於二叉樹的遍歷演算法來實現的,因此在這裡講一下二叉樹的遍歷演算法,其中包括遞迴與非遞迴演算法,在演算法中用輸出節點資料來代替對節點的操作。 首先給出這樣一棵數: 1、前序遍歷 所謂前序遍歷就是先對節點資料進行處理,然後才

遞迴前序遍歷 二叉樹的建立就是遞迴的思想,每個結點都可以看作一個樹。前序遍歷是根->左->右的順序,先列印根結點,分別將根的左右結點遞迴列印 #include <stdio.h> #include<stdlib.h> typedef

-javascript

fun 遞歸 gen ever 一個棧 順序 clas nbsp 先序 1 function TreeNode(val) { // 樹節點構造方式 2 this.val = val; 3 this.left = null; 4

鏈式 先序、中序、後序

參考部落格:click here! 鏈式二叉樹儲存結構: typedef int DataType; typedef struct BiNode { DataType data; struct BiNode *lc, *rc; // 左右子節點指標 int depth; } B

3.1分別用方式實現先序、中序和後序

題目 用遞迴和非遞迴方式,分別按照二叉樹先序、中序和後序列印所有的節點。 首先給出二叉樹節點結構定義: public class BinaryTreeNode { //二叉樹節點 private int data; private Bi

實驗三:的操作(結構轉換,的先序、中序和後序,以及層次,葉子結點和總結點的計數)

(1)將一棵二叉樹的所有結點儲存在一維陣列中,虛結點用#表示,利用二叉樹性質5,建立二叉樹的二叉連結串列。 (2) 寫出對用二叉連結串列儲存的二叉樹進行先序、中序和後序遍歷的遞迴和非遞迴演算法。 (3)寫出對用二叉連結串列儲存的二叉樹進行層次遍歷演算法。 (4)求二叉樹

前序、中序、後序寫法的透徹解析

圖a的程式碼段(ii)也可寫成圖b的理由是:由於是葉子節點,p=-=p->rchild;之後p肯定為空。為空,還需經過新一輪的程式碼段(i)嗎?顯然不需。(因為不滿足迴圈條件)那就直接進入程式碼段(ii)。看!最後還是一樣的吧。還是連續出棧兩次。看到這裡,要仔細想想哦!相信你一定會明白的。

輕鬆理解Java的構建,前序中序層次實現

二叉樹的構建規則:左子樹上的值均不大於右子樹,所以在生成插入的時候,需要以下幾步判斷根節點是否為空,不為空,則直接根節點就是插入節點若根節點不為空,判斷值與根節點大小相比,若大於,則遞迴插入右子樹,節點變為根節點的右子樹,反之則插入左子樹。插入的時候,若是遞迴插入,需要傳入根

方式實現先序、中序、後序

先序遍歷:中、左、右 中序遍歷:左、中、右 後序遍歷:左、右、中 比如下面這科樹              1         2       3    4    5   6    7 packag

先序,中序,後序實現

利用棧實現二叉樹的先序,中序,後序遍歷的非遞迴操作 #include <stdio.h> #include <malloc.h> #include <stdlib.h> #include <queue> #include &l

Python --- 的層序建立三種

隊列 方式 span 等於 不存在 pos 同時 紅色 ret 二叉樹(Binary Tree)時數據結構中一個非常重要的結構,其具有。。。。(此處省略好多字)。。。。等的優良特點。 之前在刷LeetCode的時候把有關樹的題目全部跳過了,(ORZ:我這種連數據結構都不會的

數據結構 歸和歸方式實現先序、中序和後序

nor post 後序遍歷 order else 對象 二叉樹先序 bre print   二叉樹的先序遍歷順序是根、左、右;中序遍歷順序是左、根、右;後序遍歷順序是左、右、根。   遞歸方式實現如下: 1 public class TreeNode { 2

【演算法】前序、中序、後序相互求法(轉)

二叉樹前序、中序、後序遍歷相互求法 原文地址      今天來總結下二叉樹前序、中序、後序遍歷相互求法,即如果知道兩個的遍歷,如何求第三種遍歷方法,比較笨的方法是畫出來二叉樹,然後根據各種遍歷不同的特性來求,也可以程式設計求出,下面我們分別說明。  

PAT-A1020:Tree Traversal(的重建及其中序、後序

題目傳送門:https://pintia.cn/problem-sets/994805342720868352/problems/994805485033603072 目錄 題目解釋: 解題思路: ac程式碼: 題目解釋: 給出一棵二叉樹(binary tree)的後

前序中序後序解法

遞迴解法很簡單,構建一個輔助函式helper,改變一下其中的兩行程式碼的順序便可實現前序中序後序遍歷,程式碼如下: 前序遍歷(遞迴) vector<int> preorderTraversal(TreeNode* root) { vector<in

中葉子結點的個數(的方式實現)

思路: (1)通過先序遍歷的方式求解 (2)葉子節點的特點: 左右孩子都為空 可以用非遞迴的方式 也可以用遞迴方式  package com.zhaochao.tree; import java.util.Stack; /** * Created by z