數(shù)據(jù)結(jié)構(gòu)課程設(shè)計(jì)之簡(jiǎn)易家譜 報(bào)告_第1頁
數(shù)據(jù)結(jié)構(gòu)課程設(shè)計(jì)之簡(jiǎn)易家譜 報(bào)告_第2頁
數(shù)據(jù)結(jié)構(gòu)課程設(shè)計(jì)之簡(jiǎn)易家譜 報(bào)告_第3頁
數(shù)據(jù)結(jié)構(gòu)課程設(shè)計(jì)之簡(jiǎn)易家譜 報(bào)告_第4頁
數(shù)據(jù)結(jié)構(gòu)課程設(shè)計(jì)之簡(jiǎn)易家譜 報(bào)告_第5頁
已閱讀5頁,還剩23頁未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡(jiǎn)介

1、課程設(shè)計(jì)(論文)編 號(hào): 學(xué) 號(hào): 201140410119 課 程 設(shè) 計(jì)教 學(xué) 院計(jì)算機(jī)學(xué)院課程名稱數(shù)據(jù)結(jié)構(gòu)課程設(shè)計(jì)題 目簡(jiǎn)易家譜系統(tǒng)專 業(yè)計(jì)算機(jī)科學(xué)與技術(shù)班 級(jí)(1)班姓 名陳建輝同組人員周海濤,石義灃,明廷柱指導(dǎo)教師程細(xì)才2013年1月8日 目 錄一 概述21.課程設(shè)計(jì)的目的22.課程設(shè)計(jì)的要求2二 總體方案設(shè)計(jì)31.簡(jiǎn)單家譜系統(tǒng)整體設(shè)計(jì)思路32簡(jiǎn)單家譜系統(tǒng)的主要特點(diǎn)及功能5三 詳細(xì)設(shè)計(jì)71. 查詢?nèi)康募易V成員信息72.確定指定成員在家族中的輩份73.在家譜中添加新成員,并追加到文件中9四 程序的調(diào)試與運(yùn)行結(jié)果說明121.實(shí)驗(yàn)結(jié)果截圖:122調(diào)試時(shí)遇到的問題12五 課程設(shè)計(jì)總結(jié)13附

2、錄一:程序源代碼16附錄二:參考文獻(xiàn)25一 概述1.課程設(shè)計(jì)的目的1理解和掌握該課程中的有關(guān)基本概念,程序設(shè)計(jì)思想和方法。2培養(yǎng)綜合運(yùn)用所學(xué)知識(shí)獨(dú)立完成課題的能力。3培養(yǎng)勇于探索、嚴(yán)謹(jǐn)推理、實(shí)事求是、有錯(cuò)必改,用實(shí)踐來檢驗(yàn)理論,全方位考慮問題等科學(xué)技術(shù)人員應(yīng)具有的素質(zhì)。4掌握從資料文獻(xiàn)、科學(xué)實(shí)驗(yàn)中獲得知識(shí)的能力,提高學(xué)生從別人經(jīng)驗(yàn)中找到解決問題的新途徑的悟性,初步培養(yǎng)工程意識(shí)和創(chuàng)新能力。2.課程設(shè)計(jì)的要求設(shè)計(jì)要求:輸入家族成員情況,建立樹結(jié)構(gòu),統(tǒng)計(jì)家族成員人數(shù),能查詢家族成員輩份情況。系統(tǒng)功能:1. 輸入、修改與刪除家譜信息功能2. 查詢功能:1)某家譜成員的所有子孫的集合2)某家譜成員的所有

3、祖先的集合3)某家譜成員的所有同輩成員的集合4)求某家譜成員的所有上一輩成員的集合5)給出兩個(gè)家譜成員,確定他們的關(guān)系二 總體方案設(shè)計(jì)1.簡(jiǎn)單家譜系統(tǒng)整體設(shè)計(jì)思路 此次課程設(shè)計(jì)的整體思路是采用遍歷算法,整個(gè)樹的定義使用兩個(gè)結(jié)構(gòu)體來表示,一個(gè)結(jié)構(gòu)體專門用于存放每一個(gè)節(jié)點(diǎn)的信息,另一個(gè)節(jié)點(diǎn)中定義了三個(gè)指針域,分別為父指針域(兄長(zhǎng)指針域),兄弟指針域,子指針域,整個(gè)樹的輸入采用文件導(dǎo)入的方式,首先將文件導(dǎo)入到樹中,文件包含每一個(gè)家族成員的信息,以及一個(gè)標(biāo)志位flag,標(biāo)志位的值為0,1,2,0表示此節(jié)點(diǎn)沒有兄弟節(jié)點(diǎn),1表示此節(jié)點(diǎn)至少有一個(gè)子節(jié)點(diǎn),2表示此節(jié)點(diǎn)至少有一個(gè)兄弟節(jié)點(diǎn),使用的算法是先定義一個(gè)

