資料結構實驗六是否同一顆二叉樹

孫瑞霜發表於2020-05-21

資料結構與演算法實驗報告

次實驗

 姓名:孫瑞霜 

 

一、實驗目的

1、熟練掌握學習的每種結構及其相應演算法;

2、理論聯絡實際,會對現實問題建模並設計相應演算法。

3、優化演算法,使得演算法效率適當提高

二、實驗要求

1. 認真閱讀和掌握教材上和本實驗相關內容和演算法;

2. 上機將各種相關演算法實現;

3實現上面實驗目的要求的功能,並能進行簡單的驗證

、實驗內容

認真學習 學習通->資料結構->資料->資料結構實驗指導書--陳越版,從第二章進階實驗1~10中任選一個來實現,編寫程式,輸入給定的資料,能得到給定的輸出。總結演算法思想、畫出流程圖,並思考程式有無改進空間,如何改進。

三、演算法描述

我選擇的是資料結構實驗指導書中的第二章進階中的第六個實驗:是否同一顆二叉樹。我需要完成的操作是:

1、建立一個二叉樹:給定一個插入序列就可以唯一確定一棵二叉樹。然而,一棵給定的二叉樹卻可以由多種不同的插入序列得到。例如分別按照序列{2, 1, 3}{2, 3, 1}插入初始為空的二叉樹,都得到一樣的結果。於是對於輸入的各種插入序列,需要判斷它們是否能生成一樣的二叉樹。

2、輸入包含若干組測試資料。每組資料的第1行給出兩個正整數N (10)L,分別是每個序列插入元素的個數和需要檢查的序列個數。第2行給出N個以空格分隔的正整數,作為初始插入序列。最後L行,每行給出N個插入的元素,屬於L個需要檢查的序列。

 

簡單起見,保證每個插入序列都是1N的一個排列。

3、對每一組需要檢查的序列,如果其生成的二叉樹跟對應的初始序列生成的一樣,輸出“其生成的二叉樹跟對應的初始序列生成的一樣”,否則輸出“其生成的二叉樹跟對應的初始序列生成的不一樣”。

四、詳細設計

 

 

 

 

五、程式程式碼

#include <stdio.h>

#include <stdlib.h>

#include <unistd.h>

  

   typedef struct TreeNode *BinTree; //二叉樹型別  

   struct TreeNode {

       int Data;  //結點資料

      BinTree Left;  //指向左子樹

       BinTree Right;   //指向右子樹

      int Flag;   //定義結點的標誌

  };  

 /*樹結點的插入*/

  BinTree Insert(int X, BinTree BST)

  {

      if(!BST) {         //若樹為空,則生成並返回一 個節點的二叉樹

          BST = (BinTree)malloc(sizeof(struct TreeNode));

          BST->Data = X;

          BST->Left = BST->Right = NULL;

          BST->Flag = 0;

     } else {       //開始找到要插入的節點

          if(X < BST->Data)

              BST->Left = Insert(X, BST->Left);//遞迴插入左子樹

 

          else if(X > BST->Data)

              BST->Right = Insert(X, BST->Right);//遞迴插入右子樹

 

      }

       //如果元素X已存在,則什麼都不做

      return BST;

  }

  /*建立樹:輸入資料,將它加在樹上*/

  BinTree MakeTree(int num)

  {

      BinTree S = NULL;

     int i, data;

      for(i=0;i<num;i++) {

          scanf("%d", &data);

          S = Insert(data, S);

      }

      return S;

  }

  /*清除T的各結點的flag標記*/

  void ResetT(BinTree S)

  {

      if(S->Left) ResetT(S->Left);

      if(S->Right) ResetT(S->Right);

      S->Flag = 0;

  }

  /*釋放S的空間*/

  void FreeTree(BinTree S)

  {

      if(S->Left) FreeTree(S->Left);

      if(S->Right) FreeTree(S->Right);

      free(S);

  }

  

  void InOrderTraversal(BinTree BT)  //中序遍歷

  {

      if(BT) {

          InOrderTraversal(BT->Left);//指向左子樹

          printf("%d ", BT->Data);

          InOrderTraversal(BT->Right);//指向右子樹

      }

  }

  /*檢查函式*/

  int Check(BinTree T, int data)  

  {

      if(T->Flag) {

          if(data < T->Data)

             return Check(T->Left, data);

          else if(data > T->Data)

              return Check(T->Right, data);

          else

              return 0;                   /* 是否錯誤 */

      } else {

          if(data == T->Data) {

              T->Flag = 1;

              return 1;

         } else

              return 0;

      }

  }

  /*判別函式*/

  int Judge(BinTree T, int N)

  {

      int i, data, flag = 0;//flag0代表目前還一致,1代表已經不一致

      scanf("%d", &data);

      if(data != T->Data)

          flag = 1;

      else

          T->Flag = 1;

  

      for(i=1;i<N;i++) {

          scanf("%d", &data);

          if((!flag)&&(!Check(T, data)))

              flag = 1;

      }

      if(flag)

          return 0;

      else

         return 1;

  }

 

 int main()//主函式

 {

     int N, L;

     int i, j, data;

    BinTree SourceTree, CompareTree;

    while(1) {

         scanf("%d", &N);

         if(!N) break;

         scanf("%d", &L);

         SourceTree = MakeTree(N);

         //printf("InOrder:");

         // InOrderTraversal(SourceTree);

         // printf("\n");

         for(i=0;i<L;i++) {

             if(Judge(SourceTree, N))

                 printf("其生成的二叉樹跟對應的初始序列生成的一樣\n");

             else

                 printf("其生成的二叉樹跟對應的初始序列生成的不一樣\n");

             ResetT(SourceTree);//清除T的標記flag

         }

         FreeTree(SourceTree);//釋放結點空間

     }

     return 0;

 }

六、測試和結果

 

 

 

七、使用者手冊

開啟devC++,新建一個源程式,拷貝5部分的程式碼進去,點選執行,在出現的介面中按照提示輸入資料一步步按下Enter鍵即可執行該程式,最後測試完畢,關閉介面

 

相關文章