前序 中序遍历 非递归 树不紧凑

/*

* Copyright (c) 2004

* All rights reserved.

*

* 文件名称:Traverse.c

* 文件标识:为二叉树各种操作中的一种

* 摘    要:二叉树操作,包含先序、中序和后序遍历的递归算法,

* 及中序遍历的非递归算法。

* 当前版本:1.0

* 作    者:Yu

* 完成日期:2004年7月31日

*

* 取代版本:1.0

* 原作者  :Yu

* 完成日期:2004年7月31日

*/

#include<stdlib.h>

#include<stdio.h>

#define STACK_INIT_SIZE 100//栈初始分配的空间数

#define STACKINCREAMENT 10//栈空间不够时增加的空间数

typedef char eletype;//二叉树结点信息类型
//using namespace std;
typedef struct BiTNode//二叉树结点类型

{

 struct BiTNode *lchild,*rchild;

 eletype data;

}BiTNode,*treetp,tree; ;
typedef struct node{
 int data;
 struct node *lchild,*rchild;
}*treetp1,tree1;

typedef BiTNode *elemtype;//elemtype声明为指针类型

typedef struct stack//栈的存储类型,采用动态分配

{

 elemtype *base;

 elemtype *top;

 int stacksize;

}sqstack;

 

sqstack *initstack()//创建栈

{

 sqstack *s;

 if (!(s = (sqstack *)malloc(sizeof(sqstack))))exit(-1);

 s->base = (elemtype *)malloc(STACK_INIT_SIZE*sizeof(elemtype));//初始化为栈分配STACK_INIT_SIZE个elemtype类型的空间

 if (!s->base)//分配空间失败

 {

  exit(-2);

  printf("栈空间分配失败!/n");

 }

 if (s->base)//分配空间成功

  printf("栈空间分配成功!/n");

 s->top = s->base;//初始化栈的头尾指针

 s->stacksize = STACK_INIT_SIZE;

 return s;

}

 

void push(sqstack *s,elemtype e)//压栈,e要是一个地址

{

 if (s->top-s->base>=s->stacksize)//栈满

 {

  s->base = (elemtype *)realloc(s->base,(s->stacksize+STACKINCREAMENT)*sizeof(elemtype));//栈满时增加空间

  if (!s->base)//增加分配空间失败

   exit(-2);

  s->stacksize += STACKINCREAMENT;

 }

 *(s->top) = e;

 s->top++;

}

 

elemtype pop1(sqstack *s)//出栈1,返回的e为栈顶元素是一个地址

{

 elemtype e;

 if (s->top == s->base)return 0;//栈空时返回

 s->top--;

 e = *(s->top);

 return e;

}

 

int stackempty(sqstack *s)//判断栈空,栈空返回1,否则返回0

{

 if (s->base == s->top)return 1;

 else return 0;

}

 

BiTNode *CreateBiTree(treetp t)//先序递归法建树

{

 //char x;

 //BiTNode *t;

 //scanf("%c",&x);

 ///*if (x == '0') return t;
 //else*/

 ///*{*/

 // if (!(t = (BiTNode *)malloc(sizeof(BiTNode))))exit(-1);
 // if (x == '0') return t;

 // t->data = x;//建立节点

 // t->lchild = CreateBiTree();//建左子树

 // t->rchild = CreateBiTree();//建右子树

 }

 //return t;

 int c=1;
 int number=0;
 treetp p,di; // p用来指向所要分配的结点,di用来指向p的双亲
 do{ // do—while结构用来构造二叉数,直到输入0为止
  scanf("%d",&c); // 输入叶子结点的数据
  if (t==0) // 如果这是创建的第一个结点(根),则t指向这个结点(根)
  {
   t=(treetp)malloc(sizeof(tree));
   t->lchild=t->rchild=0;
   t->data=c;
  }
  else // 否则,按二叉排序树的构造方法构造树
  { p=t; // 先让p指向根
  while(p!=0) // 如果p 不空,则按二叉排序树的查找顺序来查找新的结点位置
  {
   di=p; // 在p指向下一个结点之前,用di保存当前p的位置
   if(c<(p->data)) // 如果输入的结点比p指向的结点小
    p=p->lchild; // p指向当前p的左孩子
   else
    p=p->rchild; // 否则p指向当前p的右孩子
  }
  // 此处已经退出 while(p!=0) 这个循环,表明已经找到输入的结点合适的位置了,
  // 这个位置或者是di的左孩子,或者是di的右孩子
  if(c<(di->data)) // 如果输入的结点比di小,将输入的结点添加在di左孩子
  {
   treetp NEWdi=(treetp) malloc(sizeof(tree));
   NEWdi->lchild=NEWdi->rchild=0;
   NEWdi->data=c;
   di->lchild=NEWdi;
  }
  else // 否则将输入的结点添加在di的又孩子
  {
   treetp NEWdi=(treetp) malloc(sizeof(tree));
   NEWdi->lchild=NEWdi->rchild=0;
   NEWdi->data=c;
   di->rchild=NEWdi;
  }
  }
  ++number; // 结点数+1
 }while(c!=0);
 printf("叶子的数量:%d",number);
 return t;

}

 

