小白專場-是否同一顆二叉搜索樹-c語言實現

更新、更全的《數據結構與算法》的更新網站,更有python、go、人工智能教學等着你:http://www.javashuo.com/article/p-zfinzipt-hh.htmlpython

1、題意理解

給定一個插入序列就能夠惟一肯定一顆二叉搜索樹。然而,一顆給定的二叉搜索樹卻能夠由多種不一樣的插入序列獲得。例如:按照序列 {2, 1, 3} 和 {2, 3, 1}插入初始爲空的二叉搜索樹,都獲得同樣的結果。算法

問題:對於輸入的各類插入序列,你須要判斷它們是否能生成同樣的二叉搜索樹。數據結構

2、求解思路

兩個序列是否對應相同搜索樹的判別框架

  1. 分別建兩顆搜索樹的判別方法:根據兩個序列分別建樹,再判別樹是否同樣
  2. 不建樹的判別方法

  1. 建一棵樹,再判別其餘序列是否與該樹一致(本篇文章重點討論)
    1. 搜索樹表示
    2. 建搜索樹T
    3. 判別一序列是否與搜索樹T一致

3、搜索樹表示

/* c語言實現 */

typedef struct TreeNode *Tree;
struct TreeNode
{
  int v;
  Tree Left, Right;
  int flag;
}

程序框架搭建

/* c語言實現 */

int main()
{
  對每組數據;
  * 讀入N和L;
  * 根據第一行序列建樹T;
  * 依據樹T分別判別後面的L個序列是否能與T造成同一搜索樹並輸出結果;
  
  return 0;
}

int main()
{
  int N, L, i;
  Tree T;
  
  scanf("%d", &N);
  while (N) {
    scanf("%d", &L);
    T = MakeTree(N); // 讀數據建搜索樹T
    for (i=0; i<L, i++){
      if (Judge(T, N)) printf("Yes\n"); // 判別一序列是否與T構成同樣的搜索樹
      else printf("No\n");
      ResetT(T); // 清除T中的標記flag
    }
    FreeTree(T);
    scanf("%d", &N);
  }
  return 0;
}

3.1 如何建搜索樹

/* c語言實現 */

Tree MakeTree(int N)
{
  Tree T;
  int i, V;
  
  scanf("%d", &V);
  T = NewNode(V);
  for (i=1; i<N; i++){
    scanf("%d", &V);
    T = Insert(T, V); // 按照搜索樹順序插入左右結點
  }
  return T;
}

Tree Insert(Tree T, int V)
{
  if (!T) T = NewNode(V);
  else{
    if (V > T->v)
      T->Right = Insert(T->Right, V);
    else
      T->Left = Insert(T->Left, V);
  }
  return T;
}

Tree NewNode(int V)
{
  Tree T = (Tree)malloc(sizeof(struct TreeNode));
  T->v = V;
  T->Left = T->Right = NULL; // 左右子樹設置爲空
  T->flag = 0;
  return T;
}

3.2 如何判別

如何判別序列 3,2,4,1 是否與樹T一致?網站

方法:在樹T中按順序搜索序列 3,2,4,1 中的每一個數人工智能

  • 若是每次搜索所通過的結點在前面均出現過,則一致
  • 不然(某次搜索中遇到前面未出現的結點),則不一致
/* c語言實現 */

int check(Tree T, int V)
{
  if (T->flag) {
    // 若是flag爲1,則遞歸搜索子結點
    if (V < T->v) return check(T->Left, V);
    else if (V > T->v) return check(T->Right, V);
  }
  else{
    if (V == T->v){
      T->flag = 1;
      return 1;
    }
    else return 0;
  }
}

// 有bug版本的Judge方法:當發現序列中的某個樹與T不一致時,必須把序列後面的數都讀完,如序列 3,2,4,1 ,在讀取2時就會發現兩顆是不相同的搜索樹,下面這段代碼則不會繼續讀取 4,1,而是把它納入下一個序列
int Judge(Tree T, int N)
{
  int i, V;
  
  scanf("%d", &V);
  if (V != T->v) return 0;
  else T->flag = 1;
  
  for (i=1; i<N; i++){
    scanf("%d", &V);
    if (!check(T, V)) return 0;
  }
  return 1;
}

// 無bug版本的Judge方法
int Judge(Tree T, int N)
{
  int i, V, flag = 0; // flag:0表明目前還一致,1表明已經不一致
  
  scanf("%d", &V);
  if (V != T->v) flag = 1;
  else T->flag = 1;
  for (i=1; i<N; i++){
    scanf("%d", &V);
    if ((!flag) && (!check(T,V))) flag = 1;
  }
  if (flag) return 0;
  else return 1;
}

3.3 清空樹

/* c語言實現 */

// 清除T中各結點的flag標記
void ResetT(Tree T)
{
  if (T->Left) ResetT(T->Left);
  if (T->Right) ResetT(T->Right);
  T->flag = 0;
}

// 釋放T的空間
void FreeTree(Tree T)
{
  if (T->Left) FreeTree(T->Left);
  if (T->Right) FreeTree(T->Right);
  free(T);
}
相關文章
相關標籤/搜索