1. 程式人生 > >二叉樹(中序,先序,後序,層次)遍歷之間的相互轉變

二叉樹(中序,先序,後序,層次)遍歷之間的相互轉變

一.知道先序,中序求後序。

用先序知道根節點,通過中序知道根節點的左子右子。通過一次次遞迴,推出最後一個。

#include <iostream>
#include <cstring>
#define MAX 50+3
using namespace std;
typedef struct tree
{
    char data;//資料
    struct tree *lson;//左孩子
    struct tree *rson;//右孩子
}tree;      //要查詢的元素  查詢的地方    陣列的長度
int Search_Num(char num,char *array,int len)
{
    for(int i=0; i<len; i++)
       if(array[i] == num)
         return i;
    //return -1;//沒有找到
}                     //前序遍歷         中序遍歷   中序陣列長度
tree *suan(char *front,char *center,int len)
{
    if(len <= 0)
      return NULL;
    tree *temp = new tree;
    temp->data = *front;
    int index = Search_Num(*front,center,len);
    temp->lson = suan(front+1,center,index);
    temp->rson = suan(front+index+1,center+index+1,len-index-1);
    return temp;
}
void houxu(tree *root)//後序遍歷
{
    if( root != NULL)
    {
        houxu(root->lson);
        houxu(root->rson);
        cout<<root->data;
    }
}
int main()
{
    char *preorder = new char [MAX];//前序
    char *inorder  = new char [MAX];//中序
    cin>>preorder;cin>>inorder;
    tree *root = suan(preorder,inorder,strlen(inorder));
    houxu(root);
    cout<<endl;
    return 0;
}

二.知道中序,層次推出先序

1.陣列法。

#include<iostream>
#include<cstring>
using namespace std;
string s1,s2;
void calc(int l1,int r1,int l2,int r2)
{
    int i,j;
    for(i=l2;i<=r2;i++)
    {
        int b=0;
        for(j=l1;j<=r1;j++)
        {
            if(s2[i]==s1[j]) 
            {
                cout<<s1[j];
                b=1;
                break;
            }
        }
        if(b) break;
    }
    if(j>l1) calc(l1,j-1,0,r2);
    if(j<r1) calc(j+1,r1,0,r2);
}
int main()
{
    cin>>s1>>s2;
    calc(0,s1.length()-1,0,s2.length()-1);
    cout<<endl;
    return 0;
} 

2.指標建樹法.

#include<stdio.h>  
#include<string.h>  
int len,mark[102];                                                             //用來給中序遍歷做標記  
char s1[102],s2[102];                                                    //儲存遍歷  
void tree(int l,int r){                                                          //遞迴函式  
    if(l>r)return;                                                               //返回條件,不能等於  
    int i,j,min=0x7fffff/*int範圍的最大值*/,root;  
    for(i=l;i<=r;i++){  
        if(mark[s1[i]]<min){  
            min=mark[s1[i]];root=i;                                        //在中序遍歷中找到層次遍歷裡的最靠前的結點(即先序遍歷中要求優先輸出的根結點  
        }           
    }     
    printf("%c",s1[root]);                                                  //輸出根結點  
    tree(l,root-1);                                                             //先遍歷左子樹  
    tree(root+1,r);                                                              //再遍歷右子樹,順序不能調換  
}  
int main(){  
    scanf("%s%s",s1+1,s2+1);  
    len=strlen(s2+1);  
    int i;  
    for(i=1;i<=len;i++)  
        mark[s2[i]]=i;                                                             //做標記,雖然s2[i]為字元,但視為ASCII碼值,越靠前標記值越小  
    tree(1,len);      
}