数据结构复习代码——非递归实现二叉树的遍历方法

1、非递归实现二叉树的遍历方法

  1、非递归----后序遍历

#include<stdio.h>
#include<assert.h>
#include<malloc.h>

#include"PostStack.h"
#define ElemType char

typedef struct BinTreeNode
{
    ElemType data;
    struct BinTreeNode *leftchild;
    struct BinTreeNode *rightchild;
}BinTreeNode;

typedef struct BinTree
{
    BinTreeNode *root;
    ElemType    refvalue;
}BinTree;
//初始化
void InitBinTree(BinTree *bt,ElemType ref);

//创建二叉树----非输入方式   创建方式可自行选择
void CreateBinTree_4(BinTree *bt,char *str);
void CreateBinTree_4(BinTree *bt,BinTreeNode *&t,char *&str);

//后续遍历
void postOrder_1(BinTree *bt);
void postOrder_1(BinTreeNode *t);

////////////////////////////////////////////////////////////
void InitBinTree(BinTree *bt,ElemType ref)
{
    bt->root = NULL;
    bt->refvalue = ref;
}

void CreateBinTree_4(BinTree *bt,char *str)
{
    CreateBinTree_4(bt,bt->root,str);
}
void CreateBinTree_4(BinTree *bt,BinTreeNode *&t,char *&str)
{
    if(*str == bt->refvalue)
        t = NULL;
    else
    {
        t = (BinTreeNode*)malloc(sizeof(BinTreeNode));
        assert(t != NULL);
        t->data = *str;
        CreateBinTree_4(bt,t->leftchild,++str);
        CreateBinTree_4(bt,t->rightchild,++str);
    }
}
//非递归---后序遍历二叉树
void postOrder_1(BinTree *bt)
{
    postOrder_1(bt->root);
}
void postOrder_1(BinTreeNode *t)
{
    if(t != NULL)
    {
        SeqStack st;
        InitStack(&st);
        StkNode sn;
        BinTreeNode *p;
        do{
            while(t!=NULL)
            {
                sn.ptr = t;
                sn.tag = L;
                Push(&st,sn);
                t = t->leftchild;
            }
            bool flag = true;
            while(flag && !IsEmpty(&st))
            {
                //sn = GetElem(&st);
                GetElem(&st,sn);
                Pop(&st);
                p = sn.ptr;
                switch(sn.tag)
                {
                case L:
                    sn.tag = R;
                    Push(&st,sn);
                    flag = false;
                    t = p->rightchild;
                    break;
                case R:
                    printf("%c ",p->data);
                    break;
                }

            }
        }while(!IsEmpty(&st));
    }
}

int main()
{
    char *str = "ABC##DE##F##G#H##";
    BinTree mytree;
    InitBinTree(&mytree,'#');
    //CreateBinTree_3(&mytree);
    CreateBinTree_4(&mytree,str);

    postOrder_1(&mytree);
    printf("\n");

    return  0;
}

  引用的PostStack.h头文件

#include<stdio.h>
#include<malloc.h>
#include<assert.h>
#include<stdlib.h>

struct BinTreeNode;

typedef enum{L,R}Tag;

typedef struct StkNode
{
    BinTreeNode *ptr;
    Tag         tag;
}StkNode;


#define ETStack StkNode

#define STACK_INIT_SIZE 8
#define STACK_INC_SIZE 3


typedef struct SeqStack
{
    ETStack *base;     //每个节点的数据域
    int capacity;       //当前栈容量
    int top;            //栈顶指针
}SeqStack;

//初始化栈
void InitStack(SeqStack *s)
{
    s->base = (ETStack*)malloc(sizeof(ETStack)*STACK_INIT_SIZE);  //为栈分配内存空间并赋值给首址
    assert(s->base != NULL);        //判断内存空间是否分配成功
    s->capacity = STACK_INIT_SIZE;  //栈最大空间初始化赋值给最大容量
    s->top = 0;                     //栈顶指针赋值,指向0
}
//辅助函数--判空操作
int IsEmpty(SeqStack *s)
{
    if(s->top == 0)
    {
        return 1;
    }else{
        return 0;
    }
}
//辅助函数--判满操作
int IsFull(SeqStack *s)
{
    if(s->top == s->capacity)
    {
        return 1;
    }else{
        return 0;
    }
}
//辅助函数--遍历栈
void Show(SeqStack *s)
{
    for(int i=s->top-1;i>=0;i--)
    {
        printf("%d \n",s->base[i]);
    }
}
//辅助函数--获取栈顶元素
/*
ETStack GetElem(SeqStack *s)
{
    if(IsEmpty(s)){
        printf("该栈已空!!");
        //return 0;
    }
    int i = s->top;
    ETStack e = s->base[i-1];
    return e;
}
*/
int GetElem(SeqStack *s,ETStack &e)
{
    if(IsEmpty(s)){
        printf("该栈已空!!");
        //return 0;
    }
    int i = s->top;
    e = s->base[i-1];
    return 1;
}
//辅助函数--获取当前栈的长度
int Length(SeqStack *s){
    //由于该栈定义时,栈顶指针是从0开始的,即当前栈的长度为栈顶指针所指
    return s->top;
}
//辅助操作--增加栈内存空间
int Inc(SeqStack *s)
{
    //使用realloc函数为s->base分配新的内存空间
    ETStack *newbase = (ETStack*)realloc(s->base,sizeof(ETStack)*(s->capacity+STACK_INC_SIZE));
    //此磁盘中已无内存空间可分配给次栈
    if(newbase == NULL)
    {
        printf("内存空间已满!无法再次申请空间!");
        return 0;
    }
    //将新分配的内存空间首址赋值给栈
    s->base = newbase;
    //扩大该栈的最大容量
    s->capacity += STACK_INC_SIZE;
    return 1;
}
//入栈操作
void Push(SeqStack *s,ETStack e)
{
    if(IsFull(s)&& !Inc(s))
    {
        printf("栈空间已满,不能入栈!!");
        return;
    }
    s->base[s->top] = e;
    s->top++;
}

//出栈操作
void Pop(SeqStack *s)
{
    if(IsEmpty(s)){
        printf("栈已空,无元素可出栈!!");
        return;
    }
    --s->top;
    //printf("出栈元素为:%d \n",s->base[s->top]);
}
//清除栈操作
void Clear(SeqStack *s)
{
    //关于清除栈操作,只需将栈顶指针归零即可
    //因为该栈内的相关元素已无实用价值,可以任意改变
    s->top = 0;
}
//摧毁栈操作
void Destroy(SeqStack *s)
{
    //摧毁栈,需要释放已分配该栈的内存空间
    free(s->base);
    s->base=NULL;
    s->capacity = s->top = 0;
}

  2、前序和中序

//非递归----前序遍历
//本部分代码与上篇博客二叉树的定义以及相关实现相匹配(请勿与本篇代码融合运行)
void preOrder_1(BinTree *bt)
{
    preOrder_1(bt->root);
}
void preOrder_1(BinTreeNode *t)
{
    if(t != NULL)
    {
        SeqStack st;
        InitStack(&st);
        BinTreeNode *p;
        Push(&st,t);
        while(!IsEmpty(&st))
        {
            p = GetElem(&st);
            Pop(&st);
            printf("%c ",p->data);
            if(p->rightchild != NULL)
                Push(&st,p->rightchild);
            if(p->leftchild != NULL)
                Push(&st,p->leftchild);
        }
    }
}

void inOrder_1(BinTree *bt)
{
    inOrder_1(bt->root);
}
void inOrder_1(BinTreeNode *t)
{
    if(t != NULL)
    {
        SeqStack st;
        InitStack(&st);
        BinTreeNode *p;
        Push(&st,t);
        while(!IsEmpty(&st))
        {
            while(t != NULL && t->leftchild != NULL)
            {
                Push(&st,t->leftchild);
                t = t->leftchild;
            }
            p = GetElem(&st);
            Pop(&st);
            printf("%c " ,p->data);

            if(p->rightchild != NULL)
            {
                t = p->rightchild;
                if(t != NULL)
                    Push(&st,t);
            }

        }
    }
}

 

posted @ 2022-07-06 20:14  往心。  阅读(54)  评论(0编辑  收藏  举报