二叉树的定义及基本操作

来源:互联网 发布:灵魂摆渡风华绝代知乎 编辑:程序博客网 时间:2024/05/21 10:15

(1)定义二叉树的链式存储结构;

(2)建立一颗二叉链表表示的二叉树;

(3)对其进行前序,中序(非递归),后序输出。

(4)统计二叉树中叶子结点个数和度为2的结点个数。

         创建的二叉树为:

                   

#include <stdio.h>#include <stdlib.h>#include <malloc.h>#define OK 1#define ERROR 0#define OVERFLOW 0#define STACK_INIT_SIZE 100#define STACKINCREMENT 10typedef char TElemType;typedef int Status;//定义二叉链表的结点结构typedef struct BiTNode { // 结点结构                             TElemType data; struct BiTNode  *lchild, *rchild; //左右孩子指针} BiTNode, *BiTree;typedef BiTree SElemType;typedef struct{ SElemType *base;  //栈底指针 SElemType *top;   //栈顶指针 int stacksize;    //栈的容量}SqStack; //定义一个顺序栈Status InitStack(SqStack &S){ S.base = (SElemType *)malloc(STACK_INIT_SIZE * sizeof(SElemType)); if (!S.base){  printf("栈溢出!\n");  exit(OVERFLOW); } S.top = S.base; S.stacksize = STACK_INIT_SIZE; return OK;}//初始化一个顺序栈Status StackEmpty(SqStack S){ if (S.top == S.base){  return OK; } return ERROR;}//判断一个栈是否为空//往栈里面插入元素eStatus Push(SqStack &S, BiTree p){ if (S.top - S.base >= S.stacksize){  S.base = (SElemType *)realloc(S.base, (S.stacksize + STACKINCREMENT) * sizeof(SElemType));  if (!S.base){   printf("栈溢出!\n");   return OVERFLOW;  }  S.top = S.base + S.stacksize;  S.stacksize += STACKINCREMENT; }//若栈满,追加存储空间 *S.top++ = p; return OK;}//删除栈顶元素,用指针p返回栈里存放的根指针Status Pop(SqStack &S, BiTree &p){ if (StackEmpty(S))  return ERROR; //判空 p = *(--S.top); return OK;}Status CreateBiTree(BiTree &T){//按先序次序输入二叉树中结点的值,空格字符表示空树,构造二叉链表表示的二叉树T。char ch;scanf("%c",&ch);if(ch==' ')T=NULL;else{if(!(T=(BiTNode *)malloc(sizeof(BiTNode))))exit(OVERFLOW);T->data=ch;      //生成根结点CreateBiTree(T->lchild);//构造左子树CreateBiTree(T->rchild);//构造右子树}return OK;}Status PrintElement(TElemType e){printf("%c",e)//输出元素e的值;return OK;}Status PreOrderTraverse(BiTree T,Status(* Visit)(TElemType e)){//采用二叉链表存储结构,Visit是对数据元素操作的应用函数//先序遍历二叉树T的递归算法,对每个数据元素调用Visit函数if(T){if(Visit(T->data))if(PreOrderTraverse(T->lchild,Visit))if(PreOrderTraverse(T->rchild,Visit)) return OK;return ERROR;}else return OK;}Status InOrderTraverse(BiTree T,Status(*Visit)(TElemType e)){//中序遍历二叉树T的非递归算法,对每个数据元素调用函数VisitSqStack S;InitStack(S);BiTree 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;}}return OK;}Status PostOrderTraverse(BiTree T,Status(*Visit)(TElemType e)){//后序遍历二叉树T的递归算法,对每个数据元素调用Visit函数if(T){if(PreOrderTraverse(T->lchild,Visit))if(PreOrderTraverse(T->rchild,Visit))if(Visit(T->data))return OK;return ERROR;}else return OK;}void CountLeaf(BiTree T,int& count){//计算叶子结点数if(T){if((!T->lchild)&&(!T->rchild))count++;CountLeaf(T->lchild,count);CountLeaf(T->rchild,count);}}void Count(BiTree T,int& n2){//计算度为2的结点数if(T){if((T->lchild)&&(T->rchild))n2++;Count(T->lchild,n2);Count(T->rchild,n2);}}int main(){int n0=0,n2=0;BiTree T;printf("按先序次序输入一个二叉树的结点值:\n");if(CreateBiTree(T)){printf("创建二叉树成功\n");}elseprintf("创建二叉树失败\n");printf("先序遍历结果为:\n");if(PreOrderTraverse(T,PrintElement)){printf("\n");}elseprintf("遍历失败\n");printf("中序遍历结果为:\n");if(InOrderTraverse(T,PrintElement)){printf("\n");}elseprintf("遍历失败\n");printf("后序遍历结果为:\n");if(PostOrderTraverse(T,PrintElement)){printf("\n");}elseprintf("遍历失败\n");CountLeaf(T,n0);printf("叶子的结点数位:%d\n",n0);Count(T,n2);printf("度为2的结点个数为:%d\n",n2);return 0;}

1 0
原创粉丝点击