當前位置:首頁 » 軟體設計 » 數據結構課程設計報告

數據結構課程設計報告

發布時間: 2020-12-02 19:03:39

① 求一份數據結構課程設計報告

//class CNode.h
#ifndef __CNODE_H__
#define __CNODE_H__

#include <iostream>
using namespace std;
struct stData //出生年月結構
{
int m_nYear;
int m_nMonth;
int m_nDay;
};

struct stResult //五門課成績結構
{
double m_dSubject_1; //自己改成績的名稱
double m_dSubject_2;
double m_dSubject_3;
double m_dSubject_4;
double m_dSubject_5;
};

struct stStudent //聲明學生信息的結構
{
string m_strNumber; //學生學號
string m_strName; //姓名
char m_chSex; //性別
struct stData m_stData; //出生年月
string m_strAppearance; //政治面貌
struct stResult m_stResult; //五門課成績
};

typedef class CNode
{
private:
struct stStudent m_stStudent;
CNode* m_Next;
public:
CNode(); //構造函數
~CNode(); //析構函數
void SetNodeData(); //設置結點內容的函數成員
stStudent GetNodeData(); //獲取結點內容的函數成員
void SetNodeNext(CNode* _Next); //設置結點Next指針的函數成員
void ShowNodeData(); //輸出結點內容的函數成員
CNode* GetNodeNext(); //獲取結點Next指針的函數成員
}LinkNode;

#endif

//class CLinkList
#ifndef __CLINKLIST_H__
#define __CLINKLIST_H__

#include "CNode.h"

typedef class CLinkList
{
private:
LinkNode* m_Head; //鏈表的頭指針
LinkNode m_Node; //鏈表的頭結點
public:
CLinkList(); //構造函數
~CLinkList(); //析構函數
void CreateList(); //初始化鏈表的函數成員
LinkNode* GetListNode(int _nIndex); //按位置查找指定位結點的成員函數
void InsertList(int _nIndex); //插入結點的成員函數
void DeleteList(int _nIndex); //刪除某一結點的成員函數
LinkNode* GetHeadList(); //獲取頭指針的成員函數
void SetListData(int _nIndex); //設置鏈表中某一結點的值的成員函數
void ShowListData(int _nIndex); //這個是現實鏈表中某一結點值的函數成員
void DestroyList(int _nIndex); //銷毀某一位置以後鏈表的成員函數
void ShowList(); //顯示鏈表的成員函數
}LinkList;

#endif

//class CLinkList

#include "CLinkList.h"
#include "CNode.h"

CLinkList::CLinkList()
{
cout << "這個是構造函數"<< endl;

m_Head = &m_Node; //鏈表的頭指針指向頭結點
m_Node.SetNodeNext(NULL); //將頭結點的Next指針設置為NULL;
}

CLinkList::~CLinkList()
{
cout << "這個是析構函數" << endl;
}

void CLinkList::CreateList() //以向後追加的方式創建一個鏈表,輸入0退出
{
int nTemp = 0; //定義一個臨時變數用於標志程序結束
cout << "歡迎來創建鏈表 !" << endl;
CNode * pTemp = NULL; //定義一個臨時結點指針,用來增加新結點用
CNode * pNode = m_Head; //定義一個標記指針,首先叫其指向頭結點

while(1)
{
pTemp = new LinkNode;

cout << "請輸入下一個結點的內容!" << endl;
pTemp->SetNodeData(); //設置鏈表中結點的內容

cout << "如果想繼續輸入下一個學生的信息請輸入 1,否則輸入 0" << endl;
cin >> nTemp;
if ('0' == nTemp)
{
break;
}
pNode->SetNodeNext(pTemp); //讓鏈尾的Next指向新建的結點
pNode = pTemp; //將結尾元素向後移
}
cout << "創建鏈表結束" << endl;
}