4、鏈?zhǔn)疥?duì)列,將文件中第一個(gè)節(jié)點(diǎn)的內(nèi)容讀取放入開辟的樹的節(jié)點(diǎn)的空間里,然后將樹節(jié)點(diǎn)放入隊(duì)列中,此時(shí)隊(duì)列不為空,以隊(duì)列不為空為判斷條件,進(jìn)行while循環(huán),判斷flag的值,循環(huán)體中再進(jìn)行文件讀取,循環(huán)中進(jìn)行判斷,若flag為0,則繼續(xù)判斷隊(duì)列是否為空,為空就結(jié)束循環(huán),若不為空,則繼續(xù)出隊(duì)列,取標(biāo)志位進(jìn)行判斷,若標(biāo)志位為1,則生成新節(jié)點(diǎn),用剛剛出列的節(jié)點(diǎn)的子指針域進(jìn)行指向新節(jié)點(diǎn),新節(jié)點(diǎn)的父指針域指向出列的節(jié)點(diǎn),剩余的域?yàn)榭?,然后將新生成的?jié)點(diǎn)插入到隊(duì)列中,若flag為1,則進(jìn)行兄弟節(jié)點(diǎn)的插入,繼續(xù)循環(huán),若flag不為0,則在進(jìn)行判斷,若為2,則繼續(xù)進(jìn)行兄弟節(jié)點(diǎn)的插入,以此類推,根據(jù)文件的讀取,將樹生

5、成,本程序中所有的算法都基于以上所介紹的算法。關(guān)于io的設(shè)計(jì):考慮到題目要求家譜信息以樹形的形式一次讀入內(nèi)存,而個(gè)人的各種資料 現(xiàn)在雖然條目不多,但隨著程序的升級(jí),以后可能變得越來越大。我把樹形結(jié)構(gòu)和個(gè)人信息記錄的文檔分為兩個(gè)文件保存在外存中,一個(gè)文件串行化地記錄家譜樹的結(jié)構(gòu)信息,保存少量個(gè)人信息作為識(shí)別標(biāo)志;另一個(gè)文件保存完整的個(gè)人信息,所有的個(gè)人信息以線性記錄的方式記錄在其中。當(dāng)程序運(yùn)行要讀入家譜結(jié)構(gòu)時(shí),只讀入保存少量記錄的文件并建立起樹形結(jié)構(gòu)。索引時(shí),以樹形中的少量信息為依據(jù)在另一個(gè)文件中找到全部的各人信息資料。這樣的好處主要有兩點(diǎn):1. 由于樹形結(jié)構(gòu)是串行化記錄于外存,一個(gè)節(jié)點(diǎn)記錄多次

6、,信息大量冗余,如果樹形節(jié)點(diǎn)中保留全部信息,必將造成大量的空間浪費(fèi);只保存作為索引的少量信息在樹形結(jié)構(gòu)中,節(jié)約了空間。2. 由于結(jié)構(gòu)的精簡(jiǎn),在家譜初始化時(shí)讀入內(nèi)存需要的時(shí)間相應(yīng)減少,節(jié)約了裝載時(shí)間。這樣做存在的問題:每次執(zhí)行修改,添加,刪除,查詢時(shí)都要直接訪問外存來取得或?qū)懭霐?shù)據(jù)。內(nèi)外存訪問上的巨大時(shí)間差的存在,使得進(jìn)行這些操作相對(duì)來說并不顯得很高效。關(guān)于樹形的結(jié)構(gòu):在樹形結(jié)構(gòu)的選擇上,根據(jù)實(shí)際中多子女的現(xiàn)象選擇一般樹,考慮到家譜中成員可能存在的不定成員數(shù)問題,拋棄了以數(shù)組為基礎(chǔ)的一般樹方案,決定用鏈表來實(shí)現(xiàn)。樹形結(jié)構(gòu)的外存保存。為了提高效率,樹形結(jié)構(gòu)在程序初始化時(shí)由外存文件一次讀入內(nèi)存,此后

