南京工程學(xué)院 數(shù)據(jù)結(jié)構(gòu)樣卷09級附答案
南京工程學(xué)院試卷(樣)共 8 頁 第1頁2010 /2011 學(xué)年 第 2 學(xué)期 課程所屬部門: 計算機工程學(xué)院 課程名稱: 數(shù)據(jù)結(jié)構(gòu) 考試方式: 閉卷 使用班級: 計算機專業(yè)2009級各班 命題人:葉核亞、黃緯 教研室主任審核: 主管領(lǐng)導(dǎo)批準(zhǔn): 班級 學(xué)號 姓名 題號一二三四五總分得分本題得分一. 填空題(26分,每空2分)1. 聲明抽象數(shù)據(jù)類型的目的是_。2. 已知結(jié)點類Node<T>有data和next域,下列數(shù)據(jù)存儲結(jié)構(gòu)聲明分別為_和_。3. 已知SString s1("aababbabac"),s2("aba");,執(zhí)行下列語句后,s1字符串是_。s1.replaceAll(s1.substring(0,1),s2);s1.removeAll(s2.substring(0,2);4. 中綴表達式A+B*(C-D*(E+F)/G+H)-(I+J)*K的后綴表達式為_。5. 設(shè)一個順序循環(huán)隊列容量為60,當(dāng)front=47,rear=23時,該隊列有_個元素。6. 已知二維數(shù)組a108采用行主序存儲,數(shù)組首地址是1000,每個元素占用4字節(jié),則數(shù)組元素a45的存儲地址是_。7. 已知一棵完全二叉樹的根(第0個)結(jié)點層次為1,則第100個結(jié)點的層次為_。8. 中根遍歷序列和后根遍歷序列相反的二叉樹是_。9. 由256個權(quán)值構(gòu)造一棵哈夫曼樹,則該二叉樹共有_結(jié)點。10. 由n個頂點組成的無向連通圖,最多可以有_條邊。11. 10個元素的排序數(shù)據(jù)序列采用折半查找的平均查找長度是(寫出算式)_。12. 已知關(guān)鍵字序列為67,41,34,10,69,24,78,54,41*,采用快速排序算法按升序排序,以第一個元素為基準(zhǔn)值,其第一趟排序后的關(guān)鍵字序列為_。二. 問答題(45分,每小題5分)1. 已知目標(biāo)串為"aabcbabcaabcaababc",模式串為"abcaababc",寫出模式串改進的next數(shù)組;畫出KMP算法的匹配過程,給出字符比較次數(shù)。2. 什么是棧和隊列?兩者有何異同?什么情況下需要使用?;蜿犃??采用順序存儲結(jié)構(gòu)的棧和隊列,在進行插入、刪除操作時需要移動數(shù)據(jù)元素嗎?為什么?什么是隊列的假溢出?為什么順序存儲結(jié)構(gòu)隊列會出現(xiàn)假溢出?怎樣解決隊列的假溢出問題?鏈?zhǔn)酱鎯Y(jié)構(gòu)隊列會出現(xiàn)假溢出嗎?順序存儲結(jié)構(gòu)的棧會出現(xiàn)假溢出嗎?為什么?3. 已知一棵二叉樹中根次序遍歷序列為GCBHKAMFDJE,后根次序遍歷序列為CBGHMAJEDFK,畫出這棵二叉樹并進行中序線索化。4. 設(shè)一段正文由字符集A,B,C,D,E,F,G,H組成,其中每個字符在正文中的出現(xiàn)次數(shù)依次為23,5,17,4,9,31,29,18,采用哈夫曼編碼對這段正文進行壓縮存儲,畫出所構(gòu)造的哈夫曼樹,并寫出每個字符的哈夫曼編碼。5. 刪除以下帶權(quán)無向圖中的頂點D,畫出刪除D后圖的鄰接矩陣表示和鄰接表表示。6. 構(gòu)造以下帶權(quán)無向圖的最小生成樹,并給出該最小生成樹的代價。7. 已知關(guān)鍵字序列為16,74,60,43,54,90,46,31,29,88,71,64,50,散列表長度為11,采用除留余數(shù)法的散列函數(shù)為hash(k)=k % 11,畫出采用鏈地址法構(gòu)造的散列表,計算(寫出算式)。8. 畫出對關(guān)鍵字序列93,17,56,42,78,15,42*,25,19進行希爾排序(升序)的每一趟排序過程,說明希爾排序算法的穩(wěn)定性并解釋原因,以及希爾排序適用于什么存儲結(jié)構(gòu)。9. 將關(guān)鍵字序列29,10,25,26,58,12,31,18,47用篩選法分別建成一個最大堆和一個最小堆,寫出兩個堆序列并畫出其對應(yīng)的完全二叉樹。三. 程序閱讀和改錯題(15分,每小題5分) 1. 閱讀以下函數(shù),回答問題。template <class T>void CirHDoublyLinkedList<T>:concat(CirHDoublyLinkedList<T> &list) DLinkNode<T> *rear=head->prev; rear->next = list.head->next; list.head->next->prev = rear; rear=list.head->prev; rear->next = this->head; this->head->prev = rear; list.head->prev = list.head; list.head->next = list.head; 上述函數(shù)功能是什么?以下調(diào)用語句的運行結(jié)果是什么?CirHDoublyLinkedList<char> source("abcdef",6), list("xyz",3);source.concat(list);cout<<"source:"<<source<<"list:"<<list;2. 下列trim()函數(shù)欲刪除當(dāng)前字符串對象中的所有空格字符。void SString:trim() /刪除串對象中的所有空格字符 int i=0; while (elementi!=' ' && elementi!='0') /尋找第1個空格 i+; /i記住第1個空格下標(biāo) for (int j=i; elementj!='0' j+) if (elementj!=' ') elementi+ = elementj; /非空格字符向前移動到空格字符位置 len = i; 對于以下調(diào)用語句,運行結(jié)果是什么?正確的運行結(jié)果是什么?SString str(" a bc d e f xyz");str.trim();cout<<"str="<<str<<endl; trim()函數(shù)怎樣實現(xiàn)所求功能?算法存在什么錯誤? 如何改正?3. 已知三叉鏈表表示的二叉樹結(jié)點類TriNode聲明如下:template <class T>class TriNode /二叉樹的三叉鏈表結(jié)點類 public: T data; /數(shù)據(jù)域,保存元素 TriNode<T> *parent, *left, *right; /指針域,分別指向父母、左、右孩子結(jié)點 /構(gòu)造結(jié)點,參數(shù)依次分別指定元素、左孩子和右孩子結(jié)點 TriNode(T data, TriNode<T> *left=NULL, TriNode<T> *right=NULL) this->data = data; this->left = left; this->right = right; ;三叉鏈表表示的二叉樹類TriBinaryTree及部分函數(shù)聲明如下:class TriBinaryTree /二叉樹類(三叉鏈表) public: TriNode<T> *root; /指向根結(jié)點 TriBinaryTree(TriBinaryTree<T> &bitree); /拷貝構(gòu)造函數(shù) private: TriNode<T>* copy(TriNode<T> *p); /復(fù)制以p為根的子二叉樹;template <class T>TriBinaryTree<T>:TriBinaryTree(TriBinaryTree<T> &bitree) /拷貝構(gòu)造函數(shù) this->root = copy(bitree.root);/復(fù)制以p為根的子二叉樹,返回新建子樹的根結(jié)點template <class T>TriNode<T>* TriBinaryTree<T>:copy(TriNode<T> *p) TriNode<T> *q=NULL; if (p!=NULL) q = new TriNode<T>(p->data); q->left = copy(p->left); q->right = copy(p->right); return q; 上述函數(shù)中存在什么錯誤?如何改正?四. 程序設(shè)計題(14分,每小題7分) 1. 在帶頭結(jié)點的單鏈表類HSLinkedList中,增加以下成員函數(shù): void HSLinkedList<T>:removeAll(HSLinkedList<T> &list) /刪除所有與list匹配的子表2. 求二叉樹中指定結(jié)點的層次。 南京工程學(xué)院試卷 共 8 頁 第 2 頁 本題得分 南京工程學(xué)院試卷 共 8 頁 第 3 頁 南京工程學(xué)院試卷 共 8 頁 第 4 頁 南京工程學(xué)院試卷 共 8 頁 第 5 頁 本題得分 南京工程學(xué)院試卷 共 8 頁 第 6 頁 南京工程學(xué)院試卷 共 8 頁 第 7 頁 南京工程學(xué)院試卷 共 8 頁 第 8 頁 本題得分南京工程學(xué)院試題評分標(biāo)準(zhǔn)及參考答案(樣) 共7頁 第 1 頁 2010 / 2011 學(xué)年第 2 學(xué)期課程所屬部門: 計算機工程學(xué)院 課程名稱: 數(shù)據(jù)結(jié)構(gòu) 使用班級:計算機專業(yè)2009級各班 制作人:葉核亞、黃緯 2011年5月24日五. 填空題(26分,每空2分)1. 使數(shù)據(jù)類型的定義和實現(xiàn)分離,使一種定義有多種實現(xiàn)。2. Node<T>* table4;Node<T> table4;3. "abac"4. ABCDEF+*G/-H+*+IJ+K*-5. 366. 11487. 78. 右單支二叉樹(包括空二叉樹、只有根結(jié)點的二叉樹)9. 51110. n*(n-1)/211. 12. 41* 41 34 10 54 24 67 78 69六. 問答題(45分,每小題5分)1. 模式串"abcaababc"改進的next數(shù)組為j012345678模式串a(chǎn)bcaababc""中最長相同的前后綴子串長度k-100011212與比較=改進的nextj-100-1102002. 棧和隊列都屬于線性表結(jié)構(gòu),它們是兩種特殊的線性表,棧的插入和刪除操作都在線性表的一端進行,所以棧的特點是“后進先出”;而隊列的插入和刪除操作分別在線性表的兩端進行,所以隊列的特點是“先進先出”。深度優(yōu)先搜索遍歷算法需要使用棧作為輔助結(jié)構(gòu),廣度優(yōu)先搜索遍歷算法需要使用隊列作為輔助結(jié)構(gòu)。采用順序存儲結(jié)構(gòu)的棧和隊列,在進行插入、刪除操作時不需要移動數(shù)據(jù)元素,因為棧和隊列均不能進行中間插入、刪除操作。順序隊列,當(dāng)入隊的元素個數(shù)(包括已出隊元素)超過數(shù)組容量時,隊列尾下標(biāo)越界,數(shù)據(jù)溢出。此時,由于之前已有若干元素出隊,數(shù)組前部已空出許多存儲單元,所以,這種溢出并不是因存儲空間不夠而產(chǎn)生的,稱之為假溢出。順序隊列之所以會產(chǎn)生假溢出現(xiàn)象,是因為順序隊列的存儲單元沒有重復(fù)使用機制。解決的辦法是將順序隊列設(shè)計成循環(huán)結(jié)構(gòu)。鏈?zhǔn)酱鎯Y(jié)構(gòu)隊列不會出現(xiàn)假溢出。因為每次元素入隊,都要申請新結(jié)點,數(shù)據(jù)不會溢出。順序存儲結(jié)構(gòu)的棧不會出現(xiàn)假溢出。因為順序棧的存儲單元可以重復(fù)使用,如果數(shù)組容量不夠,則是數(shù)據(jù)溢出,而不是假溢出。3. (4)(5) (6),代價是45 (7)(8)希爾排序算法是不穩(wěn)定的,因為與距離較遠的元素進行比較,不能保證排序穩(wěn)定性。希爾排序算法僅適用于順序存儲結(jié)構(gòu),因為與距離較遠的元素進行比較,需要利用隨機存儲特性。(9)七. 程序閱讀題(15分,每小題5分) 1. 將list鏈表合并連接到當(dāng)前鏈表最后,設(shè)置list鏈表為空source:(a, b, c, d, e, f, x, y, z)list:()2. 運行結(jié)果為“abcdefxyz e f xyz”,正確的運行結(jié)果是“abcdefxyz”。 trim()函數(shù)首先尋找串的第一個空格字符,用i記住空格字符下標(biāo);再遍歷串,將串中的非空格字符(用j記住其下標(biāo))逐個向前移動到空格字符位置(i下標(biāo));算法存在錯誤,刪除后沒將字符串結(jié)束符'0'向前移動到len處,導(dǎo)致cout輸出仍然到'0',如下圖所示。 改正:函數(shù)體最后增加以下一句: elementlen = '0'3. 深拷貝創(chuàng)建二叉樹時,沒有為各結(jié)點建立指向父母結(jié)點的鏈。改正如下: 當(dāng)TriNode構(gòu)造函數(shù)不指定parent時template <class T>TriNode<T>* TriBinaryTree<T>:copy(TriNode<T> *p) TriNode<T> *q=NULL; if (p!=NULL) q = new TriNode<T>(p->data); /創(chuàng)建結(jié)點,父母結(jié)點parent為空 q->left = copy(p->left); /復(fù)制左子樹,遞歸調(diào)用 if (q->left!=NULL) q->left->parent = q; /為左孩子設(shè)置parent鏈 q->right = copy(p->right); /復(fù)制右子樹,遞歸調(diào)用 if (q->right!=NULL) q->right->parent = q; /為右孩子設(shè)置parent鏈 return q; /返回建立子樹的根結(jié)點 如果TriNode類聲明以下構(gòu)造函數(shù),參數(shù)包括指定父母結(jié)點:TriNode(T data, TriNode<T> *parent=NULL, TriNode<T> *left=NULL, TriNode<T> *right=NULL)則TriNode類深拷貝構(gòu)造函數(shù)可實現(xiàn)如下:template <class T>TriBinaryTree<T>:TriBinaryTree(TriBinaryTree<T> &bitree) /拷貝構(gòu)造函數(shù),深拷貝 this->root = copy(bitree.root, NULL, 1);/復(fù)制以p為根的子二叉樹,parent指向p的父母結(jié)點,返回新建子樹的根結(jié)點template <class T>TriNode<T>* TriBinaryTree<T>:copy(TriNode<T> *p, TriNode<T> *parent) TriNode<T> *q=NULL; if (p!=NULL) q = new TriNode<T>(p->data, parent); /創(chuàng)建結(jié)點,父母結(jié)點是parent q->left = copy(p->left, p); /復(fù)制左子樹,遞歸調(diào)用 q->right = copy(p->right, p); /復(fù)制右子樹,遞歸調(diào)用 return q; /返回建立子樹的根結(jié)點八. 程序設(shè)計題(14分,每小題7分) 以下給出參考程序,閱卷老師可根據(jù)實際情況評分,重點是表達算法思想。1. 在帶頭結(jié)點的單鏈表類HSLinkedList中,增加以下成員函數(shù),刪除所有與list匹配的子表。template <class T>void HSLinkedList<T>:removeAll(HSLinkedList<T> &list) Node<T> *start=head->next, *front=head; while (start!=NULL) Node<T> *p=start, *q=list.head->next; while (p!=NULL && q!=NULL && p->data=q->data) /一次匹配 p=p->next; q=q->next; if (q!=NULL) /一次匹配失敗,再進行下一次匹配 front=start; start=start->next; else /一次匹配成功,刪除一個子表 q=list.head->next; while (q!=NULL) /刪除從start開始與list匹配的子表 front->next = start->next; /刪除start結(jié)點 delete start; start=front->next; q=q->next; 2. 求二叉樹中指定結(jié)點的層次。一棵二叉樹中結(jié)點所在的層次定義:令根結(jié)點的層次為1,其他結(jié)點的層次是其父母結(jié)點的層次加1。 在二叉鏈表存儲的二叉樹類BinaryTree中增加成員函數(shù)如下:template <class T>int BinaryTree<T>:getLevel(T x) /返回x結(jié)點所在的層次 /若空樹或未查找到x返回-1 if (root=NULL) return -1; return getLevel(root, 1, x); /令根結(jié)點的層次為1template <class T>int BinaryTree<T>:getLevel(BinaryNode<T> *p, int i, T x) /在以p結(jié)點(層次為i)為根的子樹中求x結(jié)點所在層次 if (p!=NULL) if (p->data=x) return i; /查找成功 int level = getLevel(p->left, i+1, x); /在左子樹查找 if (level!=-1) return level; return getLevel(p->right, i+1, x); /繼續(xù)在右子樹中查找 return -1; /查找不成功 在二叉鏈表結(jié)點類BinaryNode中增加表示結(jié)點層次的成員變量level,結(jié)點構(gòu)造函數(shù)聲明如下:BinaryNode(T data, BinaryNode<T> *left=NULL, BinaryNode<T> *right=NULL, int level=0)構(gòu)造二叉樹時設(shè)置每個結(jié)點的層次屬性。例如,二叉樹類BinaryTree的一種構(gòu)造函數(shù)聲明如下:template <class T>BinaryTree<T>:BinaryTree(T prelist, int n) /以標(biāo)明空子樹的先根序列構(gòu)造一棵二叉樹 int i=0; root=create(prelist, n, i, NULL, 1); /根結(jié)點的層次為1 /以標(biāo)明空子樹的先根次序遍歷序列創(chuàng)建一棵子樹,該子樹根結(jié)點是prelisti, /根結(jié)點層次是level,其父母結(jié)點由parent指向,返回創(chuàng)建子樹的根結(jié)點指針template <class T>BinaryNode<T>* BinaryTree<T>:create(T prelist, int n, int &i, int level) BinaryNode<T> *p=NULL; if (i<n) T elem = prelisti+; if (elem!=NULL) p = new BinaryNode<T>(elem, NULL, NULL, level); /創(chuàng)建結(jié)點,層次是level p->left = create(prelist, n, i, level+1); /創(chuàng)建左子樹 p->right = create(prelist, n, i, level+1); /創(chuàng)建右子樹 return p;BinaryTree類的getLevel(p)成員函數(shù)聲明如下,算法同查找。template <class T>int BinaryTree<T>:getLevel(T x) /返回值為x結(jié)點所在的層次,若空樹或未查找到x返回-1 BinaryNode<T> *find=search(x); /查找 if (find=NULL) return -1; return find->level;在二叉樹中插入一個結(jié)點時,以插入結(jié)點為根的子樹中所有結(jié)點的層次也隨之改變,因此,BinaryTree類需要提供以下setLevel()方法動態(tài)維護層次屬性。 /設(shè)置以p結(jié)點(層次為level)為根的子樹中所有結(jié)點的層次template <class T>void BinaryTree<T>:setLevel(BinaryNode<T> *p, int level) if (p!=NULL) p->level = level; setLevel(p->left, level+1); setLevel(p->right, level+1); 共7頁 第 2 頁南京工程學(xué)院評分標(biāo)準(zhǔn)及參考答案 共7頁 第 3 頁南京工程學(xué)院評分標(biāo)準(zhǔn)及參考答案 共7頁 第 4 頁南京工程學(xué)院評分標(biāo)準(zhǔn)及參考答案 共7頁 第 5 頁南京工程學(xué)院評分標(biāo)準(zhǔn)及參考答案 共7頁 第 6 頁南京工程學(xué)院評分標(biāo)準(zhǔn)及參考答案 共7頁 第 7 頁南京工程學(xué)院評分標(biāo)準(zhǔn)及參考答案