LinkNode* CLinkList::GetListNode(int _nIndex)
{
cout << "這個是按位置查找指定位結點的成員函數" << endl;

LinkNode* pNode = m_Head->GetNodeNext(); //定義一個臨時的結點指針,初始化指向頭結點
int Temp = 0; //定義一個臨時的變數,用來標記已檢查結點的個數的

if(-1 == _nIndex) //返回頭結點(即頭指針)
{
return m_Head;
}

if(_nIndex < -1) //_nIndex控制條件
{
cout << "您輸入的是錯誤的位置!" << endl;
return 0;
}

while(pNode != NULL)
{
if(_nIndex == Temp)
{
return pNode;
}
pNode = pNode->GetNodeNext(); //臨時結點向後移動
++Temp;
}

return pNode; //沒找到結點就返回NULL

}

void CLinkList::ShowListData(int _nIndex);

void CLinkList::InsertList(int _nIndex) //插入結點的函數成員
{
cout << "這個是插入結點的成員函數" << endl;

LinkNode* pNode = GetListNode(_nIndex - 1); //定義一個結點類的指針,指向的是要插入位置的前一指針

LinkNode* pTemp = new CNode; //定義一個臨時結點指針,用來增加新結點用

pTemp->SetNodeData(); //設置插入結點的內容

pTemp->SetNodeNext(pNode->GetNodeNext());
pNode->SetNodeNext(pTemp);
}

void CLinkList::DeleteList(int _nIndex)
{
cout << "這個是刪除某一結點的成員函數" << endl;

LinkNode* pNode = GetListNode(_nIndex - 1); //定義一個結點類的指針,指向的是要刪除位置的前一指針
LinkNode* pTemp = NULL; //定義一個臨時結點指針,用來指向要刪除的結點

pTemp =pNode->GetNodeNext(); //把pTemp指向要刪除的結點

pNode->SetNodeNext(pTemp->GetNodeNext()); //把pNode指向要刪除的結點的後一個結點

delete pTemp; //刪除結點
pTemp = NULL;
}

LinkNode* CLinkList::GetHeadList()
{
cout << "這個是獲取頭指針的成員函數" << endl;

return m_Head;
}

void CLinkList::SetListData(int _nIndex)
{
cout << "這個是設置鏈表中某一結點的值的成員函數" << endl;

CNode *pNode = GetListNode(_nIndex); //定義一個結點類的指針,指向的是要修改內容位置的結點

pNode->SetNodeData(); //修改內容

}

void CLinkList::ShowListData(int _nIndex)
{
cout << "這個是顯示鏈表中某一結點值的成員函數" << endl;

CNode *pNode = GetListNode(_nIndex); //定義一個結點類的指針,指向的是要獲取內容位置的結點

pNode->ShowNodeData(); //返回想要得到位置的結點內容
}

void CLinkList::DestroyList(int _nIndex)
{
cout << "這個是銷毀某一位置以後鏈表的成員函數" << endl;

LinkNode* pTemp = GetListNode(_nIndex - 1); //定義一個結點指針,指向要銷毀位置的前一結點
LinkNode* pNode = pTemp->GetNodeNext(); //定義一個結點指針,指向要銷毀位置的結點

while(pTemp->GetNodeNext() != NULL) //銷毀動作的結束條件或初始條件
{
pTemp->SetNodeNext(pNode->GetNodeNext()); //把需要銷毀的位置的前結點的Next指向銷毀位置的下一個結點
delete pNode; //銷毀結點

pNode = pTemp->GetNodeNext(); //把pNode重新指向要銷毀位置的結點
}
}

void CLinkList::ShowList()
{
cout << "這個是顯示鏈表的成員函數" << endl;

int nTemp = 0; //定義一個臨時的整形變數用來控制輸入的個數

LinkNode* pTemp = m_Head->GetNodeNext(); //定義一個結點類指針,指向第0位的結點
if(NULL == pTemp)
{
cout << "這是個空鏈" << endl;
}

while(pTemp != NULL)
{
pTemp->ShowNodeData();

++nTemp;
if(0 == nTemp % 5 && nTemp != 0) //控制每行只能輸出5個結點的內容
{
cout << endl;
}

pTemp = pTemp->GetNodeNext();
}
}

