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

来源:互联网 发布:河北工龄工资算法 编辑:程序博客网 时间:2024/05/17 06:56

//LinkBinTree.h

#ifndef _LINKBINTREE_H_#define _LINKBINTREE_H_#include <stdio.h>#include <stdbool.h>#include <stdlib.h>//此处不能使用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 <stdbool.h>#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 <stdio.h>#include <stdlib.h>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 <stdio.h>#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 <stdlib.h>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;}


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


0 0
原创粉丝点击