二叉樹中序遍歷非遞歸演算法
A. 如何理解二叉樹中序遍歷的非遞歸演算法
#define MAXNODE 100 //二叉樹最大節點數
//定義二叉樹鏈式結構
typedef struct BitNode
{
char data; //數據域
struct BitNode *lchild,*rchild;//左右指針域
}BitNode,*BiTree;
//二叉樹進行中序非遞歸遍歷
void NRInorder(BiTree t)
{
BiTree s; //s-指向當前節點
BiTree stack[MAXNODE]; //定義棧
int top=-1; //初始化棧頂指針
if(t==NULL)
return;
stack[++top]=t;//根指針入棧
s=t->lchild; //s指向左子樹
while(s!=NULL||top!=-1)//當存在節點(涉及到根下右子樹)或者棧不為空,進行遍歷
{
while(s!=NULL) //如果存在節點,尋找最左子樹並入棧
{
if(top>=MAXNODE-1)
{
printf("棧為滿\n");
return;
}
stack[++top]=s;//當前節點入棧
s=s->lchild; //左子樹進行遍歷
}
if(top==-1)
{
printf("棧為空\n");
return;
}
s=stack[top--]; //彈出棧頂元素到s中
printf("%c ",s->data); //輸出當前節點元素值
s=s->rchild; //遍歷右子樹
}
}
B. 二叉樹中序非遞歸遍歷演算法
對的,實際上如果p=0,是往左探索到頭的意思。先要往左探索到頭,只有到頭了之後才退棧,看右子樹。
探索的過程一直是p=p->lchild,如果p左邊沒有節點了,p->lchild=nullptr了,就說明到頭了,開始執行if的第二個分支:
pop(s,p)實際上是恢復了p上一個狀態,也就是那個葉子節點;
visit(p),中序訪問就是每pop一個緊接著就訪問一個就是了;
p=p->rchild,訪問右邊,當然,如果右邊還沒有,下次pop的就是p的上上個狀態了,這相當於是從一個葉子節點離開。以此類推。
不明白的可以繼續問。
中序
C. 非遞歸中序遍歷二叉樹
//以前曾寫過,僅供參考,因為這是截取部分源碼,
#include "afx.h"
#include "stdio.h"
#include"iostream.h"
#include "iomanip.h"
#include<malloc.h>
#include<conio.h>
typedef char ElemType; //定義二叉樹結點值的類型為字元型
const int MaxLength=100; //結點個數不超過50個
typedef struct BTNode{
ElemType data;
struct BTNode *lchild,*rchild;
}BTNode,* BiTree;
void PreCreateBiTree(BiTree &T) //按先序次序輸入,構造二叉樹
{
char ch;
ch=getchar(); //不能用cin來輸入,在cin中不能識別空格。
if(ch==' ') T=NULL;
else{
if(!(T=(BTNode *)malloc(sizeof(BTNode)))) cout<<"malloc fail!";
T->data=ch;
PreCreateBiTree(T->lchild);
PreCreateBiTree(T->rchild);
}
}
void NRInOrder(BiTree bt) //非遞歸的中序遍歷演算法
{
BiTree stack[MaxLength],p;
int top;
if (bt!=NULL)
{
top=0;
p=bt;
while(p!=NULL||top>0)
{
while(p!=NULL)
{
stack[top]=p;
top++;
p=p->lchild;
}
if (top>0)
{
top--;
p=stack[top];
cout<<p->data<<" ";
p=p->rchild;
}
}
}
}
D. 先序遍歷二叉樹的非遞歸演算法
InitStack(S);//初始化棧
p=T;//取棧頂
while(P||!StackEmpty(S)){ //P存在或者棧非空
if(p) { //p非空,即左子樹或者右子樹存在
Push(S,p); //將左子樹入棧
p=p->lchild; //取下一個左子樹
}
else{
Pop(S,p); //出棧,相當於先序遍歷了,因為左子樹都TMD入棧了,現在反向輸出
p=p->rchild; //彈出一個左子樹,就同時取其右子樹右子樹,然後又跳到這個if的最開頭那裡,p存在的那個分支。接下來再取右子樹的左子樹
}
}
//其實,用遞歸也許你更能理解一些。但是,遞歸本質上也是壓棧,只不過是程序壓棧,還不如這個效率高
E. 二叉樹後序遍歷非遞歸演算法程序跪求解釋
一,大循環中的第一個循環,當前節點一直往左走一直走到頭,並且把走過的節點壓棧,這個循環遍歷完成後,棧裡面都是左邊走過但是右邊還沒有走過的節點
二,從最左邊那個沒有更左的那個節點,它位於棧頂,因為這時棧頂不是一個右節點,第二個循環跳過,然後把棧頂結點的右節點標記為r並以此作為根節點重復之前的操作
回溯:
因為一直往下層走,總會遇到既沒有左節點有沒有右節點的節點,就是葉子節點,就開始往回退 取他的右節點,取之前會把該節點標記為r,但是他沒有右節點,為null,就會跳過第一個循環,來到第二個,那麼這個葉子就從棧中pop掉,新的棧頂結點是那個葉子的父節點,如果沒有右節點,那他就成了葉子,更簡單,如果有右節點,那麼繼續二
一步一步推就是這樣子,需要考慮所有情況,會把問題想復雜,但是利用遞歸的思想就好想了
參考遞歸演算法
void preOrder2(BinTree *root)
{
preOrder(root->lchild);
preOrder(root->rchild);
}
第一個函數就是第一個小循環,只走左邊,然後把新得到的節點作為根節點,繼續調用第一個函數,得到左節點,然後再作為根節點,直到左節點為空;
第二個函數就是最後一個if,非遞歸演算法中是從棧頂取,就是左邊走過了的節點,相當於遞歸中,第一個函數執行完已經返回,然後取他的右節點作為根節點,繼續遞歸
F. 二叉樹的非遞歸中序遍歷演算法 要有結果輸出 跪求了 謝謝
太懶了,就不告訴你
G. 數據結構的中序遍歷二叉樹的結點的非遞歸演算法
如圖
H. 關於《中序遍歷二叉樹的非遞歸演算法》的論文
實用《數據結構》編程——二叉樹的建立、中序遍歷非遞歸C程序 宋麗敏 <正>近年來,伴隨著計算機應用技術的快速發展,系統程序和應用程序的規模越來越大,應用領域越來越廣泛.計算機的應用已不再局限於科學計算,而更多地應用於控制、管理及數據處理等非數值計算的處理工作.需要通過計算機加工、處理的數據對象也日益復雜化.《數據結構》課程就是一門以這些復雜的非數值型數據為研究對象,研【作者單位】:河北省廊坊職業技術學院(西校區) 065000【分類號】:G634.6【DOI】:cnki:ISSN:1005-9741.0.2004-02-009【正文快照】:近年來,伴隨著計算機應用技術的快速發展,系統程序和應用程序的規模越來越大,應用領域越來越廣泛.計算機的應用已不再局限於科學計算,而更多地應用於控制、管理及數據處理等非數值計算的處理工作.需要通過計算機加工、處理的數據對象也日益復雜化.《數據結構》課程就是一門以這 …… http://www.cnki.com.cn/Article/CJFDTotal-LKJX200402009.htm