国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

二叉樹(shù)的非遞歸遍歷算法

這篇具有很好參考價(jià)值的文章主要介紹了二叉樹(shù)的非遞歸遍歷算法。希望對(duì)大家有所幫助。如果存在錯(cuò)誤或未考慮完全的地方,請(qǐng)大家不吝賜教,您也可以點(diǎn)擊"舉報(bào)違法"按鈕提交疑問(wèn)。

二叉樹(shù)的非遞歸遍歷算法

二叉樹(shù)的遍歷是指訪(fǎng)問(wèn)二叉樹(shù)的每個(gè)結(jié)點(diǎn),且每個(gè)結(jié)點(diǎn)僅被訪(fǎng)問(wèn)一次。二叉樹(shù)的遍歷可按二叉樹(shù)的構(gòu)成以及訪(fǎng)問(wèn)結(jié)點(diǎn)的順序分為4種方式:先序遍歷、中序遍歷、后序遍歷和層次遍歷。請(qǐng)至少給出其中一種遍歷方式的非遞歸算法的思路和代碼,并舉例演示算法的執(zhí)行過(guò)程。

先序遍歷

算法思路:采用棧來(lái)實(shí)現(xiàn)先序遍歷的非遞歸算法。創(chuàng)建棧,并初始化。遍歷結(jié)點(diǎn),若結(jié)點(diǎn)存在,則入棧,并輸出結(jié)點(diǎn)的值,指向其左孩子;否則出棧,訪(fǎng)問(wèn)結(jié)點(diǎn),指向其右孩子。如果結(jié)點(diǎn)不存在或者棧為空,則遍歷結(jié)束。

代碼:

//先序遍歷二叉樹(shù)
void PreOrder(BiTree T)
{
	SqStack* S;
	S = InitStack();
	BiTreeNode* p;
	p = T;
	while (p|| !StackEmpty(*S))
	{
		if (p)
		{
			printf("%c",p->data);
			Push(S, p);
			p = p->LChild;
		}
		else
		{
			Pop(S, &p);
			p = p->RChild;
		}
	}
}