7、不管插入還是修改,刪除都不再對(duì)外存的樹結(jié)構(gòu)保存文件進(jìn)行操作,只在內(nèi)存中處理,程序退出時(shí)對(duì)外存樹結(jié)構(gòu)文件進(jìn)行一次更新。也就是說,不管在程序運(yùn)行中中對(duì)家譜結(jié)構(gòu)進(jìn)行多少種,多少次的操作,外存的樹結(jié)構(gòu)文件始終只會(huì)被程序訪問兩次。關(guān)于功能的設(shè)計(jì)(以基本要求為準(zhǔn)):1. 插入:用戶按提示輸入資料,在樹形中插入節(jié)點(diǎn),在個(gè)人完整記錄文件中添加插入人的所有信息并保存。2. 刪除:用戶輸入被刪除人的識(shí)別關(guān)鍵字(即名字),在樹形結(jié)構(gòu)中刪除此人,在個(gè)人記錄文件中不處理。3. 修改:用戶輸入被刪除任的識(shí)別關(guān)鍵字(即名字),從個(gè)人完整記錄文件中讀出該人所有信息供用戶進(jìn)行修改,然后寫回。4. 查詢:完成了關(guān)鍵字查找部分和關(guān)

8、系查找部分,讀出個(gè)人全部信息并顯示。關(guān)于個(gè)人資料單元:由于樹形節(jié)點(diǎn)要涉及到大量的邏輯操作,要用到一些運(yùn)算符的重載,個(gè)人資料在樹形單元定義為class類,而寫入文件的單元存萃是數(shù)據(jù),定義為簡(jiǎn)單的struct類。定義為struct和class類,使得不管是樹形結(jié)構(gòu)插入刪除還是io都是對(duì)整個(gè)結(jié)構(gòu)體進(jìn)行的操作,這樣,如果要往結(jié)構(gòu)體中添加若干個(gè)新信息條目或取消一些不必要的信息條目,需要修改的代碼非常之少,方便了以后的升級(jí)。2簡(jiǎn)單家譜系統(tǒng)的主要特點(diǎn)及功能 本系統(tǒng)的主要特點(diǎn)是算法簡(jiǎn)潔,易于閱讀,用戶交互界面良好。 主要實(shí)現(xiàn)功能: 1.確定指定成員在家族中的輩份 2.輸出指定輩的所有成員 3.在家譜中添加新成

9、員,并追加到文件中 4.輸出指定家庭的所有成員 5.退出本系統(tǒng) 各功能的算法思想: 1.讀出家譜并顯示 存儲(chǔ)結(jié)構(gòu)用棧,按照先顯示雙親,然后顯示其所有孩子的順序顯示所有家 庭成員。 2.確定指定成員在家族中的輩份用求成員所在的二叉樹中的層數(shù)(按層遍歷二叉樹)來確定,這里采用的是遞歸算法 3 .輸出指定輩的所有成員此處定義了一個(gè)新的結(jié)構(gòu)體類型(增加存儲(chǔ)節(jié)點(diǎn)所在的層數(shù)),定義如下: typedef struct cc struct cc *child, *next;/next指向同輩份的人物 char name; jpnode; 并用一個(gè)隊(duì)列來比較顯示同輩分的所有成員。 4.在家譜中添加新成員,并追

10、加到文件中首先,輸入一個(gè)新成員的名字;然后,輸入其雙親;之后,再添加到整個(gè)存儲(chǔ)二叉鏈表中。然后,再將新的存儲(chǔ)結(jié)構(gòu)寫回到文件中。二叉鏈表的結(jié)點(diǎn)類型為:typedef struct node elemtype data10; /存放成員的名字 struct node *child; /其孩子指針 struct node *brother; /其兄弟指針 btnode; 5.輸出指定家庭的所有成員首先,設(shè)一個(gè)棧,并設(shè)一個(gè)標(biāo)記位,先置1;然后,找到輸入的要待顯示的成員,將標(biāo)記位置0;再次,顯示其孩子和兄弟,依次下去直到顯示完其所有的親戚。 6.退出本系統(tǒng)。 三 詳細(xì)設(shè)計(jì)1. 查詢?nèi)康募易V成員信息該部