//class CNode
#include "CNode.h"

CNode::CNode() //構造函數
{
//m_stStudent = {0};
m_Next = NULL;
}

CNode::~CNode() //析構函數
{
}

void CNode::SetNodeData()
{
char* pNumber = new char[30]; //用來接收字元串的臨時變數
char* pName = new char[30];
char* pAppearance = new char[30];

cout << "學生學號: " << endl;
cin >> pNumber;
m_stStudent.m_strNumber = pNumber;
cout << "姓名: " << endl;
cin >> pName;
m_stStudent.m_strName = pName;
cout << "性別: " << endl;
cin >> m_stStudent.m_chSex;
cout << "出生年月: " << endl;
cout << "m_stData.m_nYear" << endl;
cin >> m_stStudent.m_stData.m_nYear;
cout << "m_stData.m_nMonth" << endl;
cin >> m_stStudent.m_stData.m_nMonth;
cout << "m_stData.m_nDay" << endl;
cin >> m_stStudent.m_stData.m_nDay;
cout << "政治面貌: " << endl;
cin >> pAppearance;
m_stStudent.m_strAppearance = pAppearance;
cout << "五門課成績: " << endl;
cout << "m_dSubject_1: " << endl;
cin >> m_stStudent.m_stResult.m_dSubject_1;
cout << "m_dSubject_2: " << endl;
cin >> m_stStudent.m_stResult.m_dSubject_2;
cout << "m_dSubject_3: " << endl;
cin >> m_stStudent.m_stResult.m_dSubject_3;
cout << "m_dSubject_4: " << endl;
cin >> m_stStudent.m_stResult.m_dSubject_4;
cout << "m_dSubject_5: " << endl;
cin >> m_stStudent.m_stResult.m_dSubject_5;

delete []pNumber; //釋放內存
pNumber = NULL; //指針置空

delete []pName; //釋放內存
pName = NULL;

delete []pAppearance; //釋放內存
pAppearance = NULL;
}

stStudent CNode::GetNodeData() //返回結點內容(即學生信息)
{
return m_stStudent;
}

void CNode::SetNodeNext(CNode* _Next)
{
m_Next = _Next;
}

void CNode::ShowNodeData()
{
const char* pNumber = m_stStudent.m_strNumber.c_str(); //用來接收字元串的臨時變數
const char* pName = m_stStudent.m_strNumber.c_str();
const char* pAppearance = m_stStudent.m_strAppearance.c_str();

cout << "學生學號: " << pNumber << '\t' << "姓名: " << pName << '\t' << "性別: " << m_stStudent.m_chSex;
cout << "出生年月: " << m_stStudent.m_stData.m_nYear << ',' << m_stStudent.m_stData.m_nMonth << ',' << m_stStudent.m_stData.m_nDay;
cout << "政治面貌: " << pAppearance << "五門課成績: " << endl;
cout << "m_dSubject_1: "<< m_stStudent.m_stResult.m_dSubject_1<< endl;
cout << "m_dSubject_2: "<< m_stStudent.m_stResult.m_dSubject_2<< endl;
cout << "m_dSubject_3: "<< m_stStudent.m_stResult.m_dSubject_3<< endl;
cout << "m_dSubject_4: "<< m_stStudent.m_stResult.m_dSubject_4<< endl;
cout << "m_dSubject_5: "<< m_stStudent.m_stResult.m_dSubject_5<< endl;

}

CNode* CNode::GetNodeNext()
{
return m_Next;
}

#include "CLinkList.h"
#include "CNode.h"

void Text(); //測試函數聲明

int main()
{
cout << "這是mian函數" << endl;
Text();
return 0;
}

