非遞迴前序遍歷(非遞迴、非棧)
阿新 • • 發佈:2019-02-13
前幾天面試吃了一次癟,筆試題讓我非遞迴前序遍歷,我毫不猶豫的就寫了一個棧。然後利用壓棧將前驅遍歷迅速寫了出來,當時喜滋滋的尋思今天的又比較順利哈!
面試的時候,考官問我,能不能不用棧,不遞迴實現呢?我頓時呆了... ... 從來都沒有思考過這個問題!直接影響了我後面的答題!
回來後翻閱資料,其實一顆線索二叉樹很easy的解決了這個問題!這也說明了我對資料結構知識理解的不夠深刻,沒辦法把實際問題與資料結構相結合!
那麼今天就再預習一下線索樹吧!
本文章文字是比較少的,線索化過程各種各樣的資料結構書中都做了極為詳細的解釋,我的程式碼風格是模仿了Mark Allen的《資料結構與演算法分析》中的風格!
這本書沒有講過線索二叉樹的!
根據另一本書《資料結構》嚴老師版本里學習的線索化加上Mark的程式碼風格,就形成了本文,故以原創姿態發表不應該算是抄襲吧!
這個風格的程式碼易讀性非常好,雖然我沒有加一句註釋,有基礎的人看這些程式碼應該沒有任何問題。
config.h:
#ifndef _CONFIG_H_
#define _CONFIG_H_
#include<stdio.h>
#include<stdlib.h>
#define OK 0
#define ERROR -1
#define TRUE 1
#define FALSE 0
#endif
BiTree.h
BiTree.cpp#ifndef _BITREE_H_ #define _BITREE_H_ #include "config.h" typedef enum{Link,Thread}PointerTag; typedef int ElemType; typedef int Status; typedef struct Node { ElemType data; struct Node * lchild; struct Node * rchild; PointerTag lTag; PointerTag rTag; }BiThrNode,*BiThrTree; Status visit(BiThrTree T); BiThrTree Insert(BiThrTree T,ElemType e); void PreThreading(BiThrTree T); void PreOrderThreading(BiThrTree T,BiThrTree &H); void PreOrderTraverse(BiThrTree H); #endif
#include"BiTree.h"
Status visit(BiThrTree T)
{
if(T == NULL)
{
return FALSE;
}
printf("%d ",T->data);
return OK;
}
BiThrTree Insert(BiThrTree T,ElemType e)
{
if(T == NULL)
{
T = (BiThrTree)malloc(sizeof(BiThrNode));
if(T == NULL)
{
exit(ERROR);
}
T->lchild = NULL;
T->rchild = NULL;
T->lTag = Link;
T->rTag = Link;
T->data = e;
}
else
{
if (e<T->data)
{
T->lchild = Insert(T->lchild,e);
}
else
{
T->rchild = Insert(T->rchild,e);
}
}
return T;
}
BiThrTree Pre;
void PreThreading(BiThrTree T)
{
if (T == NULL)
{
return;
}
if(T->lchild == NULL)
{
T->lTag = Thread;
T->lchild = Pre;
}
if (Pre->rchild == NULL)
{
Pre->rTag = Thread;
Pre->rchild = T;
}
Pre = T;
if (T->lTag == Link)
{
PreThreading(T->lchild);
}
if(T->rTag == Link)
{
PreThreading(T->rchild);
}
}
void PreOrderThreading(BiThrTree T,BiThrTree &H)
{
H = (BiThrTree)malloc(sizeof(BiThrNode));
if(H == NULL)
{
exit(FALSE);
}
H->rchild = H;
H->rTag = Link;
if(T == NULL)
{
H->lchild = H;
H->lTag = Link;
}
else
{
Pre = H;
H->lchild = T;
H->lTag = Link;
PreThreading(T);
Pre->rchild = H;
Pre->rTag = Link;
H->rchild = Pre;
}
}
void PreOrderTraverse(BiThrTree H)
{
if(H->lchild != H)
{
BiThrTree T = H->lchild;
while(T != H)
{
visit(T);
if (T->lTag == Link)
{
T = T->lchild;
}
else
{
T = T->rchild;
}
}
}
}
main中測試,原本我將這顆線索樹平衡化!但是由於程式碼量大,本文的主旨是線索化,main中就比較簡陋的測試!望海涵!
測試結果: