二叉树的非递归前序遍历

二叉树的遍历有递归和非递归两种,递归的已经写过,就写了一下非递归的前序遍历。中序和后续整好了一起贴另一篇。

二叉树遍历,节点位置一会移动了几次一会又回来了,进进出出,所以用栈比较适合。(我瞎说的,因为我看它们都是用栈,就用栈了,咳咳)

话说,我C++倒是学过,但是很少用C++编,因为学得不好,C++细节太多了,也记不住。所以我用的c,但是呢,C标准自己也没看过,偶尔就编到C++的范围了(传参有时候不想用指针,就引用传递),所以这个代码需要g++编译,大家别喷我。

栈的思路是 本身自己创建一块区域,装出入栈的东西。我因为本来想做一个结构体,里面加上函数指针,将进出栈等需要的函数赋值给函数指针,但是这个函数又要涉及到传参,我脑袋乱七八糟,嫌弃麻烦,如果这样其实用C++就封装函数了,何必用C。所以就定义了几个外部函数。push pop empty 。我发现写代码大脑对整个代码的结构要比较清楚,几个模块什么的,先从总览上有点规划。(又在吹牛逼了,别全信)

前序遍历 先根节点进栈;然后出,然后以刚出来这个点为当前点,进右(右不空),进左(不空)(这样出的时候就是先出左后出右);出;然后以刚出来这个点为当前点,进右,进左;如果当前左右空了,继续出,节点就回去了。可以自己在纸上画一下。

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

// the struct of tree node
typedef struct node
{
    int value;
    struct node *left,*right;
}tree;

//the struct of stack
typedef struct sstack
{
    int num;
    tree *data[10];
    // tree *curr;
}stack;

int init(stack &s)
{
    s.num=0;
    return 0;
}

//push a tree node into stack s
void push(stack &s,tree *p)
{
    s.data[s.num]=p;
    s.num++;
}

//pop a element of stack
tree *pop(stack &s)
{
    s.num--;
    printf("%d\n",s.data[s.num]->value);
    //return the pointer of the  one to pop.for save its pointer without change root
    return s.data[s.num];
}

//stack is empty or not
int empty(stack &s)
{
    if (s.num)
        return 0;
    else 
        return 1;
}

//创建二元查找树 有返回值的可以不传参 没有的话如何传参
tree *creat()
{
    int ch;
    tree *p=NULL;

    printf("input a num\n");
    scanf("%d",&ch);
    if(ch!=0)
    {
        p=(tree *)malloc(sizeof(tree));
        p->value=ch;
        printf("      %d left child\n",ch);
        p->left=creat();
        printf("      %d right child\n",ch);
        p->right=creat();
    }
    return p;
}

//non recursion travel . by stack
void preorder(stack &s,tree *p)
{

    if(p==NULL)
        return;
    printf("no_recursion preorder\n"); 
    push(s,p);// push root node 
    while(!empty(s))//if zhan fei kong
    {
        p=pop(s);//chu zhan
        if(p->right)//his left right child push into stack 
            push(s,p->right);
        if(p->left)
            push(s,p->left);
    }
}

int main(int argc, char const *argv[])
{
    tree *root=creat();
    stack bs;
    init(bs);
    preorder(bs,root);
    return 0;
}




我用的g++编译
g++ shu.c -o shu
不过因为今天刚看了gdb,为了调试当时用的
g++ -ggdb3 shu.c -o shu
进入调试用 gdb shu
然后可以设置断点 运行 单步啊 看变量啊

ok不写了,用了好多年的大牙蛀牙,医生说是智齿,明个去拔了它。

2016年添加:此文和前文皆有很多不足之处,仅供参考。
应该有个delete函数,在里面free掉malloc分配的堆空间;例如pop出的元素也应该free掉。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值