void Text()
{
cout << "這個是測試函數" << endl;

LinkList* pList = new LinkList; //創建一個內存鏈表對象

cout << "------------------CreateList-----------------------------" << endl;
pList->CreateList(); //初始化鏈表的函數成員
pList->ShowList();
cout << endl;

cout << "------------------GetListNode-----------------------------" << endl;
LinkNode* pNode = NULL; //定義一個臨時的結點類指針用於檢測查找函數成員
pNode = pList->GetListNode(3); //按位置查找指定位結點的成員函數的測試

if(pNode)
{
cout << "用按位置查找的方法找到了指定位結點" << endl;
}
else
{
cout << "對不起,用按位置查找的方沒有找到指定位結點" << endl;
}
cout << endl;

cout << "------------------InsertList-----------------------------" << endl;
pList->InsertList(0); //插入結點的成員函數的測試
pList->ShowList();
cout << endl;

cout << "------------------DeleteList-----------------------------" << endl;
pList->DeleteList(0); //刪除某一結點的成員函數的測試
pList->ShowList();
cout << endl;

cout << "------------------GetHeadList-----------------------------" << endl;
pNode = NULL;
pNode = pList->GetHeadList(); //獲取頭指針的成員函數的測試
if(pNode)
{
cout << "已經返回了頭指針" << endl;
}
else
{
cout << "對不起,頭指針為空" << endl;
}
cout << endl;

cout << "------------------GetHeadList-----------------------------" << endl;
pList->SetListData(3); //設置鏈表中某一結點的值的成員函數的測試
pList->ShowList();
cout << endl;

cout << "------------------GetListData-----------------------------" << endl;
cout << "pList->ShowListData(3) =";
pList->ShowListData(3); //獲取鏈中某一結點值的成員函數的測試
cout << endl;

cout << "------------------DestroyList(3)-----------------------------" << endl;
pList->DestroyList(3); //銷毀第3位置以後鏈表的成員函數的測試
pList->ShowList();
cout << endl;

cout << "------------------DestroyList(0)-----------------------------" << endl;
pList->DestroyList(0); //銷毀第0位置以後鏈表的成員函數的測試
pList->ShowList();
cout << endl;

delete pList; //釋放內存
pList = NULL; //指針置空

}

你的要求太多 , 沒仔細看, 我把我給別人寫的賦值給你吧 , 我已經寫的很全了,程序有問題可以給我留言

② 求一份數據結構課設報告(C語言):個人課程表 設計要求:1.建立個人課程表信息

可以幫你寫一個


③ 數據結構課程設計分析報告

這個我也提問過 就是沒人給回復。。。祝樓主好運吧

④ 數據結構課程設計報告 樹的遍歷:文件目錄結構的顯示

數據結構課程設計報告

樹的遍歷:文件目錄結構顯示

專業 計算機科學與技術(軟體工程)
學生姓名 施利華
班級 M計算機101
學號 0751401208
指導教師 吳 素 芹
起止日期 2012.1.7-2012.1.14

目 錄
1 簡介 1
2演算法說明 2
3測試結果 3
4分析與探討 6
5小結 8
參考文獻 9
附錄 10
附錄1 源程序清單 10

樹的遍歷:文件目錄結構的顯示
1 簡介
1. 樹形結構
樹形結構是一類十分重要的非線性結構,它可以很好地描述客觀世界中廣泛存在的具有分支關系或層次特性的對象,如操作系統的文件構成、人工智慧搜索演算法的模型表示以及資料庫系統的信息組織形式等。

2.輸入要求:
輸入數據包含幾個測試案例。每一個案例由幾行組成,每一行都代表了目錄樹的層次結構。第一行代表了目錄的根節點。若是目錄節點,那麼它的孩子節點將在第二行中被列出,同時用一對圓括弧「()」界定。同樣,如果這些孩子節點中某一個也是目錄的話,那麼這個目錄所包含的內容將在隨後的一行中列出,由一對圓括弧將首尾界定。目錄的輸入格式為:*name size,文件的輸入格式為:name size,其中*代表當前節點是目錄,表示文件或目錄的名稱,由一串長度不大於10的字元組成,並且name字元串中不能含有『(』,『),』[『,』]『和』*『。size是該文件/目錄的大小,為一個大於0的整數。每一個案例中最多隻能包含10層,每一層最多有10個文件/目錄。
3.輸出要求:
對每一個測試案例,輸出時要求:第d層的文件/目錄名前需要插入8*d個空格,兄弟節點之間要在同一列上。不要使用Tab(製表符)來統一輸出的縮進。每一個目錄的大小(size)是它所包含的所有子目錄和文件大小以及它自身大小的總和。
4.輸入例子:
*/usr1
(*mark1*alex1)
(hw.c3*course1)(hw.c5)
(aa.txt12)
*/usr1
()
表示有兩個不同的根目錄,目錄名都是/usr,第一個根目錄/usr下包含mark和alex兩個子目錄,mark目錄下包含大小為3的文件hw.c和子目錄course,alex目錄下有一個大小為5的文件hw.c,子目錄course下包含文件aa.txt,其大小為12;第二個根目錄/usr下為空。
5.輸出例子:
|_*/usr[24]
|_*mark[17]
| |_hw.s[3]
| |_*course[13]
| |_aa.txt[12]
|_*alex[6]
|_hw.c[5]
|_*/usr[1]
2演算法說明
typedef struct TreeNode{
int data;
TreeNode *left;
TreeNode *right;
}TreeNode,*Tree;
先序:
void first(Tree *root)
{
printf("%d ",root->data);
first(root->left);
first(root->right);
}
中序:
void mid(Tree *root)
{
mid(root->left);
printf("%d ",root->data);
mid(root->right);
}
後序:
void last(Tree *root)
{
last(root->left);
last(root->right);
printf("%d ",root->data);
}
3測試結果
將代碼打入Microsoft Visual C++ 6.0軟體中,改完相關錯誤後運行代碼,開始不能出現正確的運行結果,在相關文件中新建文本文件,文件命名為」input.txt「。在文本文件中,打入輸入數據,得出下列截圖。

圖3-1 輸入數據
得出」input.txt」記事後,重新運行代碼,在相關文件夾的「output.txt」會出現相關的正確的輸出結果,此時得出下列兩張截圖。

圖3-2 輸出結果

圖3-3 輸出結果
輸入正確的代碼後運行程序,得出下列截圖。

圖3-4 運行結果

4分析與探討
目錄結構是一種典型的樹形結構,為了方便對目錄的查找,遍歷等操作,可以選擇孩子兄弟雙親鏈表來存儲數的結構。程序中要求對目錄的大小進行重新計算,根據用戶的輸入來建立相應的孩子兄弟雙親鏈表,最後輸入樹形結構。可以引入一個Tree類,將樹的構造,銷毀,目錄大小的重新計算(reSize),建立樹形鏈表結構(parse),樹形結構輸出(outPut)等一系列操作都封裝起來,同時對於每一個樹的借點,它的私有變數除了名稱(Name),大小(Size)和層數(Depth)之外,根據孩子兄弟雙親鏈表表示的需要,還要設置三個指針,即父指針(Tree*parent),下一個兄弟指針(Tree*NextSibling)和第一個孩子指針(Tree*Firstchild)。下面是幾個主要函數的實現。
1.建立樹形鏈表結構的函數parse()
根據輸入來確定樹形關系是,首先讀取根借點目錄/文件名和大小值,並根據這些信息建立一個新的節點;然後讀入後面的各行信息,對於同一括弧中的內容,即具有相同父節點的那些節點建立兄弟關聯。這個函數實際上是採用層數遍歷建立樹形鏈表結構。
定義一個Tree*類型的數組treeArray[ ],用來存放目錄的節點信息,並定義兩個整型變數head和rear,head值用來標記當前節點的父節點位置,每處理完一對括弧,head需要增加1,即下一對待處理括弧的父節點在treeArray[ ]中要往後移一個位置。如果當前處理的節點是目錄類型,則將它放在treeArray[ ]數組中,rear是treeArray[ ]的下標變數,加入一個樹的節點,並和head所指的父節點建立關聯,但是不用放入treeArray[ ]中。
2.目錄大小重新計算函數reSize()
輸入數據中對目錄大小的初始化值一般為1,而目錄的真正大小應該是自身的大小和它包含的所有文件及子目錄的大小之和。因此,在計算目錄大小的時候,需要遍歷它下面所有的文件和子目錄,可以採用遞歸嵌套的後序遍歷方式。另外要注意,採用孩子兄弟雙親鏈表表示時,父目錄下的所有子目錄和子文件都在該父目錄的左子樹上(右字數第一個節點是該目錄的兄弟節點),所以遍歷的時候只需要遍歷目錄的左字數即可。
3.輸出樹形結構的函數outPut()
輸出是一個線序遍歷的過程。為完成對樹形的輸出,兄弟目錄之前需要相同的縮進,用』|』上下相連,而斧子目錄或父目錄和子文件之間需要設定正確的縮進,子目錄或子文件要比父目錄向右縮進8個空格。設置一個標志數組flag[11](每個目錄下最大層次數為10),當前Tree*temp指針所指的節點如果有兄弟節點,則置flag數組值為1,否則置為0;並由此節點反復查詢它的祖先節點的情況,知道根節點位置。輸出時,遇到flag[ ]=1時,屏幕輸出「| 」,表明是兄弟節點;遇到flag[ ]=0時則輸出「 」,這樣就可以保證兄弟節點之間有相同的縮進,而子節點總比父節點享有縮進8個空格。