11、分程序所完成的具體功能是把賈府中所有的成員信息按照輩份依次顯示出來,首先從賈無名開始,然后下一輩份的賈演、賈源等最后是賈蓉的信息。每個(gè)輩份之間都有間隔。設(shè)計(jì)思想:利用隊(duì)列遍歷所有的結(jié)點(diǎn),在遍歷的同時(shí)依次輸出每個(gè)結(jié)點(diǎn)的值(即為家庭成員的信息)。代碼如下:void dis_family(jpnode *p)char namename_length;jpnode *here = null;printf(請(qǐng)輸入該家庭的首個(gè)成員:); scanf(%s,name);here = find_name(p,name);if(here = null) printf(無該家庭!n); return;printf

12、(n);dispjp(here);2.確定指定成員在家族中的輩份該部分代碼所完成的具體功能是查詢某一個(gè)家庭成員的信息。首先手動(dòng)輸入你要查詢的那個(gè)成員的名字,然后利用隊(duì)列依次查找該成員的信息,如果該家譜中存在這個(gè)成員則輸出該成員的有關(guān)信息;如果家譜中不存在該成員,則輸出提示信息:家譜中無此人!設(shè)計(jì)思想:有兩個(gè)函數(shù),一個(gè)函數(shù)(queryelemt)利用隊(duì)列遍歷所有的節(jié)點(diǎn),在遍歷的同時(shí)即可查找所輸入的成員是否存在該家譜中;另外一個(gè)函數(shù)(queryelemtofamily)用于輸入你要查找的成員的輩分和輸出查找的結(jié)果。代碼如下:int beifen(jpnode *p, char name) stat

13、ic int n = 1;static int level = 0;if(p = null )return level;if(equal(p-name,name) = 1)return (level=n);n+; beifen(p-child,name);n-; beifen(p-next,name); /向右查詢n不必加(先加后減)!return level;void bei_fen(jpnode *p) char namename_length;int n=0;printf(請(qǐng)輸入要查明輩分的人的姓名:); scanf(%s,name); n = beifen(p,name);if(n =

14、 0)printf(該家族中無此人!n);else printf(n %s 是 %s 家族中的第%d輩 n,name,p-name,n);/ /*輸出指定輩的所有成員*/void chabei(jpnode *p, int bei) static int n = 1;static int tag = 0;if(p = null )return;if(bei = n)tag = 1;printf(%s ,p-name);n+; chabei(p-child,bei);n-; chabei(p-next,bei); /向右查詢n不必加(先加后減)!if(tag = 0)printf(該家族中還沒有

15、這一輩呢.n);void disp_pei(jpnode *p)int bei; printf(n你想要查看那一輩的成員:);scanf(%d,&bei); printf(n.該家族中輩分為%d的成員有.nn,bei);chabei(p,bei);printf(n);3.在家譜中添加新成員,并追加到文件中該部分程序所完成的具體功能是:輸入你要添加人的名字,比如吳長(zhǎng),他會(huì)被添加到文件中。設(shè)計(jì)思想:首先確定他的父母,然后把他添加到他的父母的根節(jié)點(diǎn)之下。代碼如下:int equal(char const *p,char const q)/判斷兩個(gè)字符串是否相等while(*p+ = *q+)if(*

16、p = 0 & *q = 0)return (1);return (0);jpnode *find_name(jpnode *s, char *parent)/定位家譜中的成員。返回其指針(地址)static jpnode *here = null;if(s = null)return here;if(equal(s-name,parent) = 1)return (here=s); here = find_name(s-child,parent);here = find_name(s-next,parent);return here;void print_file(jpnode *p,fil

17、e *fp) static int level=0; int i; if(p != null) for(i=0;iname); else return; level+; print_file(p-child,fp); level-; print_file(p-next,fp); void add_number(jpnode *p) /在家譜中添加新成員,并寫入文件char parentname_length,namename_length;file *fp = null;jpnode *here = null; jpnode *s = (jpnode *)malloc( 2*sizeof(vo

18、id *) + strlen(name) + 1 );s-next = s-child = null; printf(請(qǐng)輸入要添加的新成員的雙親姓名:);scanf(%s,parent); printf(請(qǐng)輸入要添加的新成員的姓名:); scanf(%s,name); strcpy(s-name,name);here = find_name(p,parent);if(here-child = null)here-child = s;else here = here-child;while(here-next != null)here = here-next;here-next = s; fp

