/* 树的先根周游的非递归算法*/ 张老师得代码功能不好 网上中序可以 /*
* 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;
//}