根據二叉樹的中序序列+前序序列 可以唯一確定一個二叉樹——數據結構課程(分治,遞歸)


 

定理:

  僅根據先序、中序、后序序列中的其中一個無法唯一確定一個二叉樹。 

  根據二叉樹的中序序列+前序序列 或者中序序列+后序序列 可以唯一確定一個二叉樹,這里給出了構造方法。

 

 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; //建立指針型數組?
17     int top=-1,k,j=0;//top為棧頂指針,k為標記,j為字符串指針 
18     
19     b=NULL;//初始化樹為空
20     char ch=str[j];//j指向字符串的指針
21     while(ch!='\0')//掃描字符串
22     {
23         switch(ch)//判斷當前字符 
24         {
25             case '(':St[++top]=p;k=1;break;//接下來的節點為左子樹 
26             case ')':--top;break;
27             case ',':k=2;break;
28             default:p=(BTNode *)malloc(sizeof(BTNode));//當前字符為節點 
29                     p->data=ch;p->lchild=p->rchild=NULL;
30                     if(b==NULL) b=p;//第一個節點當做根節點
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)//銷毀當前二叉樹
47 {
48     if(b!=NULL)
49     {
50         DestroyBTree(b->lchild);
51         DestroyBTree(b->rchild);
52         free(b);//遞歸釋放節點空間 
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(",");    //有右孩子結點時才輸出','
65             DispBTree(b->rchild);                //遞歸處理右子樹
66             printf(")");                        
67         }
68     }
69 } 
二叉樹的基本操作

具體思路為:(分治,遞歸)

  1根據先序或者后序序列先找出當前樹的根節點

  2然后從中序序列中找到根節點所在的位置

  3中序序列中,根節點之前的屬於左子樹,根節點之后的屬於右子樹

  4對左子樹和右子樹所在的序列分別進行1~3操作。

 

 1 #include "二叉樹基本操作.cpp"   //調用自己的函數庫
 2 #define MaxWidth 40
 3 /*函數功能: 
 4     根據前序和中序字符串 創建二叉樹, 
 5     輸入當前子樹前序中序字符串的首地址
 6     以及當前子樹的節點數
 7 
 8 */ 
 9 BTNode *CreateBT1(char *pre ,char *in,int n)
10 {
11     BTNode *b;
12     char *p;//當前節點指針
13     if(n<=0) return NULL;
14     b=(BTNode *)malloc(sizeof(BTNode));        //創建二叉樹結點*b
15     b->data=*pre;//先序序列的第一個節點即為根節點
16     for(p=in;p<in+n;p++) //在中序序列中尋找根節點的位置
17         if(*p==*pre) break;
18     int k=p-in;//左子樹的節點數
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);                        //根結點值
30     b=(BTNode *)malloc(sizeof(BTNode));        //創建二叉樹結點*b
31     b->data=r;
32     for (p=in;p<in+n;p++)                    //在in中查找根結點
33         if (*p==r)    break;
34     k=p-in;                                //k為根結點在in中的下標
35     b->lchild=CreateBT2(post,in,k);            //遞歸構造左子樹
36     b->rchild=CreateBT2(post+k,p+1,n-k-1);    //遞歸構造右子樹
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\n",pre);
48     printf("中序序列:%s\n",in);
49     printf("構造一棵二叉樹b:\n");
50     printf("  括號表示法:");DispBTree(b);printf("\n");
51     b=CreateBT2(post,in,n);
52     printf("構造一棵二叉樹b:\n");
53     printf(" 括號表示法:");DispBTree(b);printf("\n");
54         DestroyBTree(b);
55     return 0;
56 }  
根據(前序+中序序列)還原二叉樹

 

#include<stdio.h>
#include<malloc.h>
#include<cstring>
#include<iostream>
using namespace std;

typedef struct Bnode /*  定義二叉樹存儲結構*/  
{
    char data;
    struct Bnode *lchild,*rchild;```
} BtNode,*BTree;

BtNode *Q[100]; //隊列Q放樹結點地址

BtNode *CreatBTree()//輸入為完全二叉樹的前提下,構建二叉樹 
{
    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++)  //結束標志
    {
        s=NULL;
        if (str[i]!='#')  //當前字符非空,建立節點加入隊列 
        {
            s=(BtNode *)malloc(sizeof(BtNode)); //生成新結點
            s->data=str[i];
            s->lchild=NULL;
            s->rchild=NULL;
        }
        Q[++rear]=s;  //結點入隊
        if (rear==1) root=s; //記錄根結點
        else
        {
            if (s && Q[front])
            {
                if (rear%2==0) Q[front]->lchild=s; //左孩子入隊
                else Q[front]->rchild=s;  //右孩子入隊
            }
            if (rear%2==1)  front++; //新結點是雙親的右孩子,則雙親結點出隊
        }
    }
    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();/*創建二叉樹*/

    cout<<"二叉樹的先序遍歷結果:"<<endl;
    preorder(mytree);//先序遍歷二叉樹
    cout<<endl;
    cout<<"二叉樹的中序遍歷結果:"<<endl;
    inorder(mytree);//中序遍歷二叉樹
    cout<<endl;
    cout<<"二叉樹的后序遍歷結果:"<<endl;
    posorder(mytree);//后序遍歷二叉樹
    cout<<endl;

    return 0;
}
遍歷

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM