/* 二叉树后根周游的非递归算法*/

/* 二叉树后根周游的非递归算法*/
#include "stdafx.h"
#include<stdlib.h>
#include<stdio.h>

typedef char DataType;

struct BinTreeNode;                         /* 二叉树中结点 */
typedef struct BinTreeNode *PBinTreeNode;   /* 结点的指针类型 */
int inum=0;

struct BinTreeNode {
 DataType  info;                         /* 数据域 */
 PBinTreeNode  llink;                    /* 指向左子女 */
 PBinTreeNode  rlink;                    /* 指向右子女 */
};

typedef struct BinTreeNode *BinTree;
typedef BinTree *PBinTree;
typedef PBinTreeNode BNode;

PBinTreeNode root_btree(PBinTree t) {
 return *t;
}

PBinTreeNode leftChild_btree (PBinTreeNode p){
 return p->llink;
}

PBinTreeNode rightChild_btree (PBinTreeNode p){
 return p->rlink;
}

/*以下算法就是先将二叉树扩充为扩充的二叉树,
然后按先根次序周游的顺序输入结点的信息,
生成一个双链存储的二叉树的过程*/
/*
PBinTreeNode create(PBinTreeNode t,int c)
{
 PBinTreeNode p,di; // p用来指向所要分配的结点,di用来指向p的双亲
 do{ // do—while结构用来构造二叉数,直到输入0为止
  scanf("%d",&c); // 输入叶子结点的数据
  if (t==0) // 如果这是创建的第一个结点(根),则t指向这个结点(根)
  {
   t=(PBinTreeNode)malloc(sizeof(PBinTreeNode));
   t->llink=t->rlink=0;
   t->info=c;
  }
  else // 否则,按二叉排序树的构造方法构造树
  { p=t; // 先让p指向根
  while(p!=0) // 如果p 不空,则按二叉排序树的查找顺序来查找新的结点位置
  {
   di=p; // 在p指向下一个结点之前,用di保存当前p的位置
   if(c<(p->info)) // 如果输入的结点比p指向的结点小
    p=p->llink; // p指向当前p的左孩子
   else
    p=p->rlink; // 否则p指向当前p的右孩子
  }
  // 此处已经退出 while(p!=0) 这个循环,表明已经找到输入的结点合适的位置了,
  // 这个位置或者是di的左孩子,或者是di的右孩子
  if(c<(di->info)) // 如果输入的结点比di小,将输入的结点添加在di左孩子
  {
   PBinTreeNode NEWdi=(PBinTreeNode) malloc(sizeof(PBinTreeNode));
   NEWdi->llink=NEWdi->rlink=0;
   NEWdi->info=c;
   di->llink=NEWdi;
  }
  else // 否则将输入的结点添加在di的又孩子
  {
   PBinTreeNode NEWdi=(PBinTreeNode) malloc(sizeof(PBinTreeNode));
   NEWdi->llink=NEWdi->rlink=0;
   NEWdi->info=c;
   di->rlink=NEWdi;
  }
  }
  ++number; // 结点数+1
 }while(c!=0);
 printf("叶子的数量:%d",number);
 return t;
} */
PBinTreeNode createRest_BTree() {
 /* 递归创建从根开始的二叉树 */
 //PBinTreeNode  pbnode;
 //char ch;
 //int i=0;
 //scanf("%c",&ch);
 //if ( ch == '@') pbnode = NULL;
 //else {
 // inum++;
 // //if (inum>6) return pbnode;
 // pbnode = (PBinTreeNode )malloc(sizeof(struct BinTreeNode));
 // if (pbnode == NULL) {
 //  printf("Out of space!/n");
 //  return pbnode;
 // }
 // pbnode->info = ch;

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

}


PBinTree  create_BTree( void ) {
 /* 创建完整的二叉树 */
 int i=0;
 PBinTree pbtree = (PBinTree)malloc(sizeof(BinTree));
 if (i<1){
  i++;
  
   
   if (pbtree != NULL)
   /*{
    i++;  
   }*/
    *pbtree = createRest_BTree( );  /* 递归创建从根开始的二叉树 */
 }
 
 return pbtree;
}

void visit(BNode p) {
 //printf("%c ",p->info); }
 printf("%d ",p->info);
}

typedef struct {
 BNode ptr;          /* 进栈结点 */
 int   tag;          /* 标记 */
} Elem;

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

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, Elem 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所指的栈不为空,求栈顶元素的值 */
Elem  top_seq( PSeqStack pastack ) {
 return (pastack->s[pastack->t]);
}

void nPostOrder(PBinTree t) {
 PSeqStack st; /* 栈中元素类型为 Elem */
 Elem stnode;
 BNode  p;  /* 周游时当前要处理的结点*/
 char continueflag; /* 表明是否继续退栈,从右子树返回时访问完根之后需继续退栈 */

 if (*t == NULL) return;
 st = createEmptyStack_seq( );  /* 创建空栈 */

 p = *t;                 /* 从根结点开始 */
 do {     /* 每执行一次大循环进入一棵由p指出根的子树去周游 */
  while (p != NULL) { /* 反复地把遇到的结点进栈并进入它的左子树 */
   stnode.ptr = p;
   stnode.tag = 1;
   push_seq(st, stnode);
   p = leftChild_btree(p);
  }
  continueflag = 't';
  while ( continueflag == 't' && !isEmptyStack_seq(st) ) {
   stnode = top_seq(st);
   pop_seq(st); /* 退栈 */
   p = stnode.ptr;    
   if (stnode.tag == 1) {
    /* 如果是从左子树回来,则改标志重新进栈,停止退栈并进入右子树 */
    stnode.tag = 2;
    push_seq(st, stnode);
    continueflag = 'f';
    p = rightChild_btree(p);
   }
   else visit(p);
  }
 } while (!isEmptyStack_seq (st)); /* 栈为空时,全部周游完 */
}

int main(){

PBinTree  PBinTreeNode = create_BTree();
 nPostOrder(PBinTreeNode);
 putchar('/n');
 return 0;
}


 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值