19、= fopen(jiapu_data.txt,w);print_file(p,fp);fclose(fp);四 程序的調(diào)試與運(yùn)行結(jié)果說明1.實(shí)驗(yàn)結(jié)果截圖:2調(diào)試時(shí)遇到的問題(1)當(dāng)選擇功能3(添加新成員),添加完成員后,寫回文件時(shí)出現(xiàn)了錯(cuò)誤,原本添加的為其中一個(gè)結(jié)點(diǎn)的孩子,結(jié)果寫回文件時(shí)卻成了該結(jié)點(diǎn)的孫子,也就是本是要添加為此結(jié)點(diǎn)的孩子的兄弟,結(jié)果卻成了其孩子的孩子。最后經(jīng)過單步跟蹤發(fā)現(xiàn)寫入文件的函數(shù)編寫錯(cuò)誤,缺少判斷條件,經(jīng)過修改后,此問題得到了解決。(2)當(dāng)選擇功能0(顯示此家譜),沒有按照事先存儲(chǔ)在txt中的文件顯示,通過認(rèn)真檢查程序中顯示成員的函數(shù)(按層遍歷)、不斷調(diào)試,發(fā)現(xiàn)并不是該顯

20、示函數(shù)的錯(cuò)誤,因?yàn)樵诠δ?(輸出指定家庭的所有成員)中,也是通過調(diào)用該函數(shù)實(shí)現(xiàn)輸出功能,于是,檢查txt文件中事先存儲(chǔ)的家譜成員,發(fā)現(xiàn)是由于“(”與“)”沒有匹配好,導(dǎo)致沒有按照預(yù)期想法創(chuàng)建二叉樹造成的錯(cuò)誤,通過修改txt文件,使得錯(cuò)誤得以解決。五 課程設(shè)計(jì)總結(jié)本組的課程任務(wù)為簡(jiǎn)易家譜,在組長(zhǎng)的帶領(lǐng)下,經(jīng)過我們共同的努力,本程序主要任務(wù)已基本完成。另外本程序功能完善,具有良好的交互性,可以滿足用戶多種需求。美中不足的是本系統(tǒng)沒有采用之前我所設(shè)想的遞歸,我們這次改用隊(duì)列來建樹、查找等,這樣代碼少有一定的冗余,如果時(shí)間充分,我們會(huì)更加精進(jìn),爭(zhēng)取采用代碼量相對(duì)較少的遞歸算法,另外更加完善一些功能,包

21、括增加日志功能,給不同級(jí)別的人員設(shè)置管理權(quán)限,比如說家譜管理員在獲得本族長(zhǎng)的同意下修改某個(gè)成員的信息,而其他成員只具備瀏覽的功能。在本程序簡(jiǎn)易家譜的創(chuàng)作過程中,我們組員各抒己見,意見很不一致,包括是采用遞歸算法,還是采用隊(duì)列;數(shù)據(jù)成員的結(jié)構(gòu)如何定義,甚至包括成員的名字,大家的意見都不統(tǒng)一。但是在探討的過程中,我們也理解自己思維的不足,也見識(shí)了另外不同的編程思想,這也讓我體會(huì)到了交流的魅力。只有我們大家坦誠(chéng)布公的把自己想法說出來,然后我們?cè)诶硇缘姆治鏊惴ǖ膬?yōu)劣與可行性,這樣就能結(jié)合大家共同的智慧,組織大家共同的力量,為共同的目標(biāo)努力奮斗。次大作業(yè)的推薦學(xué)時(shí)是20個(gè)學(xué)時(shí),但回想起來,光這篇報(bào)告就寫

22、了有三四個(gè)學(xué)時(shí),由于我本身編程能力不強(qiáng),構(gòu)思,寫代碼,修改,調(diào)試的時(shí)間加起來絕對(duì)是有余了。雖然付出不少,但在前期的設(shè)計(jì)組織中,中期的代碼編寫和后期的修改調(diào)試中都學(xué)到了不少。起初我的家譜中數(shù)據(jù)并不是以結(jié)構(gòu)的形式打包,讀入,寫出操作的時(shí)候代碼異常繁瑣,這是恰好看到一本編程書上有用結(jié)構(gòu)輸入輸出的范例,深深感到結(jié)構(gòu)化確實(shí)是方便多了,而且讀寫不容易出錯(cuò)。當(dāng)時(shí)我的代碼本已經(jīng)寫了有一大半,思慮再三,還是決定進(jìn)行大換血,家譜數(shù)據(jù)的改變讓程序來了個(gè)大換血,提高了效率的同時(shí),代碼幾乎變了一多半。我想,當(dāng)時(shí)唯一不變的就只有對(duì)整個(gè)程序越來越清醒地認(rèn)識(shí)和對(duì)將要完成的代碼的更準(zhǔn)確地把握。代碼完成之后,一編譯,至少有五六十

