實驗三:二叉樹的操作(結構轉換,遞迴和非遞迴的先序、中序和後序遍歷,以及層次遍歷,葉子結點和總結點的計數)
阿新 • • 發佈:2019-01-03
(1)將一棵二叉樹的所有結點儲存在一維陣列中,虛結點用#表示,利用二叉樹性質5,建立二叉樹的二叉連結串列。
(2) 寫出對用二叉連結串列儲存的二叉樹進行先序、中序和後序遍歷的遞迴和非遞迴演算法。
(3)寫出對用二叉連結串列儲存的二叉樹進行層次遍歷演算法。
(4)求二叉樹的所有葉子及結點總數。
//Sinhaeng Hhjian #include<stdio.h> #include<string.h> #include<stdlib.h> #define MAX 100005 typedef struct BTNode{ char data; struct BTNode *lchild, *rchild; }BTNode, *BiTree; struct Queue{ BiTree *base; int f, r; }; void InitQueue(Queue &q){ q.base = (BiTree *)malloc(sizeof(BiTree) * MAX); q.f = q.r = 0; } void InQueue(Queue &q, BiTree bt){ q.base[q.r++] = bt; } int IsEmpty(Queue q){ return q.f == q.r? 1:0; } void OutQueue(Queue &q, BiTree &bt){ if(IsEmpty(q)) return ; bt = q.base[q.f++]; } void CreatBiTree(BiTree &bt, char *Data, int n){ Queue Q; int Qnum[MAX], f, r, i; BiTree p; if(n<1){ bt = NULL; return; } bt = (BiTree)malloc(sizeof(BTNode)); bt->data = Data[1]; InitQueue(Q); InQueue(Q, bt); f = r = 0; Qnum[r++]=1; while(!IsEmpty(Q)){ OutQueue(Q, p); i=Qnum[f++]; if(2*i > n || Data[2*i] == '#') p->lchild = NULL; else{ p->lchild = (BiTree)malloc(sizeof(BTNode)); p->lchild->data = Data[2*i]; InQueue(Q, p->lchild); Qnum[r++] = 2*i; } if(2*i+1 > n || Data[2*i+1] == '#') p->rchild = NULL; else{ p->rchild = (BiTree)malloc(sizeof(BTNode)); p->rchild->data = Data[2*i+1]; InQueue(Q, p->rchild); Qnum[r++] = 2*i+1; } } } void PreOrderTraverse(BiTree bt){ if(bt){ printf("%3c", bt->data); PreOrderTraverse(bt->lchild); PreOrderTraverse(bt->rchild); } } void InOrderTraverse(BiTree bt){ if(bt){ InOrderTraverse(bt->lchild); printf("%3c", bt->data); InOrderTraverse(bt->rchild); } } void PostOrderTraverse(BiTree bt){ if(bt){ PostOrderTraverse(bt->lchild); PostOrderTraverse(bt->rchild); printf("%3c", bt->data); } } struct Stack{ BiTree *base; int top; }; void Push(Stack &s, BiTree bt){ s.base[++s.top] = bt; } int GetTop(Stack s, BiTree &bt){ if(!s.top) return 0; bt = s.base[s.top]; return 1; } int IsSEmpty(Stack s){ return s.top==0? 1 : 0; } void InitStack(Stack &s){ s.base = (BiTree *)malloc(MAX*(sizeof(BiTree))); s.top=0; } void Pop(Stack &s, BiTree &bt){ if(IsSEmpty(s)) return ; bt = s.base[s.top]; s.top--; } void PreOrderTraverse2(BiTree bt){ if(bt){ Stack S; BiTree p; InitStack(S); Push(S, bt); while(!IsSEmpty(S)){ while(GetTop(S, p) && p){ printf("%3c", p->data); Push(S, p->lchild); } Pop(S, p); if(!IsSEmpty(S)){ Pop(S, p); Push(S, p->rchild); } } } } void InOrderTraverse2(BiTree bt){ if(bt){ Stack S; BiTree p; InitStack(S); Push(S, bt); while(!IsSEmpty(S)){ while(GetTop(S, p) && p) Push(S, p->lchild); Pop(S, p); if(!IsSEmpty(S)){ Pop(S, p); printf("%3c", p->data); Push(S, p->rchild); } } } } void PostOrderTraverse2(BiTree bt){ if(bt){ Stack S; BiTree p, q; InitStack(S); Push(S, bt); while(!IsSEmpty(S)){ while(GetTop(S, p) && p) Push(S, p->lchild); Pop(S, p); if(!IsSEmpty(S)){ GetTop(S, p); if(p->rchild) Push(S, p->rchild); else{ Pop(S, p); printf("%3c", p->data); while(!IsSEmpty(S) && GetTop(S, q) && q->rchild == p){ Pop(S, p); printf("%3c", p->data); } if(!IsSEmpty(S)){ GetTop(S, p); Push(S, p->rchild); } } } } } } void LevelOrderTraverse(BiTree bt){ if(bt){ Queue Q; BiTree p; InitQueue(Q); InQueue(Q, bt); while(!IsEmpty(Q)){ OutQueue(Q, p); printf("%3c", p->data); if(p->lchild) InQueue(Q, p->lchild); if(p->rchild) InQueue(Q, p->rchild); } } } void CountLeaf(BiTree bt, int &leaves, int &cnt, char *lea){ if(bt){ cnt++; CountLeaf(bt->lchild, leaves, cnt, lea); if(!bt->lchild && !bt->rchild) lea[leaves++]=bt->data; CountLeaf(bt->rchild, leaves, cnt, lea); } } int main(){ BiTree bt; char date[MAX]; printf("請輸入一維陣列結構的二叉樹:\n"); scanf("%s", date+1); int n=strlen(date+1); CreatBiTree(bt, date, n); printf("遞迴先序遍歷:"); PreOrderTraverse(bt); printf("\n"); printf("遞迴中序遍歷:"); InOrderTraverse(bt); printf("\n"); printf("遞迴後序遍歷:"); PostOrderTraverse(bt); printf("\n\n"); printf("非遞迴先序遍歷:"); PreOrderTraverse2(bt); printf("\n"); printf("非遞迴中序遍歷:"); InOrderTraverse2(bt); printf("\n"); printf("非遞迴後序遍歷:"); PostOrderTraverse2(bt); printf("\n\n"); printf("層次遍歷:"); LevelOrderTraverse(bt); printf("\n\n"); int cnt=0, sum=0; char leaves[MAX]; CountLeaf(bt, sum, cnt, leaves); printf("葉子節點總數為:%d\n", sum); printf("分別是:"); for(int i=0;i<sum;i++) printf("%3c", leaves[i]); printf("\n節點總數為:%d\n", cnt); return 0; }