二叉树非递归遍历之层次遍历,先序、中序遍历

//LinkBinTree.h

#ifndef _LINKBINTREE_H_
#define _LINKBINTREE_H_

#include 
#include 
#include 


//此处不能使用typedef去"定义"数据的类型,提供一个typedef会传递此数据结构支持多种类型的信息,而创建二叉树节点的函数,却明确指定以固定%x的方式去
//格式化存储输入,这种声明与实现的不一致可能会带来不必要的烦恼
//typedef char Element;         禁止!!!

//二叉树节点类型结构
typedef struct _BinTreeNode
{
    char data;
    struct _BinTreeNode *leftChild;         //左孩子
    struct _BinTreeNode *rightChild;        //右孩子
}BinTreeNode;

//二叉树管理结构,flag参数用于标记空节点,当数据等于flag的值时,节点为空
typedef struct _BinTree
{
    BinTreeNode *root;
    char		 flag;
}BinTree;


//初始化函数,用于初始化二叉树管理变量
void InitBinTree(BinTree *tree, char flag);

//创建函数,以输入字符方式创建
void CreateBinTree_input(BinTree *tree);                            //提供接口的封装函数

//非递归遍历
//层次遍历
void LevelOrder(BinTree tree);

//先、中序遍历非递归实现
void PreOrder(BinTree tree);
void InOrder(BinTree tree);


#endif // _LINKBINTREE_H_




//LinBinTree.c

#include "LinkBinTree.h"
#include "LinkQueue.h"
#include "LinkStack.h"

void InitBinTree(BinTree *tree, char flag)
{
    tree->root = NULL;
    tree->flag = flag;
}

static void Create_1(BinTree *tree, BinTreeNode **node)    //创建方式的先序的
{
    char item;
    if( 1 != scanf("%c", &item) || item == tree->flag ) //如果输入字符与空节点标记值相等,则将节点置NULL并立即返回
    {
        *node = NULL;
         return ;
    }
    //输入值不为标记,创建节点并创建左右孩子
    *node = (BinTreeNode *)malloc(sizeof(BinTreeNode));
    if( NULL == *node )
    {
        *node = NULL;
        return ;
    }
    (*node)->data = item;
    Create_1(tree, &(*node)->leftChild);
    Create_1(tree, &(*node)->rightChild);
}


static BinTreeNode *Create_2(BinTree *tree)
{
    char item;
    if( 1 != scanf("%c", &item) || item == tree->flag )
        return NULL;

    BinTreeNode * p = (BinTreeNode *)malloc(sizeof(BinTreeNode));
    if( NULL == p )
        return NULL;
    p->data = item;
    p->leftChild = Create_2(tree);
    p->rightChild = Create_2(tree);

    return p;
}

void CreateBinTree_input(BinTree *tree)
{
    printf("请输入各节点元素,#表示该节点为空节点\n");
    Create_1(tree, &(tree->root));
    //tree->root = Create_2(tree);
}

//利用队列先入先出的特性对二叉树进行层次遍历
static void LevelOrder_(BinTreeNode *node)
{
    if( NULL == node )
        return ;
    BinTreeNode *e = NULL;
    LinkQueue queue;
    InitQueue(&queue);

    EnQueue(&queue, node);
    while (!IsEmpty(queue))                         //有未被访问节点
    {
        GetTop(queue, &e);
        DeQueue(&queue);                            //保证只被访问一次
        printf("%c", e->data);

        if( NULL != e->leftChild )
            EnQueue(&queue, e->leftChild);          //先入队左孩子确保左孩子先被访问
        if( NULL != e->rightChild )
            EnQueue(&queue, e->rightChild);
    }
}

void LevelOrder(BinTree tree)
{
    LevelOrder_(tree.root);
    printf("\n");
}

//利用栈先入后出的特性对二叉树进行层次遍历
static void PreOrder_(BinTreeNode *node)
{
    if( NULL == node )
        return ;
    BinTreeNode *e = NULL;
    LinkStack stack;
    initStack(&stack);

    push(&stack, node);
    while   (!isEmpty(stack))
    {
        getTop(stack, &e);
        pop(&stack);                        //及时弹出
        printf("%c", e->data);

        if( NULL != e->rightChild )         //先入栈右孩子,以确保左孩子先被访问
            push(&stack, e->rightChild);
        if( NULL != e->leftChild )
            push(&stack, e->leftChild);
    }
}

void PreOrder(BinTree tree)
{
    PreOrder_(tree.root);
     printf("\n");
}

static void InOrder_(BinTreeNode *node)
{
    if( NULL == node )
        return ;
    BinTreeNode *e = NULL, *p = node;
    LinkStack stack;
    initStack(&stack);

    push(&stack, node);
    while (!isEmpty(stack))
    {
        while (NULL != p && NULL != p->leftChild)       //保证左子树先被访问
        {
            push(&stack, p->leftChild);
            p = p->leftChild;
        }
        //已无可入栈左子树,可以访问根节点了
        getTop(stack, &e);
        pop(&stack);
        printf("%c", e->data);
        //当前子树的右子树可能不存在
        if( NULL != e->rightChild )                     //存在则将其右子树入栈,回到while循环保证右子树的所有左子树先被访问
        {
            push(&stack, e->rightChild);
            p = e->rightChild;
        }
    }
}

void InOrder(BinTree tree)
{
    InOrder_(tree.root);
    printf("\n");
}



//main.cpp

#include "LinkBinTree.h"

int main(int argc, char **argv)
{
    //const char *str = "ABC##DE##F##G#H##";
    BinTree tree;
    InitBinTree(&tree, '#');
    CreateBinTree_input(&tree);
    LevelOrder(tree);
    PreOrder(tree);
    InOrder(tree);

    return 0;
}