23、個(gè)錯(cuò)誤提示,而且最末debug一行欄的最后一行提示因?yàn)橄惹暗腻e(cuò)誤而中斷編譯,有的是指針指向錯(cuò)誤,有的是忘了分號(hào),括號(hào),更多的是一些賦值錯(cuò)誤,前面的錯(cuò)誤都好改,賦值錯(cuò)誤就比較麻煩了,因?yàn)橐褂觅x值的地方太多,逐行改代碼雖然也可以,但實(shí)在是一個(gè)巨大工程。所謂巧招必是險(xiǎn)招至少對(duì)我是這樣說來慚愧,我只有嘗試著寫以前從未是過的運(yùn)算符重載函數(shù),為此專門翻找出了大一的c+教材,溫習(xí)了一番運(yùn)算符重載才戰(zhàn)戰(zhàn)兢兢地搞定了賦值問題。試運(yùn)行時(shí)出現(xiàn)了更多的問題,而且更具有隱蔽性,幾次為了一個(gè)邏輯錯(cuò)誤而來回反復(fù)地翻看代碼,嘿嘿,再加上網(wǎng)上有代碼的傳說,讓人有想直接放棄的沖動(dòng),但一想到寫代碼的辛苦,覺得放棄了實(shí)在可惜。那幾

24、天吃飯,睡覺,走路,看電視,隨時(shí)隨地,都記掛著那幾處錯(cuò)誤,腦子都會(huì)浮現(xiàn)出代碼的影子,不自覺地開始找錯(cuò)誤。哎那種感覺!不知道是充實(shí)還是急迫地?zé)?,最后終于找到了,根本來不急高興,只有松了一口氣和一陣的疲憊?,F(xiàn)在程序終于完成了,心里的石頭也下了地。至于成績(jī),不想了 另外,通過本次課程設(shè)計(jì),我覺得自己最大的收獲就是:(1)學(xué)會(huì)了怎樣將課堂所學(xué)知識(shí)運(yùn)用到較為實(shí)際的應(yīng)用中來由于對(duì)二叉鏈表的存儲(chǔ)比較感興趣,我選做的是家譜,開始覺得無從下手,但是經(jīng)過仔細(xì)分析后,漸漸找到一點(diǎn)思路(首先創(chuàng)建,然后分別實(shí)現(xiàn)各個(gè)功能,最后利用菜單實(shí)現(xiàn)選擇功能并輸出結(jié)果)。(2)鍛煉提出問題、解決問題和自學(xué)的能力 家譜的實(shí)現(xiàn)要求讀、

25、寫文件,于是“如何將文件從文檔中讀出”,“ 怎么寫入文件”都是要滿足要求必須解決的問題。為此,我查找了很多資料,最后自學(xué)、解決這一問題(3)增加了對(duì)編程的熱愛和興趣本次編寫家譜程序的過程中,我體驗(yàn)到了編程的酸甜苦辣:開始,由于即將運(yùn)用所學(xué)知識(shí)設(shè)計(jì)實(shí)際問題而激動(dòng)興奮;后來編寫程序過程中,在想不出算法如何實(shí)現(xiàn)或者追求空間、時(shí)間上高效率的算法時(shí)會(huì)比較糾結(jié);以及遇到bug時(shí),追蹤數(shù)據(jù)的痛苦;當(dāng)然,還有解決問題后的激動(dòng)與自豪。所有這些都增強(qiáng)了我對(duì)編程的熱愛、提高了我對(duì)計(jì)算機(jī)專業(yè)的興趣。附錄一:程序源代碼#include#include#include#include#define name_length

26、 50 /名字最大長(zhǎng)度#define line_length 100 /文本行最大長(zhǎng)度typedef struct cc struct cc *child, *next;/next指向同輩份的人物 char name;jpnode;void clear(char p,int n) /清空字符數(shù)組pwhile(n- 0)*p+ = 0; static jpnode *last = null; static int last_level = 0;void addjp(jpnode *head, char const name, int level) jpnode *s = head, *r = n

