二茶树
/* ****************二叉树有关算法*************** */ #include "stdio.h" #include "conio.h" #include "stdlib.h" #define stackinitsize 100 #define OK 1 #define ERROR 0 #define OVERFLOW -1 typedef int TElemType ; typedef int Status; //一一一一一二叉树的二叉链表存储表示一一一一一 typedef struct BiTNode{ TElemType data; struct BiTNode *lchild,*rchild; //左右孩子指针 }BiTnode,*SElemType,*BiTree; typedef struct{ //该堆栈的元素是指针类型的 //base和top均是指向指针的指针 SElemType *base; SElemType *top; int stacksize; }sqstack;//堆栈结构 //一一一一一基本操作的函数原型说明(部分)一一一一一 Status CreateBitree(BiTree &T); //按先序次序输入二叉树中结点的值(一个字符),空格字符表示空树。 //构造二叉链表表示的二叉树T. Status PreOrderTraverse(BiTree T,Status(*Visit)(TElemType e)); //采用二叉链表存储结构,visit是对结点操作的应用函数。 //先序遍历二叉树T,对每个结点调用函数Visit一次且仅一次。 //一旦visit()失败,则操作失败。 Status InorderTraverse(BiTree T,Status(*Visit)(TElemType e)); //采用二叉链表存储结构,Visit是对结点操作的应用函数。 //中序遍历二叉树T,对每个结点调用函数Visit一次且仅一次。 //一旦visit()失败,则操作失败。 Status PostorderTraverse(BiTree T,Status(*Visit)(TElemType e)); //采用二叉链表存储结构,visit是对结点操作的应用函数。 //后序遍历二叉树T,对每个结点调用函数Visit一次且仅一次。 //一旦visit()失败,则操作失败。 Status LevelIOrderTraverse(BiTree T,Status(*Visit)(TElemType e)); //采用二又链表存储结构,Visit是对结点操作的应用函数。 //层序遍历二叉树T,对每个结点调用函数Visit一次且仅一次。 //一旦visit()失败,则操作失败 sqstack *InitStack()//初始化堆栈 {sqstack *s; s->base=(SElemType*)malloc(100*sizeof(SElemType)); if(!s->base) return NULL; s->top=s->base; s->stacksize=100; return s; } int StackEmpty(sqstack *s) //栈空判别 {return(s->top==s->base); } void Pop(sqstack *s,SElemType &e)//弹栈 { e=*--s->top; } Status GetTop(sqstack *s,SElemType &e) { if(s->top==s->base) return ERROR; e=*(s->top-1); return OK; } void Push(sqstack *s,SElemType e)//将元素压入堆栈 {SElemType t; *s->top++=e; } Status CreateBiTree(BiTree &T){ //按先序次序输入二叉树中结点的值(一个字符),空格字符表示空树。 //构造二叉链表表示的二叉树T. char ch; ch=getche(); if(ch==' ') T=NULL; else{ if(!(T=(BiTNode *)malloc(sizeof(BiTNode)))) return(OVERFLOW); T->data=ch; //生成根结点 CreateBiTree(T->lchild);//构造左子树 CreateBiTree(T->rchild);//构造右子树 } return OK; }//CreateBiTree Status PreOrderTraverse(BiTree T,Status(*Visit)(TElemType e)) //采用二叉链表存储结构,visit是对数据元素操作的应用函数, //先序遍历二叉树T的递归算法,对每个数据元素调用函数visit。 //调用实例: PreOrderTraverse(T,printElement); { if(T){ if (Visit(T->data)) if (PreOrderTraverse(T->lchild,Visit)) if (PreOrderTraverse(T->rchild,Visit)) return OK; return ERROR; }else return OK; }//preOrderTraVerse Status InOrderTraverse(BiTree T,Status(*Visit)(TElemType e)) //采用二叉链表存储结构,visit是对数据元素操作的应用函数, //中序遍历二叉树T的递归算法,对每个数据元素调用函数visit。 { if(T){ if (InOrderTraverse(T->lchild,Visit)) if (Visit(T->data)) if (InOrderTraverse(T->rchild,Visit)) return OK; return ERROR; }else return OK; }//preOrderTraVerse Status PostOrderTraverse(BiTree T,Status(*Visit)(TElemType e)) //采用二叉链表存储结构,visit是对数据元素操作的应用函数, //后序遍历二叉树T的递归算法,对每个数据元素调用函数visit。 { if(T){ if (PostOrderTraverse(T->lchild,Visit)) if (PostOrderTraverse(T->rchild,Visit)) if (Visit(T->data)) return OK; return ERROR; }else return OK; }//preOrderTraVerse Status PrintElement(TElemType e) { //输出元素e的值 printf("%c",e); return OK; } Status InorderTraverseNoRecursion1(BiTree T,Status(*Visit)(TElemType e)) //采用二叉链表存储结构,visit是对数据元素操作的应用函数。 //中序遍历二叉树T的非递归算法,对每个数据元素调用函数visit。 {sqstack *s; BiTree p; s=InitStack();p=T; while(p||!StackEmpty(s)) { if(p){ Push(s,p);p=p->lchild;}//根指针进栈,遍历左子树 else{ //根指针退栈,访问根结点,遍历右子树 Pop(s,p);if(!Visit(p->data)) return ERROR; p=p->rchild; }//else }//while return OK; }//InorderTraVerse1 Status InorderTraverseNoRecursion2(BiTree T,Status(*Visit)(TElemType e)) //采用二叉链表存储结构,visit是对数据元素操作的应用函数。 //中序遍历二叉树T的非递归算法,对每个数据元素调用函数visit。 {sqstack *s; BiTree p; s=InitStack();Push(s,T); while(!StackEmpty(s)) { while(GetTop(s,p)&&p) Push(s,p->lchild);//向左走到尽头 Pop(s,p); //空指针退栈 if(!StackEmpty(s)) { //访问结点,向右一步 Pop(s,p);if(!Visit(p->data)) return ERROR; Push(s,p->rchild); }//if }//while return OK; }//InorderTraVerse1 void main() { BiTree t; printf("\n请按先序遍历输入二叉树(当左右子树为空时用空格输入)\n"); CreateBiTree(t); printf("\n该二叉树的先序遍历为:\n"); PreOrderTraverse(t,PrintElement); printf("\n该二叉树的中序遍历为:\n"); InOrderTraverse(t,PrintElement); printf("\n该二叉树的后序遍历为:\n"); PostOrderTraverse(t,PrintElement); printf("\n该二叉树的中序遍历为:(用非递归调用1)\n"); InorderTraverseNoRecursion1(t,PrintElement); printf("\n该二叉树的中序遍历为:(用非递归调用2)\n"); InorderTraverseNoRecursion2(t,PrintElement); }