treeArray[]

4.消除輸入總多餘空格的函數skipwhiteSpace(string&s,int*i)
從用戶輸入數據中讀入一行後,調用該函數來跳過s字元串中s[i]之後的空格,以方便後面的處理。
此外,關於讀入目錄名稱,大小,以及將string類型的Size值轉換成int類型的函數的實現,相對比較簡單,此外不再贅述。

圖4-1 數據異常測試案例

5小結

參考文獻
[1] 劉振安,劉燕君.C程序設計課程設計[M].[北京]機械工業出版社,2004年9月
[2] 譚浩強.C程序設計(第三版).清華大學出版社,2005年7月
[3] 嚴蔚敏,吳偉民.數據結構(C語言版).清華大學出版社,1997年4月
[4]吳文虎.程序設計基礎.清華大學出版社,2003年
[5]王立柱.C/C++與數據結構.清華大學出版社,2002年
[6]顧元剛.數據結構簡明教程.東南大學出版社,2003年
[7]郭福順,王曉芬,李蓮治.數據結構(修訂本).大連理工大學出版社,1997年
[8]嚴蔚敏,陳文博.數據結構及應用演算法教程.清華大學出版社,2004年

附錄
附錄1 源程序清單
#include <string>
#include <iostream>
#include <fstream>
using namespace std;

string s = "";
int startPos = 0;
ofstream outfile;
ifstream infile;

/**構造Tree類**/
class Tree{
string Name; /* 樹的根結點名稱 */
int Size; /* 樹的大小,用於統計這棵樹本身及其包含的所以子樹大小的總和*/
Tree* FirstChild; /* 指向它的第一個孩子結點 */
Tree* NextSibling; /* 指向它的下一個兄弟結點 */
Tree* parent; /* 指向雙親結點 */

public:
Tree(string Name = "", int Size = 0);/* 構造函數 */
void parse(); /* 根據輸入數據來建立樹形結構 */
void reSize(); /* 重新統計樹結點的大小 */
void outPut(); /* 輸出樹形結構 */
~Tree(); /* 析構函數 */
};

/*** 樹結點數組treeArray[],以及用來標注雙親結點位置的head和目錄結點的rear***/
Tree* treeArray[100];
int head = 0, rear = 0;

/*** 建立只有一個結點的樹,其三個指針域均為空 ***/
Tree::Tree(string Name, int Size){
this->Name = Name;
this->Size = Size;
FirstChild = NULL;
NextSibling = NULL;
parent = NULL;
}