演示過(guò)程(以先序遍歷輸入ABD##E##CF###為例)

  1. 根節(jié)點(diǎn)A入棧,并打印該結(jié)點(diǎn)的值,P指向其左孩子
    二叉樹(shù)的非遞歸遍歷算法

此時(shí)輸出:A

  1. 繼續(xù)遍歷結(jié)點(diǎn),此時(shí)B結(jié)點(diǎn)存在并打印該結(jié)點(diǎn)的值,則將該結(jié)點(diǎn)入棧,P指向B結(jié)點(diǎn)的左孩子
    二叉樹(shù)的非遞歸遍歷算法

此時(shí)輸出:AB

  1. 繼續(xù)遍歷結(jié)點(diǎn),此時(shí)D結(jié)點(diǎn)存在并打印該結(jié)點(diǎn)的值,則將該結(jié)點(diǎn)入棧,P指向D結(jié)點(diǎn)的左孩子
    二叉樹(shù)的非遞歸遍歷算法

此時(shí)輸出:ABD

  1. 繼續(xù)遍歷結(jié)點(diǎn),此時(shí)D結(jié)點(diǎn)的左孩子不存在,則將棧頂元素出棧,P指向D結(jié)點(diǎn)的右孩子
    二叉樹(shù)的非遞歸遍歷算法

此時(shí)輸出:ABD(不變)

  1. 繼續(xù)遍歷結(jié)點(diǎn),此時(shí)D結(jié)點(diǎn)的右孩子不存在,則將棧頂元素出棧,P指向B結(jié)點(diǎn)的右孩子
    二叉樹(shù)的非遞歸遍歷算法

此時(shí)輸出:ABD(不變)

  1. 繼續(xù)遍歷結(jié)點(diǎn),此時(shí)E結(jié)點(diǎn)存在并打印該結(jié)點(diǎn)的值,則將該結(jié)點(diǎn)入棧,P指向E結(jié)點(diǎn)的左孩子
    二叉樹(shù)的非遞歸遍歷算法

此時(shí)輸出:ABDE

  1. 繼續(xù)遍歷結(jié)點(diǎn),此時(shí)E結(jié)點(diǎn)的左孩子為空,則將棧頂元素出棧,P指向E結(jié)點(diǎn)的右孩子
    二叉樹(shù)的非遞歸遍歷算法

此時(shí)輸出:ABDE(不變)

  1. 繼續(xù)遍歷結(jié)點(diǎn),此時(shí)E結(jié)點(diǎn)的右孩子為空,則將棧頂元素出棧,P指向A結(jié)點(diǎn)的右孩子
    二叉樹(shù)的非遞歸遍歷算法

此時(shí)輸出:ABDE(不變)

  1. 繼續(xù)遍歷結(jié)點(diǎn),此時(shí)C結(jié)點(diǎn)存在并打印該結(jié)點(diǎn)的值,則將該結(jié)點(diǎn)入棧,P指向C結(jié)點(diǎn)的左孩子
    二叉樹(shù)的非遞歸遍歷算法

此時(shí)輸出:ABDEC

  1. 繼續(xù)遍歷結(jié)點(diǎn),此時(shí)F結(jié)點(diǎn)存在并打印該結(jié)點(diǎn)的值,則將該結(jié)點(diǎn)入棧,P指向F結(jié)點(diǎn)的左孩子
    二叉樹(shù)的非遞歸遍歷算法

此時(shí)輸出:ABDECF

  1. 繼續(xù)遍歷結(jié)點(diǎn),此時(shí)F結(jié)點(diǎn)的左孩子為空,則將棧頂元素F出棧,P指向F結(jié)點(diǎn)的右孩子

此時(shí)F結(jié)點(diǎn)的右孩子也為空,繼續(xù)將棧頂元素C出棧,P指向C結(jié)點(diǎn)的右孩子,此時(shí)P指向的結(jié)點(diǎn)為空,棧也為空,遍歷結(jié)束。

中序遍歷

算法思路:同樣也是用棧,與先序遍歷相同,只是輸出在不同位置。創(chuàng)建棧,并初始化。遍歷結(jié)點(diǎn),若結(jié)點(diǎn)存在,則入棧,指向其左孩子;否則出棧,訪(fǎng)問(wèn)結(jié)點(diǎn),并輸出結(jié)點(diǎn)的值,指向其右孩子。如果結(jié)點(diǎn)不存在或者棧為空,則遍歷結(jié)束

代碼:

//中序遍歷二叉樹(shù)
void InOrder(BiTree T)
{
	SqStack* S;
	S = InitStack();
	BiTreeNode* p;
	p = T;
	while (p || !StackEmpty(*S))
	{
		if (p)
		{
			Push(S, p);
			p = p->LChild;
		}
		else
		{
			Pop(S, &p);
			printf("%c", p->data);
			p = p->RChild;
		}
	}
}

后序遍歷

算法思路:由于后序遍歷是后序遍歷根節(jié)點(diǎn)的左子樹(shù),后序遍歷根節(jié)點(diǎn)的右子樹(shù),最后訪(fǎng)問(wèn)根節(jié)點(diǎn),那么最大問(wèn)題就是判斷是否該結(jié)點(diǎn)結(jié)束遍歷左子樹(shù),所以采取以下操作來(lái)解決。同樣也使用一個(gè)棧,初始化棧,遍歷結(jié)點(diǎn),若結(jié)點(diǎn)存在,結(jié)點(diǎn)入棧,并對(duì)該結(jié)點(diǎn)標(biāo)志位0,表示該結(jié)點(diǎn)尚未被遍歷其左子樹(shù),然后指向其右結(jié)點(diǎn);若結(jié)點(diǎn)不存在,滿(mǎn)足該結(jié)點(diǎn)的左子樹(shù)已被遍歷進(jìn)入循環(huán),遍歷該結(jié)點(diǎn)的右子樹(shù)。不滿(mǎn)足退出循環(huán),然后繼續(xù)出棧得到子結(jié)點(diǎn),并將其壓入棧,指向子節(jié)點(diǎn)的右孩子,并對(duì)該結(jié)點(diǎn)標(biāo)志為1。

代碼:

//后序遍歷
void Postorder(BiTree T)
{
	SqStack* S;
	S = InitStack();
	BiTreeNode* p;
	p = T;
	char tag[Maxsize] = {'0'};
	while (p || !StackEmpty(*S))
	{
		if (p)
		{
			Push(S, p);
			tag[S->top] = '0';//標(biāo)志結(jié)點(diǎn)是否遍歷右子樹(shù)
			p = p->LChild;
		}
		else
		{
			while (tag[S->top] == '1') {
				Pop(S, &p);
				printf("%c",p->data);
			}
			if (S->top == -1) break;
			Pop(S, &p);
			Push(S, p);
			p = p->RChild;
			tag[S->top] = '1';
		}
		

	}
}

層次遍歷

算法思路:采用順序隊(duì)列來(lái)實(shí)現(xiàn),將根節(jié)點(diǎn)入隊(duì),進(jìn)入循環(huán),將隊(duì)頭指針?biāo)傅脑爻鲫?duì),并輸出其結(jié)點(diǎn)的值,如果該結(jié)點(diǎn)的左孩子存在,將其左孩子入隊(duì),如果該結(jié)點(diǎn)的右孩子存在,將右孩子入隊(duì),直到隊(duì)頭指針和隊(duì)尾指針相等退出循環(huán)。

