二叉樹模板 先中後序遍歷,非遞迴演算法,層次遍歷,葉子結點數,深度
阿新 • • 發佈:2019-01-29
#include <iostream> #include<stdio.h> #include<malloc.h> #include<queue> #define MAX 50 using namespace std; typedef struct BTNode /*節點結構宣告*/ { char data ; /*節點資料*/ struct BTNode *lchild; struct BTNode *rchild ; /*指標*/ }*BiTree; int nodenum; int leavesnum; BiTree createBiTree(BiTree t) /* 先序遍歷建立二叉樹*/ { char s; printf("\nplease input data:(exit for #)"); s=getchar(); if(s=='#') { t=NULL; return t; } t=(BiTree)malloc(sizeof(struct BTNode)); if(t==NULL) { printf("Memory alloc failure!"); return t; } t->data=s; nodenum++; /*二叉樹結點計數*/ t->lchild=createBiTree(t->lchild); /*遞迴建立左子樹*/ t->rchild=createBiTree(t->rchild); /*遞迴建立右子樹*/ if(t->lchild==NULL&&t->rchild==NULL) leavesnum++; /*葉子結點計數*/ return t; } void PreOrder(BiTree p) /* 先序遍歷二叉樹*/ { if ( p!= NULL ) { printf("%c", p->data); PreOrder( p->lchild ) ; PreOrder( p->rchild) ; } } void InOrder(BiTree p) /* 中序遍歷二叉樹*/ { if( p!= NULL ) { InOrder( p->lchild ) ; printf("%c", p->data); InOrder( p->rchild) ; } } void PostOrder(BiTree p) /* 後序遍歷二叉樹*/ { if ( p!= NULL ) { PostOrder( p->lchild ) ; PostOrder( p->rchild) ; printf("%c", p->data); } } void Preorder_n(BiTree p) /*先序遍歷的非遞迴演算法*/ { BiTree stack[MAX],q; int top=0,i; for(i=0; i<MAX; i++) stack[i]=NULL; /*初始化棧*/ q=p; while(q!=NULL) { printf("%c",q->data); if(q->rchild!=NULL) stack[top++]=q->rchild; if(q->lchild!=NULL) q=q->lchild; else if(top>0) q=stack[--top]; else q=NULL; } } void InOrder_n(BiTree t) /*中序遍歷二叉樹的非遞迴演算法*/ { BiTree stack[MAX],p; /*定義順序棧stack,最大容量為100*/ int top=0; /*棧頂指標top*/ p=t; do { while(p!=NULL) /*順著左鏈走到盡頭*/ { stack[top++]=p; /*當二叉樹不空的時候根指標入棧*/ p=p->lchild; /*順著左鏈搜尋知道最左端葉子結點*/ } if(top>0) { p=stack[top-1]; /*棧不空時取出棧頂元素*/ printf("%c",p->data); /*輸出當前訪問的根結點*/ top--; p=p->rchild; /*順著右鏈搜尋*/ } } while(top!=0||p!=NULL); /*遍歷未結束時,繼續訪問結點*/ } void PostOrder_n(BiTree t) /*後序遍歷二叉樹的非遞迴演算法*/ { if(t==NULL) return ; BiTree stack[MAX],pnow=t,plast=NULL; /*pnow當前訪問結點存根結點,plast上次訪問的結點,定義指標賦值NULL*/ int top=0; /*棧頂充當指標作用的top*/ while(pnow!=NULL) { stack[top++]=pnow; pnow=pnow->lchild; } /*讓pnow指向最左下的結點的左孩子,值為NULL*/ while(top>0) { pnow=stack[top-1]; /*讓pnow指向最左下的結點*/ top--; /*相當於棧頂元素出棧*/ if(pnow->rchild==NULL||pnow->rchild==plast) /*如果右子樹為空或右子樹已訪問過,訪問根結點*/ { printf("%c",pnow->data); plast=pnow; /*plast存已訪問的最新結點*/ } else /*右子樹不為空且未訪問*/ { stack[top++]=pnow; /*左右根,要先輸出右,根結點再次進棧*/ pnow=pnow->rchild; /*當前訪問的結點更新為pnow的右子樹*/ while(pnow!=NULL) { stack[top++]=pnow; pnow=pnow->lchild; } /*找到該右子樹的最左下結點更新pnow*/ } } } int TreeCount(BiTree t) /*求二叉樹葉子結點數*/ { if(t==NULL) return 0; /*空樹*/ else if((t->lchild==NULL)&&(t->rchild==NULL)) return 1; else return TreeCount(t->lchild)+TreeCount(t->rchild); } int Depth(BiTree t) /*求二叉樹的深度*/ { int hl,hr; if(t==NULL) return 0; else { hl=Depth(t->lchild); hr=Depth(t->rchild); if(hl>=hr) return hl+1; else return hr+1; } } int TreeDepth(BiTree t) /*求二叉樹的深度*/ { int rightdep=0; int leftdep=0; if(t==NULL) return 0; leftdep=TreeDepth(t->lchild); rightdep=TreeDepth(t->rchild); return (leftdep>rightdep)?(leftdep+1):(rightdep+1); } void release(BiTree t) /*釋放二叉樹空間*/ { if(t!=NULL) { release(t->lchild); release(t->rchild); free(t); } } void LevelOrder(BiTree t) /*層次遍歷*//*acm模板c++*/ { BiTree p=t; queue<BiTree>q; q.push(p); while(q.empty()!=1) { p=q.front(); printf("%c",p->data); q.pop(); if(p->lchild!=NULL) q.push(p->lchild); if(p->rchild!=NULL) q.push(p->rchild); } } int main() { BiTree t=NULL; nodenum=0; leavesnum=0; t=createBiTree(t); printf("\n\nPreOrder the tree is:"); PreOrder(t); printf("\n\nInOrder the tree is:"); InOrder(t); printf("\n\nPostOrder the tree is:"); PostOrder(t); printf("\n\n先序遍歷序列(非遞迴):"); Preorder_n(t); printf("\n\n中序遍歷序列(非遞迴):"); InOrder_n(t); printf("\n\n後序遍歷序列(非遞迴):"); PostOrder_n(t); printf("\n\n層次遍歷序列:"); LevelOrder(t); printf("\n\n二叉樹中結點總數:"); printf("%d\n",nodenum); printf("\n\n二叉樹中葉子結點總數:"); printf("%d\n",leavesnum); /*或者TreeCount(t)*/ printf("\n\n二叉樹的深度:"); printf("%d\n",Depth(t)); /*或者TreeDepth(t)*/ release(t); return 0; }