/* 树的先根周游的非递归算法*/ 张老师得代码功能不好 网上中序可以 /*

/* 树的先根周游的非递归算法*/ 张老师得代码功能不好 网上中序可以 /*

* 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;

}
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);

}
//5 4 6 9 2 7 5 8 0
// 0 2 4 5 5 6 7 8 9
   //5
   // 6
   // 5  8
   // 7  9

   // 左边
   // 2
   // 0  4

/* 树的先根周游的非递归算法*/

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

typedef int DataType;
#define MAXNUM 20       /* 栈中最大元素个数 */
struct  SeqStack {      /* 顺序栈类型定义 */
 DataType  s[MAXNUM];
 int  t;    /* 指示栈顶位置 */
};
typedef  struct SeqStack  *PSeqStack; /* 顺序栈类型的指针类型 */

/*创建一个空栈;为栈结构申请空间,并将栈顶变量赋值为-1*/
PSeqStack  createEmptyStack_seq( void ) {
 PSeqStack pastack;
 pastack = (PSeqStack)malloc(sizeof(struct SeqStack));
 if (pastack==NULL)
  printf("Out of space!! /n");
 else
  pastack->t = -1;
 return  pastack;
}

/*判断pastack所指的栈是否为空栈,为空栈时返回1,否则返回0*/
int  isEmptyStack_seq( PSeqStack pastack ) {
 return pastack->t == -1;
}

/* 在栈中压入一元素x */
void  push_seq( PSeqStack pastack, DataType x ) {
 if( pastack->t >= MAXNUM - 1  )
  printf( "Overflow! /n" );
 else {
  pastack->t++;
  pastack->s[pastack->t] = x;//这里肯定出错了,应该是他的值 而不是 序号
 }
}

/* 删除栈顶元素 */
void  pop_seq( PSeqStack pastack ) {
 if (pastack->t == -1 )
  printf( "Underflow!/n" );
 else
  pastack->t = pastack->t - 1;
}

/* 当pastack所指的栈不为空栈时,求栈顶元素的值 */
DataType  top_seq( PSeqStack pastack ) {
 return (pastack->s[pastack->t]);
}

struct  ParTreeNode {
 /*DataType  info;   结点中的元素 */
 int parent; /* 结点的父结点位置 */
};

#define  MAXNUM   20
#define null -1

struct  ParTree{   // 这个数据结构真 变态,没有数据的 值 只有 母节点的 位置。
 int   n;                  /* 树中结点的个数 */
 struct ParTreeNode  nodelist[MAXNUM];   /* 存放树中的结点 */
};

typedef struct ParTree  *PParTree;  /* 树类型的指针类型 */

int rightSibling_partree(PParTree t, int p) {
 int i;
 if (p >= 0 && p < t->n) {
  for (i = p+1; i <= t->n; i++)
   if (t->nodelist[i].parent == t->nodelist[p].parent) return i;//t->nodelist[i];//i;
 }
 return null;
}

/* 依先根序列存储时,求最左子结点的运算可简化如下*/
int leftChild_partree(PParTree t, int p) {
 if (t->nodelist[p+1].parent == p)
  return p+1;//t->nodelist[p+1];//return p + 1;//错误肯定是这里
 else
  return null;
}

typedef int Node;

void visit(Node p) { printf("%d ",p); }

void npreOrder ( PParTree t, Node p ) {
 Node c;
 PSeqStack s; /* 栈元素的类型是 Node */
 s = createEmptyStack_seq ( );

 c = 0; /*c = root ( p );*/
 do {
  while ( c!=null ) {
   visit ( c );
   push_seq( s, c );
   c = leftChild_partree ( t, c );
  }
  while ( c == null && !isEmptyStack_seq(s)) {
   c = rightSibling_partree(t, top_seq(s));
   pop_seq(s);
  }
 } while(c != null);
}

struct  ParTree tree = {10, -1,0,1,1,3,3,3,0,7,7};

//int main(){
// npreOrder(&tree, 0);
// putchar('/n');
// return 0;
//}

 

 

  • 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、付费专栏及课程。

余额充值