代碼:

//層次遍歷
void Levelorder(BiTree T)
{
	BiTree Q[Maxsize];
	int front, rear;
	if (T == NULL)return;
	front = -1;
	rear = 0;
	Q[rear] = T;
	while (front != rear)
	{
		front++;
		printf("%c",Q[front]->data);
		if (Q[front]->LChild != NULL)
		{
			rear++;
			Q[rear] = Q[front]->LChild;
		}
		if (Q[front]->RChild != NULL)
		{
			rear++;
			Q[rear] = Q[front]->RChild;
		}
	}
}

代碼匯總

//非遞歸先序遍歷、中序遍歷、后序遍歷可用棧來(lái)實(shí)現(xiàn)
//層次遍歷可用隊(duì)列來(lái)實(shí)現(xiàn)
//作者:Second to none
#include<stdio.h>
#include<malloc.h>
#include<stdlib.h>
#include<Windows.h>
#include<math.h>
#define Maxsize 30
typedef char ElemType;
void gotoxy(int x, int y)
{
	COORD c;
	c.X = x - 1;
	c.Y = y - 1;
	SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), c);
}
typedef struct BiTreeNode
{
	ElemType data;
	struct BiTreeNode* LChild, * RChild;
}*BiTree;
typedef struct SqStack
{
	BiTree data[Maxsize];
	int top;
}*Stack;
//創(chuàng)建棧
Stack InitStack()
{
	Stack S;
	S = (Stack)malloc(sizeof(SqStack));
	S->top = -1;
	return S;
}
//棧空
int StackEmpty(SqStack S)
{
	if (S.top == -1)return 1;
	else return 0;
}
//入棧
void Push (Stack S,BiTree p)
{
	S->top++;
	S->data[S->top] = p;
}
//出棧
void Pop(Stack S, BiTree* p)
{
	*p = S->data[S->top];
	S->top--;
}
BiTree CreateBiTree()
{
	char ch;
	BiTree T;
	scanf_s("%c",&ch,1);
	if (ch == '#')T = NULL;
	else {
		T = (BiTree)malloc(sizeof(BiTreeNode));
		T->data = ch;
		T->LChild = CreateBiTree();
		T->RChild = CreateBiTree();
	}
	return T;
}
//先序遍歷二叉樹(shù)
void PreOrder(BiTree T)
{
	SqStack* S;
	S = InitStack();
	BiTreeNode* p;
	p = T;
	while (p|| !StackEmpty(*S))
	{
		if (p)
		{
			printf("%c",p->data);
			Push(S, p);
			p = p->LChild;
		}
		else
		{
			Pop(S, &p);
			p = p->RChild;
		}
	}
}
//中序遍歷二叉樹(shù)
void InOrder(BiTree T)
{
	SqStack* S;
	S = InitStack();
	BiTreeNode* p;
	p = T;
	while (p || !StackEmpty(*S))
	{
		if (p)
		{
			Push(S, p);
			p = p->LChild;
		}
		else
		{
			Pop(S, &p);
			printf("%c", p->data);
			p = p->RChild;
		}
	}
}
//后序遍歷
void Postorder(BiTree T)
{
	SqStack* S;
	S = InitStack();
	BiTreeNode* p;
	p = T;
	char tag[Maxsize] = {'0'};
	while (p || !StackEmpty(*S))
	{
		if (p)
		{
			Push(S, p);
			tag[S->top] = '0';//標(biāo)志結(jié)點(diǎn)是否遍歷右子樹(shù)
			p = p->LChild;
		}
		else
		{
			while (tag[S->top] == '1') {
				Pop(S, &p);
				printf("%c",p->data);
			}
			if (S->top == -1) break;
			Pop(S, &p);
			Push(S, p);
			p = p->RChild;
			tag[S->top] = '1';
		}
		

	}
}
//層次遍歷
void Levelorder(BiTree T)
{
	BiTree Q[Maxsize];
	int front, rear;
	if (T == NULL)return;
	front = -1;
	rear = 0;
	Q[rear] = T;
	while (front != rear)
	{
		front++;
		printf("%c",Q[front]->data);
		if (Q[front]->LChild != NULL)
		{
			rear++;
			Q[rear] = Q[front]->LChild;
		}
		if (Q[front]->RChild != NULL)
		{
			rear++;
			Q[rear] = Q[front]->RChild;
		}
	}
}
int GetHightOfTree(BiTree T)
{
	int rh = 0, lh = 0;
	if (!T)return 0;
	else
	{
		lh = GetHightOfTree(T->LChild);
		rh = GetHightOfTree(T->RChild);
		return(lh > rh ? lh : rh) + 1;
	}
}
void DisplayBinTree(BiTree T, int col, int row, int h)
{
	if (T)
	{
		gotoxy(col, row);
		printf("%c", T->data);
		DisplayBinTree(T->LChild, col - h, row + 1, h / 2);
		DisplayBinTree(T->RChild, col + h, row + 1, h / 2);
	}
}
void DisplayTree(BiTree T)
{
	int k = 0;
	k = GetHightOfTree(T);
	DisplayBinTree(T, (int)pow(2, k - 1) * 2 + 1, 4, (int)pow(2, k - 1));
	printf("\n\n\n");
}
int main()
{
	BiTree T;
	printf("請(qǐng)采用先序遍歷輸入:\n");
	T = CreateBiTree();
	printf("輸出二叉樹(shù)的樹(shù)形結(jié)構(gòu)");
	DisplayTree(T);
	printf("\n先序遍歷輸出\n");
	PreOrder(T);
	printf("\n中序遍歷輸出\n");
	InOrder(T);
	printf("\n后序遍歷輸出\n");
	Postorder(T);
	printf("\n層次遍歷輸出\n");
	Levelorder(T);
	return 1;
}

運(yùn)行截圖

二叉樹(shù)的非遞歸遍歷算法文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-424021.html

到了這里,關(guān)于二叉樹(shù)的非遞歸遍歷算法的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來(lái)自互聯(lián)網(wǎng)用戶(hù)投稿,該文觀點(diǎn)僅代表作者本人,不代表本站立場(chǎng)。本站僅提供信息存儲(chǔ)空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請(qǐng)注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實(shí)不符,請(qǐng)點(diǎn)擊違法舉報(bào)進(jìn)行投訴反饋,一經(jīng)查實(shí),立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費(fèi)用

相關(guān)文章

覺(jué)得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請(qǐng)作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包