資料結構與演算法實驗報告
第六次實驗
姓名:孫瑞霜
一、實驗目的
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個需要檢查的序列。
簡單起見,保證每個插入序列都是1到N的一個排列。
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;//flag:0代表目前還一致,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鍵即可執行該程式,最後測試完畢,關閉介面。