/*** 析構函數,刪除同一根結點下的各個子結點,釋放空間 ***/
Tree::~Tree()
{
Tree* temp;
Tree* temp1;
temp = FirstChild;
while(temp != NULL)
{
temp1 = temp;
temp = temp->NextSibling;
delete temp1;
}
}

/* 先序遍歷根結點下的所有結點,將每一個結點的Size值都加到根結點的Size中去**/
void Tree::reSize()
{
Tree* temp = this;

/*** 如果當前的結點沒有孩子結點,則它的Size值不變,即為輸入時候的值 ***/
if(temp->FirstChild != 0){
temp = temp->FirstChild;
while(temp != 0){
temp->reSize();
Size += temp->Size;
temp = temp->NextSibling;
}
}
}

/***檢查Name中有無非法字元**************/
bool checkName(string s)
{
if(s[0]!='*' && s.length() > 10)
return false;
if(s[0]=='*' && s.length() > 11)
return false;
if(s[0]!='*' && (s[0]=='(' || s[0]==')' || s[0]=='[' || s[0]==']'))
return false;
for(int i=1;i<s.length();i++){
if(s[i]=='*' || s[i]=='(' || s[i]==')' || s[i]=='[' || s[i]==']')
return false;
}
return true;
}

/*** 按照先序遍歷的方式有縮進地來輸出樹形結構 ***/
void Tree::outPut()
{
Tree* temp; /*用來指向當前結點的祖先結點*/
Tree* temp1;
bool flag[11];/*用來標志輸出縮進、層次情況的數組*/
int i;

outfile.open("output.txt",ios::app);
if(!outfile){
cout<<"cannot append the output file.\n";
exit(0);
}
if(!checkName(Name)){
cout<<"input error!--"<<Name<<endl;
exit(0);
}
outfile<<"|_"<<Name<<"["<<Size<<"]\n";
outfile.close();

/* 輸出當前的結點信息 */
temp1= FirstChild;/* 用來指向當前結點的子結點 */

while(temp1 != NULL)
{
outfile.open("output.txt",ios::app);
if(!outfile){
cout<<"cannot append the output file.\n";
exit(0);
}

i = 0;
temp = temp1;
while(temp->parent != NULL)
{
/*當前temp指針所指的結點如果有兄弟結點,則置flag數組值為1,否則置為0;並由此結點反復查詢它的祖先結點的情況,直到根結點為止*/
if(i>=10){
//檢查當前的父目錄包含的子文件(或目錄數)是否大於10;
cout<<"input error!--dictionary contains more than 10 levels."<<endl;
exit(0);
}
temp = temp->parent;
if(temp->NextSibling != NULL)
flag[i++] = true;
else
flag[i++] = false;
}
/*兄弟結點之間有相同的縮進,子結點比父結點向右縮進8個空格*/
while(i--)
{
if(flag[i] == true)
outfile<<"| ";
else
outfile<<" ";
}
outfile.close();
temp1->outPut();
temp1 = temp1->NextSibling;
}
}

/*** 跳過字元串s中,第(*i)個之後多餘的空格 ***/
void skipWhiteSpace(string& s, int* i)
{
while(s[*i] == '\t' || s[*i] == ' ')
(*i)++;
}

/*** 獲取輸入行中一對'()'之間的字元串,即為同一雙親結點下的子結點 ***/
string getSubDir(string& line, int* startPos)
{
string res = "";
skipWhiteSpace(line,startPos);
while(line[*startPos] != ')')
res += line[(*startPos)++];
res += line[(*startPos)++];
skipWhiteSpace(line, startPos);
return res;
}

/*** 由於用戶輸入時候目錄的大小Size值為String類型,因此需要將它轉變成integer類型***/
int stringToNum(string s)
{
int num = 0;
unsigned int i = 0;
while(i < s.length())
{
num *= 10;
num += s[i++] - '0';
}

return num;
}

