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