1. 程式人生 > >c/c++實現利用二叉樹的先序遍歷和中序遍歷序列重建樹

c/c++實現利用二叉樹的先序遍歷和中序遍歷序列重建樹

先序遍歷中第一個結點必然是根結點,利用該結點在中序遍歷中的位置,將樹分為左子樹和右子樹,然後遞迴重建左子樹和右子樹,程式碼如下

#include <iostream>
using namespace std;

struct Node {
  char value;
  Node* left;
  Node* right;
  Node() { };
  Node(char c, Node* l = NULL, Node* r = NULL): value(c), left(l), right(r) { }
};

Node* build(int n, char* s1, char* s2){
  //s1表示的是先序遍歷,s2表示的是中序遍歷,s3表示的是後續遍歷
  if (n <= 0)
    return NULL;
  // 分別求左右子樹的大小
  int leftn = strchr(s2, s1[0]) - s2;
  int rightn = n - leftn - 1; //到這裡為止,起始可以加兩條二層的for迴圈判斷是否可以重建子樹,原理是左(右)子樹的所有結點在先序和後序中相同,次序可以不一
  //重建左子樹
  Node* root = new Node(s1[0]);
  root->left = build(leftn, s1+1, s2);
  //重建右子樹
  root->right = build(rightn, s1 + 1 + leftn, s2 + 1 + leftn);
  return root;
}

//用前序遍歷測試二叉樹是否重新建立
void PreOrder (Node* root) {
  if (root) {
    printf("%c", root->value);
    PreOrder(root->left);
    PreOrder(root->right);
  }
}

//用中序遍歷測試二叉樹是否重新建立
void InOrder (Node* root) {
  if (root) {
    InOrder(root->left);
    printf("%c", root->value);
    InOrder(root->right);
  }
}

//用後續遍歷測試二叉樹是否重新建立
void PostOrder (Node* root) {
  if (root) {
    PostOrder(root->left);
    PostOrder(root->right);
    printf("%c", root->value);
  }
}
int main() {
  char s1[100], s2[100];
  while (scanf("%s%s", s1, s2) == 2) {
    int n = strlen(s1);
    Node* root = build(n, s1, s2);
    printf("前序遍歷序列為: ");
    PreOrder(root);
    printf("\n");

    printf("中序遍歷序列為: ");
    InOrder(root);
    printf("\n");

    printf("後序遍歷序列為: ");
    PostOrder(root);
    printf("\n");
  }
  return 0;
}