C语言数据结构之二叉树的操作
输入完全二叉树的先序序列,用#代表虚结点(空指针),如ABD###CE##F##,建立二叉树的二叉链表。已知二叉树的先序遍历序列和中序遍历序列,或者已知二叉树的中序遍历序列和后序遍历序列,建立二叉树的二叉链表。将一棵二叉树的所有结点存储在一维数组中,虚结点用#表示,利用二叉树的性质5,建立二叉树的二叉链表。例如用数组a存储的二叉树的结点如下(0单元不用写出对用二叉链表存储的二叉树进行先序、中序和后序遍历的递归和非递归算法。写出对用二叉链表存储的二叉树进行层次遍历算法。求二叉树的所有叶子及结点总数。
#include <stdio.h> #include <stdlib.h> typedef struct BiTNode { int data; struct BiTNode *lchild,*rchild; }BiTNode,*BiTree; void CreateBiTree(BiTree &bt)//按先序遍历创建一个二叉树 { int tmp; scanf("%d",&tmp ); if(tmp==-1) bt=NULL; else { bt=(BiTree)malloc(sizeof(BiTNode)); if(!bt) return; bt->data =tmp; CreateBiTree(bt->lchild ); CreateBiTree(bt->rchild ); } } void InOrderTraverse(BiTree bt)//中序递归遍历 { if(bt==NULL) return; else { InOrderTraverse(bt->lchild ); printf("%d ",bt->data ); InOrderTraverse(bt->rchild ); } } void PreOrderTraverse(BiTree bt) //先序遍历二叉树 { if ( bt ) { printf(“%4d”, bt->data); PreOrderTraverse(bt->lchild); PreOrderTraverse(bt->rchild); } } void PostOrderTraverse(BiTree bt) //后序遍历二叉树 { if ( bt ) { PostOrderTraverse(bt->lchild); PostOrderTraverse(bt->rchild); printf(“%4d”, bt->data); } } #define MAXSTACK 15 typedef struct { //定义栈的存储结构 BiTree *base; int top; }SqStack; //栈操作的相关函数 void InitStack(SqStack &S) { S.base=(BiTree*)malloc(sizeof(BiTNode)); if( !S.base ) exit(0); S.top=0; } void Push(SqStack &S, BiTree e) { if( S.top== MAXSTACK ) exit(0); S.base[S.top] = e; S.top++; } void Pop(SqStack &S, BiTree &e) { if( S.top==0) exit(0); S.top--; e=S.base[S.top]; } int GetTop(SqStack S, BiTree &e) { if( S.top== 0 ) return 0; e=S.base[S.top-1]; return 1; } int StackEmpty(SqStack S ) { if ( S.top == 0 ) return 1; else return 0; } void InOrderTraverse1(BiTree bt)//中序非递归遍历----用到栈 { SqStack S; BiTree p; if ( bt ) { InitStack( S ); Push( S, bt ); while( !StackEmpty( S )) { while(GetTop( S, p ) && p ) Push( S, p->lchild ); Pop( S, p ); if( !StackEmpty( S )) { Pop( S, p ); printf("%d ", p->data ); Push( S, p->rchild ); } } }//if } void PreOrderTraverse1(BiTree bt) //先序遍历二叉树的非递归算法 { SqStack S; BiTree p; if ( bt ) { InitStack( S ); Push( S, bt ); while( !StackEmpty( S )) { while(GetTop( S, p ) && p ) { printf(“%4d”, p->data ); Push( S, p->lchild ); } Pop( S, p ); if( !StackEmpty( S )) { Pop( S, p ); Push( S, p->rchild ); } } }//if } void PostOrderTraverse1(BiTree bt) //后序遍历二叉树的非递归算法 { SqStack S; BiTree p, q; if ( bt ) { InitStack( S ); Push( S, bt ); while( !StackEmpty( S )) { while(GetTop( S, p ) && p ) Push( S, p->lchild ); Pop( S, p ); if( !StackEmpty( S )) { GetTop( S, p ); Push( S, p->rchild ); if(GetTop( S, p ) && !p ) { Pop( S, p ); //空结点出栈 Pop( S, p ); printf(“%4d”, p->data ); while( !StackEmpty(S) && GetTop( S, q) && q->rchild == p) { Pop( S, p ); printf(“%4d”, p->data ); } if( !StackEmpty(S) ) { GetTop( S, p ); Push( S, p->rchild ); } }//if(!p) }//if(!StackEmpty(S)) }//whie }//if } #define MAXQSIZE 100 //最大队列长度 typedef struct { BiTree *base; //初始化动态分配空间 int front; int rear; } SqQueue; int InitQueue(SqQueue &Q){ //构造一个空队列 Q.base = (BiTree *)malloc(MAXQSIZE * sizeof(BiTNode)); if ( ! Q.base) return 0; Q.front = Q.rear = 0; return 1; } //InitQueue int EnQueue(SqQueue &Q, BiTree e){ //插入元素e为Q的新的队尾元素 if ((Q.rear+1)%MAXQSIZE == Q.front) return 0; Q.base[Q.rear] = e; Q.rear = (Q.rear+1) % MAXQSIZE; return 1; } int DeQueue(SqQueue &Q, BiTree &e){ // 删除Q的队头元素, 并用e返回其值 if(Q.front == Q.rear) return 0; e = Q.base[Q.front]; Q.front = (Q.front+1) % MAXQSIZE; return 1; } int EmptyQueue(SqQueue Q)//判队空 { if(Q.front ==Q.rear ) return 1; else return 0; } void LevelOrderTraverse(BiTree bt) { //按层次遍历二叉树算法——用到队列这种数据结构 SqQueue Q; BiTree p; if( !bt ) return ; //空树 InitQueue(Q);//初始化空队列Q //p=bt; EnQueue(Q, bt); //根入队 while( !EmptyQueue(Q)) { DeQueue(Q, p); //队头p出队 printf("%d ",p->data ); //访问p if(p->lchild) EnQueue(Q,p->lchild); //p的左孩子入队 if(p->rchild) EnQueue(Q,p->rchild); //p的右孩子入队 } } void LeavesCount(BiTree bt,int &count)//求二叉树的叶子结点数 { SqQueue Q; BiTree p; //p=bt; if(!bt) count=0; else { InitQueue(Q); EnQueue(Q,bt); while( !EmptyQueue(Q)) { DeQueue(Q, p); if(!p->lchild && !p->rchild)count++; if(p->lchild) EnQueue(Q,p->lchild); //p的左孩子入队 if(p->rchild) EnQueue(Q,p->rchild); //p的右孩子入队 } } } void main() { BiTree bt; printf("建立二叉树:\n"); CreateBiTree(bt); printf("中序递归遍历二叉树:\n"); InOrderTraverse(bt); printf("\n"); printf("中序非递归遍历二叉树:\n"); InOrderTraverse1(bt); printf("\n"); printf("层次遍历二叉树:\n"); LevelOrderTraverse(bt); printf("\n"); int count=0; LeavesCount(bt,count); printf("叶子结点数为:%d\n",count); }
不为失败找原因,要为成功找方法!