二叉樹的定義及基本操作
阿新 • • 發佈:2019-02-09
(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 10 typedef 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; }//判斷一個棧是否為空 //往棧裡面插入元素e Status 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的非遞迴演算法,對每個資料元素呼叫函式Visit SqStack 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"); } else printf("建立二叉樹失敗\n"); printf("先序遍歷結果為:\n"); if(PreOrderTraverse(T,PrintElement)) { printf("\n"); } else printf("遍歷失敗\n"); printf("中序遍歷結果為:\n"); if(InOrderTraverse(T,PrintElement)) { printf("\n"); } else printf("遍歷失敗\n"); printf("後序遍歷結果為:\n"); if(PostOrderTraverse(T,PrintElement)) { printf("\n"); } else printf("遍歷失敗\n"); CountLeaf(T,n0); printf("葉子的結點數位:%d\n",n0); Count(T,n2); printf("度為2的結點個數為:%d\n",n2); return 0; }