1. 程式人生 > >非遞迴前序遍歷(非遞迴、非棧)

非遞迴前序遍歷(非遞迴、非棧)

前幾天面試吃了一次癟,筆試題讓我非遞迴前序遍歷,我毫不猶豫的就寫了一個棧。然後利用壓棧將前驅遍歷迅速寫了出來,當時喜滋滋的尋思今天的又比較順利哈!

面試的時候,考官問我,能不能不用棧,不遞迴實現呢?我頓時呆了... ... 從來都沒有思考過這個問題!直接影響了我後面的答題!

回來後翻閱資料,其實一顆線索二叉樹很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

#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
BiTree.cpp
#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中就比較簡陋的測試!望海涵!

測試結果: