樹(2)--二叉樹的遍歷(非遞迴)+線索二叉樹
一:二叉樹的遍歷.
由於遞迴演算法很簡單,在這裡就不例舉了,主要看一下非遞迴演算法(其實也就是用棧實現,因為遞迴本身就是一種棧)
1.先序遍歷:
思想:(1)從根節點依次遍歷當前節點的左子樹,邊遍歷訪問,並且壓入棧
(2).再訪問當前棧頂結點的右子樹,然後再返回到(1)執行,直至棧空
#define maxsize 100
typedef struct
{
Bitree Elem[maxsize];
int base,top;
}SqStack;
void PreOrderUnrec(Bitree t)
{
SqStack s;
StackInit(s);
p=t;
while (p!=null || !StackEmpty(s))
{
while (p!=null) //遍歷左子樹
{
visite(p->data);
push(s,p);
p=p->lchild;
}//endwhile
if (!StackEmpty(s)) //通過下一次迴圈中的內嵌while實現右子樹遍歷
{
p=pop(s);
p=p->rchild;
}//endif
}//endwhile
}//PreOrderUnrec
2.中序遍歷:
思想:(1)從根節點遍歷左子樹,邊遍歷邊入棧
(2)彈出棧頂元素,並訪問,然後訪問當前棧頂的右子樹,回到(1)
#define maxsize 100
typedef struct
{
Bitree Elem[maxsize];
int base,top;
}SqStack;
void InOrderUnrec(Bitree t)
{
SqStack s;
StackInit(s);
p=t;
while (p!=null || !StackEmpty(s))
{
while (p!=null) //遍歷左子樹
{
push(s,p);
p=p->lchild;
}//endwhile
if (!StackEmpty(s))
{
p=pop(s);
visite(p->data); //訪問根結點
p=p->rchild; //通過下一次迴圈實現右子樹遍歷
}//endif
}//endwhile
}//InOrderUnrec
3.後序遍歷
在後序遍歷中,要保證左孩子和右孩子都已被訪問並且左孩子在右孩子前訪問才能訪問根結點。對於任一結點P,將其入棧,然後沿其左子樹一直往下搜尋,直到搜尋到沒有左孩子的結點,此時該結點出現在棧頂,但是此時不能將其出棧並訪問,因此其右孩子還為被訪問。所以接下來按照相同的規則對其右子樹進行相同的處理,當訪問完其右孩子時,該結點又出現在棧頂,此時可以將其出棧並訪問。這樣就保證了正確的訪問順序。可以看出,在這個過程中,每個結點都兩次出現在棧頂,只有在第二次出現在棧頂時,才能訪問它。因此需要多設定一個變數標識該結點是否是第一次出現在棧頂
while(p!=NULL||!s.empty())
{
while(p!=NULL) //沿左子樹一直往下搜尋,直至出現沒有左子樹的結點
{
BTNode *btn=(BTNode *)malloc(sizeof(BTNode));
btn->btnode=p;
btn->isFirst=true;
s.push(btn);
p=p->lchild;
}
if(!s.empty())
{
temp=s.top();
s.pop();
if(temp->isFirst==true) //表示是第一次出現在棧頂
{
temp->isFirst=false;
s.push(temp);
p=temp->btnode->rchild;
}
else //第二次出現在棧頂
{
cout<<temp->btnode->data<<" ";
p=NULL;
}
}
}
二.線索二叉樹:
含有n個結點的二叉樹,一共有2n個指標域,有n+1個處於Null狀態,為了使空間不浪費,可以讓這些空的指標域指向二叉樹各種遍歷的前驅或後繼結點,這樣又可以方便查詢每一個元素,而不必採用遍歷,節省了時間
1.儲存結構:
typedef enum { Link, Thread } PointerThr;
// Link==0:指標,Thread==1:線索
typedef struct BiThrNode{
TElemType data;
Struct BiThrNode *lchild, *rchild; // 左右孩子指標
PointerThr LTag, RTag; // 左右標誌,當LTag=Thread時,表示線索,為Link時表示指向下一結點
} BiThrNode, *BiThrTree;
1)若結點有左子樹,則lchild指向其左孩子;
否則, lchild指向其直接前驅(即線索);
2).若結點有右子樹,則rchild指向其右孩子;
否則,rchild指向其後繼(即線索);
例:
2.線索二叉樹的中序遍歷演算法:
Status IOTraver_T( BiThrTree T,Status (*Visit)(TElemType e) )
{ //T指向頭結點,頭結點的左鏈lchild指向根結點,中序遍歷 //二叉線索樹T的非遞迴演算法,對每個資料元素呼叫函式Visit。
p = T->lchild; //p指向根結點
while (p != T) { //空樹或遍歷結束時,p = = T
while (p->LTag==Link) p = p->lchild;
if (!Visit(p->data)) return ERROR; //訪問其左子樹為空的結點
while (p->RTag==Thread && p->rchild!=T)
{ p = p->rchild; Visit(p->data); } //訪問後繼結點
p = p->rchild;
}
return OK;
} // IOTraver_T
3.線索二叉樹的生成演算法:
void InThreading (BiThrTree p)//中序併線索化
{
if (p)
{
InThreading( p->lchild ); // 左子樹線索化
if ( !p->lchild )
{ p->LTag=Thread; p->lchild=pre; } // 前驅線索
if ( !pre->rchild )
{ pre->RTag=Thread; pre->rchild=p; } //後繼線索
pre = p; // 保持pre指向p的前驅
InThreading(p->rchild); //右子樹線索化
}
} // InThreading
Status InorderThreading(BiThrTree & Thrt, BiThrTree T)
{ //中序遍歷二叉樹T,並將其中序線索化, Thrt 指向頭結點.
if ( ! (Thrt = (BiThrTree) malloc ( sizeof (BiThrnode) ) ) exit ( OVERFLOW ) ;
Thrt ->LTag = Link; Thrt ->RTag = Thead; // 建頭結點
Thrt ->rchild = Thrt ; //右指標回指
if ( !T ) Thrt ->lchild = Thrt ; // 若二叉樹空,則左指標回指
else {
Thrt ->lchild = T; pre = Thrt; //將頭結點與樹相連
<strong>InThreading(T); </strong> // 中序遍歷進行中序線索化,呼叫上面的函式
pre ->rchild = Thrt;
pre ->RTag = Thread; //最後一個結點線索化
Thrt ->rchild = pre;
}
return OK;
} // InOrderThreading
相關文章
- 遍歷二叉樹-------遞迴&非遞迴二叉樹遞迴
- 樹3-二叉樹非遞迴遍歷(棧)二叉樹遞迴
- 什麼是遍歷二叉樹,JavaScript實現二叉樹的遍歷(遞迴,非遞迴)二叉樹JavaScript遞迴
- 非遞迴先序遍歷二叉樹遞迴二叉樹
- 二叉樹的非遞迴遍歷寫法二叉樹遞迴
- 二叉樹的四種遍歷(遞迴與非遞迴)二叉樹遞迴
- 二叉樹的所有遍歷非遞迴實現二叉樹遞迴
- 遍歷二叉樹的遞迴與非遞迴程式碼實現二叉樹遞迴
- 二叉樹建立後,如何使用遞迴和棧遍歷二叉樹?二叉樹遞迴
- 二叉樹的前中後序遍歷(遞迴和非遞迴版本)二叉樹遞迴
- 二叉樹——後序遍歷的遞迴與非遞迴演算法二叉樹遞迴演算法
- Day14 | 二叉樹遞迴遍歷二叉樹遞迴
- 遍歷二叉樹的迭代和遞迴方法二叉樹遞迴
- 二叉樹的遍歷 → 不用遞迴,還能遍歷嗎二叉樹遞迴
- 迴圈遍歷二叉樹二叉樹
- 線索二叉樹的構造和遍歷二叉樹
- python實現二叉樹及其七種遍歷方式(遞迴+非遞迴)Python二叉樹遞迴
- 二叉樹的建立與遍歷(遞迴實現)二叉樹遞迴
- 中序線索二叉樹的建立與遍歷二叉樹
- 線索二叉樹【定義、應用、線索化、遍歷】二叉樹
- C++樹——遍歷二叉樹C++二叉樹
- 玩轉二叉樹(樹的遍歷)二叉樹
- 二叉樹遍歷二叉樹
- 二叉樹---遍歷二叉樹
- 刷題系列 - Python用非遞迴實現二叉樹前序遍歷Python遞迴二叉樹
- 二叉樹的遍歷二叉樹
- 【LeetCode-二叉樹】二叉樹前序遍歷LeetCode二叉樹
- 中序線索二叉樹的構造和遍歷二叉樹
- 144.二叉樹的前序遍歷145.二叉樹的後序遍歷 94.二叉樹的中序遍歷二叉樹
- 刷題系列 - Python用非遞迴實現二叉樹後續遍歷Python遞迴二叉樹
- 刷題系列 - Python用非遞迴實現二叉樹中序遍歷Python遞迴二叉樹
- 【C++】翻轉二叉樹(遞迴、非遞迴)C++二叉樹遞迴
- 二叉樹(順序儲存二叉樹,線索化二叉樹)二叉樹
- 二叉樹遍歷方法二叉樹
- 二叉樹遍歷 -- JAVA二叉樹Java
- 完全二叉樹的遍歷二叉樹
- 根據二叉樹的前序遍歷和中序遍歷輸出二叉樹;二叉樹
- 二叉樹的遞迴套路二叉樹遞迴
- 13、線索二叉樹二叉樹