27、ull; jpnode *p = (jpnode *)malloc( 2*sizeof(void *) + strlen(name) + 1 ); p-child = p-next = null; strcpy(p-name,name); if( *s = null) *s = p; last = p; return; if(level - last_level = 1) last-child = p; last = p;last_level = level;return; if(level = last_level) & (*s != null)last-next = p; last = p

28、;last_level = level;return; r = *s; /r指向家譜樹 last_level = level; while( level- 0) /找到相同的輩分 while(r-next != null)r = r-next; r = r-child; /以兄弟連接 while( r-next != null) r = r-next; r-next = p; last = p;void creatjp(jpnode *head) char namename_length=, lineline_length=; char *p = null; int level=0,i=0;

29、/輩分,以制表符個(gè)數(shù)表示 file *fp = null; fp = fopen(jiapu_data.txt,r); if(fp = null) printf(open error!n); exit(1); while(level=0, i=0, fgets(line,line_length,fp) != null) p = line; while(*p+ = t)level+; /計(jì)算輩分 ,計(jì)算完后p指向名字開始處 while(linei+ != n) ; linei-1=0; /讀入的換行符用字符串結(jié)束標(biāo)識(shí)符替換 strcpy(name,p-1); addjp(head,name,le

30、vel); clear(name,name_length); clear(line,line_length); fclose(fp);void dispjp(jpnode *p)/從p指向的結(jié)點(diǎn)顯示該家族 static int level=0; int i; if(p != null) for(i=0;iname); else return; level+; dispjp(p-child); level-; dispjp(p-next); / /*在家譜中添加新成員,并追加到文件中*/int equal(char const *p,char const q)/判斷兩個(gè)字符串是否相等while(

31、*p+ = *q+)if(*p = 0 & *q = 0)return (1);return (0);jpnode *find_name(jpnode *s, char *parent)/定位家譜中的成員。返回其指針(地址)static jpnode *here = null;if(s = null)return here;if(equal(s-name,parent) = 1)return (here=s); here = find_name(s-child,parent);here = find_name(s-next,parent);return here;void print_file

32、(jpnode *p,file *fp) static int level=0; int i; if(p != null) for(i=0;iname); else return; level+; print_file(p-child,fp); level-; print_file(p-next,fp); void add_number(jpnode *p) /在家譜中添加新成員,并寫入文件char parentname_length,namename_length;file *fp = null;jpnode *here = null; jpnode *s = (jpnode *)mallo

33、c( 2*sizeof(void *) + strlen(name) + 1 );s-next = s-child = null; printf(請(qǐng)輸入要添加的新成員的雙親姓名:);scanf(%s,parent); printf(請(qǐng)輸入要添加的新成員的姓名:); scanf(%s,name); strcpy(s-name,name);here = find_name(p,parent);if(here-child = null)here-child = s;else here = here-child;while(here-next != null)here = here-next;here

34、-next = s; fp = fopen(jiapu_data.txt,w);print_file(p,fp);fclose(fp);/ /*輸出指定家庭的所有成員*/void dis_family(jpnode *p)char namename_length;jpnode *here = null;printf(請(qǐng)輸入該家庭的首個(gè)成員:); scanf(%s,name);here = find_name(p,name);if(here = null) printf(無該家庭!n); return;printf(n);dispjp(here);/ /*確定指定成員在家族中的輩份*/int b

35、eifen(jpnode *p, char name) static int n = 1;static int level = 0;if(p = null )return level;if(equal(p-name,name) = 1)return (level=n);n+; beifen(p-child,name);n-; beifen(p-next,name); /向右查詢n不必加(先加后減)!return level;void bei_fen(jpnode *p) char namename_length;int n=0;printf(請(qǐng)輸入要查明輩分的人的姓名:); scanf(%s,

36、name); n = beifen(p,name);if(n = 0)printf(該家族中無此人!n);else printf(n %s 是 %s 家族中的第%d輩 n,name,p-name,n);/ /*輸出指定輩的所有成員*/void chabei(jpnode *p, int bei) static int n = 1;static int tag = 0;if(p = null )return;if(bei = n)tag = 1;printf(%s ,p-name);n+; chabei(p-child,bei);n-; chabei(p-next,bei); /向右查詢n不必加(先加后減)!if(tag = 0)printf(該家族

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。

評(píng)論

0/150

提交評(píng)論