//已知中序和层次遍历序来生成二叉树 #include <stdlib.h> #include <stdio.h> #include <string.h> typedef char type; static int levels = 0; struct node { type key; node * left; node * right; }; node * fun(type arrLevel[], type arrMid[], int length, int beg , int end) { if(beg > end)return NULL; int lb = beg, le, rb, re = end; bool flag = false; node * root = (node*)malloc(sizeof(node)); if(beg == end) { root->key = arrMid[beg]; root->left = root->right = NULL; return root; } for(levels = 0; levels < length; levels ++)//注意levels是静态变量 每次都在加 { for(int i = beg; i < end; i ++) { if(arrMid[i] == arrLevel[levels]) { le = i -1; rb = i + 1; flag = true; root->key = arrLevel[levels]; break; //找到 } } if(flag)break; } root->left = fun(arrLevel, arrMid, length, lb, le); root->right = fun(arrLevel, arrMid, length, rb, re); return root; } /*-----后序遍历------*/ void post_traverse(node *r) { if(r){ post_traverse(r->left); post_traverse(r->right); printf("%c ",r->key); } printf("/n"); } /*-----后序析构------*/ void post_destroy(node* &r) { if(r) { post_destroy(r->left); post_destroy(r->right); free(r); r = 0; } } int main() { const int MAX = 20; //type arrLevel[] = "ABCDEFGHIJKMNOP"; //type arrMid[] = "HDIBJEKAMFNCOGP"; type arrLevel[MAX]; type arrMid[MAX]; printf("输入层次和中序序列 :/n"); gets(arrLevel); gets(arrMid); int length = strlen(arrLevel); node * root = fun(arrLevel, arrMid, length, 0, length-1); printf("后序遍历输出二叉树: "); post_traverse(root); post_destroy(root); getchar(); return 0; } //输入层次和中序序列 : //abcde //badce //后序遍历输出二叉树: // //b // // //d // // //e //c //a 二叉树的其它算法: #include "BiTree.h" #include <iostream> using namespace std; //每次访问所进行的操作 int Visit(int data) { cout<<(char)data; return 1; } //按前序遍历生成二叉树 void CreateBiTree(BiTree& T) { char c; cin>>c; if(c == '#') { T=NULL; } else { T = new BiTNode(); T->data = c ; CreateBiTree(T->lchild) ; //构造左子树 CreateBiTree(T->rchild) ; //构造右子树 } return ; } /*由先序序列和中序序列构造二叉树*/ void PreMidCreateBiTree(BiTree& T,string pre,string mid) { int length = pre.length() ; if( length >0 ) { T = new BiTNode(); T->data = pre[0] ; T->lchild = NULL; T->rchild = NULL; int pos = mid.find(pre[0]);//根结点在中序遍历序的位置 if(pos > 0) //左子树不空 PreMidCreateBiTree(T->lchild,pre.substr(1,pos),mid.substr(0,pos)); if(pos < length-1) //右子树不空 PreMidCreateBiTree(T->rchild,pre.substr(pos+1,length-pos-1),mid.substr(pos+1,length-pos-1)); } } /*由中序序列和后序序列构造二叉树*/ void MidPostCreateBiTree(BiTree& T,string mid,string post) { int length = post.length(); if(length>0) { //根结点 T = new BiTNode(); T->data = post[length-1] ; T->lchild = NULL; T->rchild = NULL; int pos = mid.find(post[length-1]); //根结点在中序遍历序的位置 if(pos > 0) //左子树不空 MidPostCreateBiTree(T->lchild,mid.substr(0,pos),post.substr(0,pos)); if(pos < length-1) //右子树不空 MidPostCreateBiTree(T->rchild,mid.substr(pos+1,length- pos-1 ),post.substr(pos,length- pos-1)); } } // 前序递归遍历二叉树 void PreOrderTraverse(BiTree T,int (*Visit)(TElemType e)) { if(T!=NULL) { Visit(T->data); PreOrderTraverse(T->lchild,Visit); PreOrderTraverse(T->rchild,Visit); } return ; } //非递归前序遍历二叉树 void PreOrderTraverse1(BiTree T,int (*Visit)(TElemType e)) { if(T==NULL) return ; stack <BiTree> s ; s.push(T); while(!s.empty()) { BiTree p = s.top(); s.pop(); Visit(p->data); if(p->rchild != NULL) s.push(p->rchild); if(p->lchild != NULL) s.push(p->lchild); } return; } //递归中序遍历二叉树 void InOrderTraverse(BiTree T,int (*Visit)(TElemType e)) { if(T!=NULL) { InOrderTraverse(T->lchild,Visit); Visit(T->data); InOrderTraverse(T->rchild,Visit); } return; } //非递归中序遍历二叉树 void InOrderTraverse1(BiTree T,int (*Visit)(TElemType e)) { if(T == NULL) return; stack <BiTree> s; // s.push(T); 注意初始化的时候,不要把T入栈 BiTree p = T; while(!s.empty() || p) { if( p!=NULL ) { s.push(p); //根指针进栈,遍历左子树 p = p->lchild ; } else { p=s.top(); //根指针退栈,访问根结点,遍历右子树 s.pop(); Visit(p->data); p=p->rchild ; } } } //递归后序遍历二叉树 void PostOrderTraverse(BiTree T,int (*Visit)(TElemType e)) { if(T!=NULL) { PostOrderTraverse(T->lchild,Visit); PostOrderTraverse(T->rchild,Visit); Visit(T->data); } return ; } //非递归后序遍历二叉树 void PostOrderTraverse1(BiTree T,int (*Visit)(TElemType e)) { if(T == NULL) return ; stack <BiTree> s; s.push(T); while(!s.empty()) { BiTree p = s.top(); s.pop(); if(p->rchild != NULL) s.push(p->rchild); if(p->lchild != NULL) s.push(p->lchild); Visit(p->data); } return; } //层次遍历二叉树 void LevelOrderTraverse(BiTree T,int (*Visit)(TElemType e)) { if(T==NULL) return; queue<BiTree> pq ; pq.push(T); while(!pq.empty()) { BiTree p= pq.front(); pq.pop(); Visit(p->data); if(p->lchild != NULL) pq.push(p->lchild); if(p->rchild != NULL) pq.push(p->rchild); } } /*销毁二叉树*/ void DestroyBiTree(BiTree& T) { if(T!=NULL) { BiTree lchild = T->lchild ; BiTree rchild = T->rchild ; delete T; DestroyBiTree(lchild); DestroyBiTree(rchild); } } /*构造非线索化的线索二叉树*/ //按前序次序输入二叉树中结点的值(一个字符),'#'号表示空树 void CreateBiThrTree(BiThrTree& T) { char c; cin>>c; if(c == '#') T=NULL; else { T = new BiThrNode(); T->data = c ; T->LTag = T->RTag = Link ; //左右子都是指针 CreateBiThrTree(T->lchild) ; //构造线索左子树 CreateBiThrTree(T->rchild) ; //构造线索右子树 } } /*中序遍历二叉树,并将其 中序线索化,Thr指向头结点*/ void InOrderThreading(BiThrTree& Thrt , BiThrTree T) { Thrt = new BiThrNode(); if(Thrt == NULL ) return ; Thrt ->LTag = Link ; //头结点的左子是指针 Thrt->RTag = Thread ;//右子是索引 Thrt->rchild = Thrt ; if(!T) Thrt ->lchild = Thrt; //如果二叉树空,则左指针回指 else { Thrt->lchild = T; BiThrTree pre = Thrt ; InThreading(T,pre); //最后一个结点进行 线索化 pre->rchild = Thrt ; pre->RTag = Thread ; Thrt->rchild = pre ; } } //中序线索化二叉树 void InThreading(BiThrTree p,BiThrTree& pre) { if(p != NULL) { InThreading(p->lchild,pre) ; if(pre->rchild == NULL) //后继线索 { pre->RTag = Thread; pre->rchild = p; } if(p->lchild == NULL) //前驱线索 { p->LTag = Thread ; p->lchild = pre ; } pre = p; InThreading(p->rchild,pre) ; } } /*中序遍历线索化的二叉树*/ int InOrderTraverse_Thr(BiThrTree T,int (*Visit)(TElemType e)) { BiThrTree p =T->lchild ; //T为线索化二叉树的头结点 while(p != T) //只要没有回到头结点 ,就一直循环 { while(p->LTag == Link) //即只要左子 不为空就一直 向左走 { p=p->lchild ; } Visit(p->data); while(p->RTag == Thread && p->rchild != T) //右子为线索,即下一个中序遍历点 { p=p->rchild ; Visit(p->data); } p=p->rchild ; //此时,右子是指针,则向右 走一步 } return 1; } /*销毁线索化的二叉树*/ void DestroyBiThrTree(BiThrTree & T) { /* if(Thrt==NULL) return; if(Thrt->LTag ==Link ) DestroyBiThrTree( Thrt->lchild); if(Thrt->RTag == Link) DestroyBiThrTree( Thrt->rchild); delete Thrt; */ BiThrTree p = T->lchild ; //T为线索化二叉树的头结点 while(p != T) //只要没有回到头结点 ,就一直循环 { while(p->LTag == Link) //即只要左子 不为空就一直 向左走 { p=p->lchild ; } Visit(p->data); BiThrTree q = p; BiThrTree t = NULL; while(p->RTag == Thread && p->rchild != T) //右子为线索,即下一个中序遍历点 { p=p->rchild ; if( t != NULL ) { delete t; t = NULL; } Visit(p->data); t = p; } p=p->rchild ; //此时,右子是指针,则向右 走一步 if(t != NULL) { delete t; t = NULL; } delete q; } delete T; } int main() { //ABC##DE#G##F### BiTree T; cout<<"请输入完全前序遍历序列'#'表示空:"<<endl; CreateBiTree(T); cout<<endl; cout<<"前序非递归遍历序列:"<<endl; PreOrderTraverse(T,Visit); cout<<endl; cout<<"中序非递归遍历序列:"<<endl; InOrderTraverse(T,Visit); cout<<endl; cout<<"后序非递归遍历序列:"<<endl; PostOrderTraverse(T,Visit); cout<<endl; cout<<"层次遍历序列:"<<endl; LevelOrderTraverse(T,Visit); cout<<endl; DestroyBiTree( T); string pre ; string mid ; cout<<"由先序序列和中序序列构造二叉树"<<endl; cout<<"请输入先序序列:"<<endl; cin>>pre; cout<<"请输入中序序列:"<<endl; cin>>mid; PreMidCreateBiTree(T,pre,mid); cout<<"前序遍历序列:"<<endl; PreOrderTraverse(T,Visit); cout<<endl; cout<<"中序遍历序列:"<<endl; InOrderTraverse(T,Visit); cout<<endl; cout<<"后序遍历序列:"<<endl; PostOrderTraverse(T,Visit); cout<<endl; cout<<"层次遍历序列:"<<endl; LevelOrderTraverse(T,Visit); cout<<endl; DestroyBiTree( T); cout<<endl; string post ; cout<<"由中序序列和后序序列构造二叉树"<<endl; cout<<"请输入中序序列:"<<endl; cin>>mid; cout<<"请输入后序序列:"<<endl; cin>>post; MidPostCreateBiTree( T, mid, post); cout<<"前序遍历序列:"<<endl; PreOrderTraverse(T,Visit); cout<<endl; cout<<"中序遍历序列:"<<endl; InOrderTraverse(T,Visit); cout<<endl; cout<<"后序遍历序列:"<<endl; PostOrderTraverse(T,Visit); cout<<endl; cout<<"层次遍历序列:"<<endl; LevelOrderTraverse(T,Visit); cout<<endl; DestroyBiTree( T); cout<<endl; cout<<"以下是线索化部份"<<endl; cout<<"请输入完全前序遍历序列'#'表示空:"<<endl; BiThrTree T1; CreateBiThrTree(T1); BiThrTree Thrt; InOrderThreading(Thrt ,T1); cout<<"中序遍历线索化的二叉树:"<<endl; InOrderTraverse_Thr(Thrt,Visit); DestroyBiThrTree(Thrt); //delete Thrt ; system("pause"); return 0; }