int InOrder(BiTNode *t)//中序遍历二叉树非递归算法

{

 sqstack *s;

 BiTNode *p;

 s = initstack();//初始化栈

 p = t;

 printf("中序遍历二叉树,字符序列为:/n");

 while (p||!stackempty(s))

 {

  while (p)//找最左结点

  {

   push(s,p);

   p = p->lchild;//p指针顺lchild而下

  }

  p = pop1(s);//栈顶元素出栈以访问最左结点

  printf("%d",p->data);//访问最左结点

  p = p->rchild;

 }

 printf("/n");

 return 1;

}
int InOrderPre(BiTNode *t)//中序遍历二叉树非递归算法

{

 sqstack *s;

 BiTNode *p;

 s = initstack();//初始化栈

 p = t;

 printf("中序遍历二叉树,字符序列为:/n");

 while (p||!stackempty(s))

 {

  while (p)//找最左结点

  {
      printf("%d",p->data);//访问最左结点
   push(s,p);

   p = p->lchild;//p指针顺lchild而下

  }

  p = pop1(s);//栈顶元素出栈以访问最左结点

  //printf("%d",p->data);//访问最左结点

  p = p->rchild;

 }

 printf("/n");

 return 1;

}
void  PreOrder(BiTNode *t)//BiNode<T> *root)
{
 int top= -1;      //采用顺序栈,并假定不会发生上溢
 BiTNode *root=t;
 sqstack *s;
 s = initstack();//初始化栈

 BiTNode *p;
 p = t;
 while (root!=NULL || top!= -1)
 {
  while (root!= NULL)
  {
          //cout<<root->data;
     printf("%d",root->data);//访问最左结点
   //s[++top]=root;
   push(s,root);
   root=root->lchild; 
  }
 /* if (top!= -1) { */ //错在这里 不能加这个判断
   //root=s[top--];
   root = pop1(s);
  while (root!= NULL){
   /*root = pop1(s);*/
   root = pop1(s);
   root=root->rchild;  //这个我没有看懂  他是先把所有的 左边 的 读完 ,再从下到上 读 右边的
  //}
   //root = pop1(s);
  }
 }
}

//
void main()

{//晕,这个程序也无法正确执行

 //BiTNode *t;
 treetp t=0,r;
 r=CreateBiTree(t);//create (t,0);
 

 //printf("请输入建树字符序列,以空格表示NULL:/n");

 //t = CreateBiTree();

 InOrder(r);

 //PreOrder(r);
 InOrderPre(r);

}
//5 4 6 9 2 7 5 8 0
// 0 2 4 5 5 6 7 8 9  中序。前序是 024556789
   //5
   // 6
   // 5  8
   // 7  9

   // 左边
   // 2
   // 0  4
// 5
//4
//2
//0
//右边
//6
//5  9
// 7
// 8
 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
1.先序遍历非递归算法#define maxsize 100typedef struct{ Bitree Elem[maxsize]; int top;}SqStack;void PreOrderUnrec(Bitree t){ SqStack s; StackInit(s); p=t; while (p!=null || !StackEmpty(s)) { while (p!=null) //遍历左子 { visite(p->data); push(s,p); p=p->lchild; }//endwhile if (!StackEmpty(s)) //通过下一次循环中的内嵌while实现右子遍历 { p=pop(s); p=p->rchild; }//endif }//endwhile }//PreOrderUnrec2.中序遍历非递归算法#define maxsize 100typedef struct{ Bitree Elem[maxsize]; int top;}SqStack;void InOrderUnrec(Bitree t){ SqStack s; StackInit(s); p=t; while (p!=null || !StackEmpty(s)) { while (p!=null) //遍历左子 { push(s,p); p=p->lchild; }//endwhile if (!StackEmpty(s)) { p=pop(s); visite(p->data); //访问根结点 p=p->rchild; //通过下一次循环实现右子遍历 }//endif }//endwhile}//InOrderUnrec3.后序遍历非递归算法#define maxsize 100typedef enum{L,R} tagtype;typedef struct { Bitree ptr; tagtype tag;}stacknode;typedef struct{ stacknode Elem[maxsize]; int top;}SqStack;void PostOrderUnrec(Bitree t){ SqStack s; stacknode x; StackInit(s); p=t; do { while (p!=null) //遍历左子 { x.ptr = p; x.tag = L; //标记为左子 push(s,x); p=p->lchild; } while (!StackEmpty(s) && s.Elem[s.top].tag==R) { x = pop(s); p = x.ptr; visite(p->data); //tag为R,表示右子访问完毕,故访问根结点 } if (!StackEmpty(s)) { s.Elem[s.top].tag =R; //遍历右子 p=s.Elem[s.top].ptr->rchild; } }while (!StackEmpty(s));}//PostOrderUnrec
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值