根据二叉树的中序序列+前序序列 可以唯一确定一个二叉树——数据结构课程(分治,递归)
生活随笔
收集整理的這篇文章主要介紹了
根据二叉树的中序序列+前序序列 可以唯一确定一个二叉树——数据结构课程(分治,递归)
小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.
定理:
僅根據(jù)先序、中序、后序序列中的其中一個無法唯一確定一個二叉樹。
根據(jù)二叉樹的中序序列+前序序列 或者中序序列+后序序列 可以唯一確定一個二叉樹,這里給出了構(gòu)造方法。
1 #include<cstdio>
2 #include<string.h>
3 #include<malloc.h>
4 using namespace std;
5 #define MaxSize 100
6 typedef char ElemType;
7 typedef struct node
8 {
9 ElemType data;
10 struct node* lchild;
11 struct node* rchild;
12 }BTNode;
13
14 void CreateBTree(BTNode * &b, char * str)//傳入地址b,將其作為根
15 {
16 BTNode *St[MaxSize],*p=NULL; //建立指針型數(shù)組?
17 int top=-1,k,j=0;//top為棧頂指針,k為標(biāo)記,j為字符串指針
18
19 b=NULL;//初始化樹為空
20 char ch=str[j];//j指向字符串的指針
21 while(ch!='')//掃描字符串
22 {
23 switch(ch)//判斷當(dāng)前字符
24 {
25 case '(':St[++top]=p;k=1;break;//接下來的節(jié)點為左子樹
26 case ')':--top;break;
27 case ',':k=2;break;
28 default:p=(BTNode *)malloc(sizeof(BTNode));//當(dāng)前字符為節(jié)點
29 p->data=ch;p->lchild=p->rchild=NULL;
30 if(b==NULL) b=p;//第一個節(jié)點當(dāng)做根節(jié)點
31 else
32 {
33 switch(k)
34 {
35 case 1:St[top]->lchild=p;break;
36 case 2:St[top]->rchild=p;break;
37
38 }
39 }
40
41 }
42 ch=str[++j];
43 }
44 }
45
46 void DestroyBTree(BTNode * &b)//銷毀當(dāng)前二叉樹
47 {
48 if(b!=NULL)
49 {
50 DestroyBTree(b->lchild);
51 DestroyBTree(b->rchild);
52 free(b);//遞歸釋放節(jié)點空間
53 }
54 }
55
56 void DispBTree(BTNode *b)
57 {
58 if(b!=NULL)
59 {
60 printf("%c",b->data);
61 if (b->lchild!=NULL || b->rchild!=NULL)
62 { printf("(");
63 DispBTree(b->lchild); //遞歸處理左子樹
64 if (b->rchild!=NULL) printf(","); //有右孩子結(jié)點時才輸出','
65 DispBTree(b->rchild); //遞歸處理右子樹
66 printf(")");
67 }
68 }
69 }
二叉樹的基本操作
具體思路為:(分治,遞歸)
1根據(jù)先序或者后序序列先找出當(dāng)前樹的根節(jié)點
2然后從中序序列中找到根節(jié)點所在的位置
3中序序列中,根節(jié)點之前的屬于左子樹,根節(jié)點之后的屬于右子樹
4對左子樹和右子樹所在的序列分別進(jìn)行1~3操作。
1 #include "二叉樹基本操作.cpp" //調(diào)用自己的函數(shù)庫
2 #define MaxWidth 40
3 /*函數(shù)功能:
4 根據(jù)前序和中序字符串 創(chuàng)建二叉樹,
5 輸入當(dāng)前子樹前序中序字符串的首地址
6 以及當(dāng)前子樹的節(jié)點數(shù)
7
8 */
9 BTNode *CreateBT1(char *pre ,char *in,int n)
10 {
11 BTNode *b;
12 char *p;//當(dāng)前節(jié)點指針
13 if(n<=0) return NULL;
14 b=(BTNode *)malloc(sizeof(BTNode)); //創(chuàng)建二叉樹結(jié)點*b
15 b->data=*pre;//先序序列的第一個節(jié)點即為根節(jié)點
16 for(p=in;p<in+n;p++) //在中序序列中尋找根節(jié)點的位置
17 if(*p==*pre) break;
18 int k=p-in;//左子樹的節(jié)點數(shù)
19 b->lchild=CreateBT1(pre+1,in,k);
20 b->rchild=CreateBT1(pre+k+1,p+1,n-k-1);
21
22 return b;
23 }
24 BTNode *CreateBT2(char *post,char *in,int n)
25 { BTNode *b;
26 char r,*p;
27 int k;
28 if (n<=0) return NULL;
29 r=*(post+n-1); //根結(jié)點值
30 b=(BTNode *)malloc(sizeof(BTNode)); //創(chuàng)建二叉樹結(jié)點*b
31 b->data=r;
32 for (p=in;p<in+n;p++) //在in中查找根結(jié)點
33 if (*p==r) break;
34 k=p-in; //k為根結(jié)點在in中的下標(biāo)
35 b->lchild=CreateBT2(post,in,k); //遞歸構(gòu)造左子樹
36 b->rchild=CreateBT2(post+k,p+1,n-k-1); //遞歸構(gòu)造右子樹
37 return b;
38 }
39 int main()
40 {
41 BTNode *b;
42 ElemType pre[]="ABDEHJKLMNCFGI";
43 ElemType in[]="DBJHLKMNEAFCGI";
44 ElemType post[]="DJLNMKHEBFIGCA";
45 int n=14;
46 b=CreateBT1(pre,in,n);
47 printf("先序序列:%s
",pre);
48 printf("中序序列:%s
",in);
49 printf("構(gòu)造一棵二叉樹b:
");
50 printf(" 括號表示法:");DispBTree(b);printf("
");
51 b=CreateBT2(post,in,n);
52 printf("構(gòu)造一棵二叉樹b:
");
53 printf(" 括號表示法:");DispBTree(b);printf("
");
54 DestroyBTree(b);
55 return 0;
56 }
根據(jù)(前序+中序序列)還原二叉樹
#include<stdio.h>
#include<malloc.h>
#include<cstring>
#include<iostream>
using namespace std;
typedef struct Bnode /* 定義二叉樹存儲結(jié)構(gòu)*/
{
char data;
struct Bnode *lchild,*rchild;```
} BtNode,*BTree;
BtNode *Q[100]; //隊列Q放樹結(jié)點地址
BtNode *CreatBTree()//輸入為完全二叉樹的前提下,構(gòu)建二叉樹
{
char ch ,str[20];
int front=1,rear=0;//定義隊列的頭尾指針
int i, n;
BtNode *root = NULL, *s;
gets(str);
n=strlen(str);
cout<<n<<endl;
for(i=1; i<n; i++) //結(jié)束標(biāo)志
{
s=NULL;
if (str[i]!='#') //當(dāng)前字符非空,建立節(jié)點加入隊列
{
s=(BtNode *)malloc(sizeof(BtNode)); //生成新結(jié)點
s->data=str[i];
s->lchild=NULL;
s->rchild=NULL;
}
Q[++rear]=s; //結(jié)點入隊
if (rear==1) root=s; //記錄根結(jié)點
else
{
if (s && Q[front])
{
if (rear%2==0) Q[front]->lchild=s; //左孩子入隊
else Q[front]->rchild=s; //右孩子入隊
}
if (rear%2==1) front++; //新結(jié)點是雙親的右孩子,則雙親結(jié)點出隊
}
}
return root;
}
void preorder(BTree T)//先序遍歷
{
if(T)
{
cout<<T->data<<" ";
preorder(T->lchild);
preorder(T->rchild);
}
}
void inorder(BTree T)//中序遍歷
{
if(T)
{
inorder(T->lchild);
cout<<T->data<<" ";
inorder(T->rchild);
}
}
void posorder(BTree T)//后序遍歷
{
if(T)
{
posorder(T->lchild);
posorder(T->rchild);
cout<<T->data<<" ";
}
}
int main()
{
BtNode * mytree;
mytree=CreatBTree();/*創(chuàng)建二叉樹*/
cout<<"二叉樹的先序遍歷結(jié)果:"<<endl;
preorder(mytree);//先序遍歷二叉樹
cout<<endl;
cout<<"二叉樹的中序遍歷結(jié)果:"<<endl;
inorder(mytree);//中序遍歷二叉樹
cout<<endl;
cout<<"二叉樹的后序遍歷結(jié)果:"<<endl;
posorder(mytree);//后序遍歷二叉樹
cout<<endl;
return 0;
}
遍歷
總結(jié)
以上是生活随笔為你收集整理的根据二叉树的中序序列+前序序列 可以唯一确定一个二叉树——数据结构课程(分治,递归)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Spring Bean的继承
- 下一篇: 全国首个算力交易平台在上海正式发布:整合