/*** 提取目錄/文件的名稱 ***/
string getName(string& s, int* i)
{
string name = "";
while(s[*i] != ' ' && s[*i] != '\t')
name += s[(*i)++];
return name;
}

/*** 提取目錄/文件的大小,然後將string類型轉換成integer類型 ***/
int getSize(string&s, int* i)
{
string size = "";
while((unsigned int)(*i) < s.length() && s[*i] != ' ' && s[*i] != '\t' && s [*i] != ')')
size += s[(*i)++];
return stringToNum(size);
}

/*** 根據用戶的輸入字元串來構建樹的結構 ***/
void Tree::parse()
{
Tree* temp;
string line;
string name;
int size;

/***head值用來標記當前結點的雙親結點位置;如果當前處理的結點是目錄類型,則將它放在treeArray[]數組中,下標用rear來記錄;如果是文件類型的目錄,只需要按照name和size建立一個樹的結點,但是不用放入treeArray[]中 ***/
while(getline(infile,line,'\n'))
{
startPos = 0;
while(1)
{
s = getSubDir(line, &startPos);
int i = 1;
skipWhiteSpace(s, &i);
if(s[i] != ')')
{
skipWhiteSpace(s,&i);
name = getName(s,&i);
skipWhiteSpace(s,&i);
size = getSize(s,&i);
temp = treeArray[head%100]->FirstChild = new Tree(name,size);
temp->parent = treeArray[head%100];
if(name[0] == '*')
treeArray[(rear++)%100] = temp;
skipWhiteSpace(s,&i);
}
while(s[i] != ')')
{
skipWhiteSpace(s,&i);
name = getName(s,&i);
skipWhiteSpace(s,&i);
size = getSize(s,&i);
temp->NextSibling = new Tree(name,size);
skipWhiteSpace(s,&i);
temp = temp->NextSibling;
temp->parent = treeArray[head%100];
if(name[0] == '*')
treeArray[(rear++)%100] = temp;
}
head ++;
/***測試是否一行掃描完畢***/
if((unsigned int)startPos >= line.length())
break;
}
/***只有一個根結點的情況***/
if(head == rear)
break;
}
}

///////////////////////////////////////////////////////////
//**** 主測試文件main.cpp******/////
//////////////////////////////////////////////////////////
int main()
{
Tree* fileTree;
string s;
string name;
int size;

outfile.open("output.txt");
if(!outfile){
cout<<"cannot open the output file!\n";
exit(0);
}

outfile<<"The result is as follows:\n";
outfile.close();

infile.open("input.txt",ios::out);
if(!infile){
cout<<"cannot open the input file!\n";
exit(0);
}

while(getline(infile,s,'\n'))
{
int i = 0;
skipWhiteSpace(s, &i);
name = getName(s,&i);
skipWhiteSpace(s,&i);
size = getSize(s,&i);
fileTree = new Tree(name, size);
if(name[0] == '*')
{
treeArray[rear++] = fileTree;
fileTree->parse();
}
fileTree->reSize();
fileTree->outPut();
delete fileTree;
}
infile.close();
return 0;
}

熱點內容
美發店認證 發布:2021-03-16 21:43:38 瀏覽:443
物業糾紛原因 發布:2021-03-16 21:42:46 瀏覽:474
全國著名不孕不育醫院 發布:2021-03-16 21:42:24 瀏覽:679
知名明星確診 發布:2021-03-16 21:42:04 瀏覽:14
ipad大專有用嗎 發布:2021-03-16 21:40:58 瀏覽:670
公務員協議班值得嗎 發布:2021-03-16 21:40:00 瀏覽:21
知名書店品牌 發布:2021-03-16 21:39:09 瀏覽:949
q雷授權碼在哪裡買 發布:2021-03-16 21:38:44 瀏覽:852
圖書天貓轉讓 發布:2021-03-16 21:38:26 瀏覽:707
寶寶水杯品牌 發布:2021-03-16 21:35:56 瀏覽:837