//LinkQueue.h

#ifndef _LINKQUEUE_H_
#define _LINKQUEUQ_H_

#include 
#include "LinkBinTree.h"

typedef BinTreeNode *ElementType;

typedef struct QueueNode
{
	ElementType data;
	struct QueueNode *next;
}QueueNode;

typedef struct LinkQueue
{
	QueueNode *first;
	int		   size;
	QueueNode *last;
}LinkQueue;

bool InitQueue(LinkQueue *lq);
bool EnQueue(LinkQueue *lq, ElementType e);
bool DeQueue(LinkQueue *lq);
void Show(LinkQueue lq);
bool GetTop(LinkQueue lq, ElementType *e);
int Length(LinkQueue lq);
bool IsEmpty(LinkQueue lq);
void Clear(LinkQueue *lq);
void Destroy(LinkQueue *lq);

#endif //_LINKQUEUE_H_


//LinkQueue
#include "LinkQueue.h"
#include 
#include 

static QueueNode *CreateNode(ElementType e)
{
	QueueNode *p = (QueueNode *)malloc(sizeof(QueueNode));
	if( NULL != p )
	{
		p->next = NULL;
		p->data = e;
	}
    return p;
}

bool InitQueue(LinkQueue *lq)
{
    QueueNode *p = CreateNode(NULL);
	if( NULL == p )
		return false;
	
	lq->first = lq->last = p;
	lq->size = 0;

	return true;
}

bool EnQueue(LinkQueue *lq, ElementType e)
{
	QueueNode *p = CreateNode(e);
	if( NULL == p )
		return false;

	lq->last->next = p;
	lq->last = p;
	lq->size++;

	return true;
}

bool DeQueue(LinkQueue *lq)
{
    if( IsEmpty(*lq) )
	{
		printf("队列为空\n");
		return false;
	}

	QueueNode *p = lq->first->next;
	lq->first->next = p->next;
	if( NULL == p->next )			//p为最后一个节点
	{
		lq->last = lq->first;		//令尾指针指向头结点
	}
	free(p);
	lq->size--;

	return true;
}

void Show(LinkQueue lq)
{
	QueueNode *p = lq.first->next;
	while(NULL != p)
	{
        printf("%p\n", p->data);
		p = p->next;
	}
}

bool GetTop(LinkQueue lq, ElementType *e)
{
	if( NULL == lq.first->next )
	{
		printf("队列为空\n");
		return false;
	}
	*e = lq.first->next->data;
	return true;
}

int Length(LinkQueue lq)
{
	return lq.size;
}

bool IsEmpty(LinkQueue lq)
{
    return lq.first == lq.last;
}

void Clear(LinkQueue *lq)
{
	if( NULL == lq->first->next )
	{
        return ;
	}

	QueueNode *p = lq->first->next;
	while( NULL != p)
	{
		lq->first->next = p->next;
		free(p);
		p = lq->first->next;
	}
	lq->size = 0;
}

void Destroy(LinkQueue *lq)
{
	Clear(lq);
	free(lq->first);
	lq->first = lq->last = NULL;
}




//LinkStack.h
#ifndef _LINKSTACK_H_
#define _LINKSTACK_H_
#include 
#include "LinkBinTree.h"

typedef BinTreeNode *ElementType;
typedef enum
{
	false_,
	true_
}bool_;

typedef struct StackNode
{
	ElementType data;
	struct StackNode *next;
}StackNode;

typedef struct LinkStack
{
	int size;
	StackNode  *Node;
}LinkStack, *pLinkStack;


void initStack(LinkStack *st);
bool_ push(LinkStack *st, ElementType e);
bool_ pop(LinkStack *st);
void show(LinkStack st);
bool_ getTop(LinkStack st, ElementType *e);
bool_ isEmpty(LinkStack st);
int  length(LinkStack st);
void destroy(LinkStack *st);

#endif //_LINKSTACK_H_


//LinkStack.c

#include "LinkStack.h"
#include 


void initStack(LinkStack *st)
{
	st->Node = NULL;
	st->size = 0;
}

bool_ push(LinkStack *st, ElementType e)
{
	StackNode *node = (StackNode *)malloc(sizeof(StackNode));
	if( NULL == node )
	{
		printf("申请节点失败\n");
		return false_;
	}

	node->data = e;
	node->next = NULL;

	node->next = st->Node;
	st->Node = node;
	st->size++;

	return true_;
}

bool_ pop(LinkStack *st)
{
	if( isEmpty(*st))
	{
		printf("栈已空\n");
		return false_;
	}

	StackNode *p = st->Node;
	st->Node = p->next;
	free(p);
	st->size--;

	return true_;
}

void show(LinkStack st)
{
	StackNode *p = st.Node;
	while (NULL != p)
	{
		printf("%d\n", p->data);
		p = p->next;
	}
}

bool_ getTop(LinkStack st, ElementType *e)
{
	if( isEmpty(st) )
	{
		printf("栈已空\n");
		return false_;
	}

	*e = st.Node->data;

	return true_;
}


bool_ isEmpty(LinkStack st)
{
	return NULL == st.Node;
}

int  length(LinkStack st)
{
	return st.size;
}


void destroy(LinkStack *st)
{
	if( NULL == st->Node )		
		return ;

	StackNode *p = st->Node;
	while(NULL != p)
	{
		st->Node = p->next;
		free(p);
		p = st->Node;
	}
	st->size = 0;
}


所使用到的队列和栈都是之前实现的


你可能感兴趣的:(数据结构与算法)