華中大數據結構課程設計-------基於查找表的單詞檢索軟件--------靜態表、動態表、哈希表


大二時寫的數據結構課程設計,好幾個朋友的推薦,現在放到博客了,希望對大家有幫助!

 

 

 

任務書

p 設計內容

設計與實現靜態查找表、基於二叉排序樹的動態查找表及HASH表等三種中的任意兩種查找表結構及其抽象數據類型;以一本英文電子書(如英文小說,科普讀物或聖經之類的社會書籍,書的篇幅不少於2萬次單詞)作為單詞文本數據來源,使用上述查找表ADT,通過讀取電子書而建立對應的兩種查找表,以單詞作為關鍵字,單詞在書籍中出現的次數及每次出現的頁碼,行號等信息作為查找表數據元素屬性;通過理論與實際測試結果對比分析兩種查找表性能。

p 設計要求

(1) 靜態查找表ADT要求實現Create、Destroy、Search、Traverse等操作,另外靜態查找表同時要求采用某種排序算法Sort對其排序,形成無序存儲與有序表存儲兩種物理存儲,並同時實現在有序表上的二分查找Search_Bin,且作為性能對比分析的一種情形。

(2) 動態查找表ADT要求實現InitDSTable、DestroyTable、SearchDSTable、InsertDSTable、DeleteDSTable、TraverseDSTable等操作,以二叉鏈表為物理存儲結構。

(3)     HASH表要求實現InitHash、DestroyHash、SearchHash、InsertHash、DeleteHash、TraverseHash等操作,設計合理的HASH函數與沖突解決辦法,並在報告中分析說明選擇理由。

(4) 一個單詞的多次出現可以由鏈表表示,形成類似於倒排索引的結構。查找表數據以文件形式保存,如果在程序重啟動時能夠從查找表文件恢復查找表,或界面友好,或增加了有意義的功能等,具有一定特色,則給予鼓勵,酌情加分。但是,如果只實現了其中一種查找表,則綜合成績不超過75分。

 

引言

1.1    課題背景與意義

數據結構在計算機科學界至今沒有標准的定義。個人根據各自的理解的不同而有不同的表述方法:

Sartaj Sahni在他的《數據結構、算法與應用》一書中稱:“數據結構是數據對象,以及存在於該對象的實例和組成實 例的數據元素之間的各種聯系。這些聯系可以通過定義相關的函數來給出。”他將數據對象(data object)定義為“一個數據對象是實例或值的集合”。Clifford A.Shaffer在《數據結構與算法分析》一書中的定義是:“數據結構是 ADT(抽象數據類型Abstract Data Type) 的物理實現。”

Lobert L.Kruse在《數據結構與程序設計》一書中,將一個數據結構的設計過程分成抽象層、數據結構層和實現層。其中,抽象層是指抽象數據類型層,它討論數據的邏輯結構及其運算,數據結構層和實現層討論一個數據結構的表示和在計算機內的存儲細節以及運算的實現。數據結構具體指同一類數據元素中,各元素之間的相互關系,包括三個組成成分,數據的邏輯結構,數據的存儲結構和數據運算結構。

在日常工作和學習中,我們會遇到統計一個文章里面所包含的單詞或者詞語。然而現在這樣的統計軟件在網絡上特別多,作為一個學計算機編程的學生,我覺得有必要了解一下其核心功能以及算法實現。通過此次設計,可以對上學期學習的數據結構課程的內容做一個總結,感受真正用上學過的算法思想,這對以后的學習以及工作也有很大的幫助。

1.2    重要意義

一般認為,一個數據結構是由數據元素依據某種邏輯聯系組織起來的。對數據元素間邏輯關系的描述稱為數據的邏輯結構;數據必須在計算機內存儲,數據的存儲結構是數據結構的實現形式,是其在計算機內的表示;此外討論一個數據結構必須同時討論在該類數據上執行的運算才有意義。

在許多類型的程序的設計中,數據結構的選擇是一個基本的設計考慮因素。許多大型系統的構造經驗表明,系統實現的困難程度和系統構造的質量都嚴重的依賴於是否選擇了最優的數據結構。許多時候,確定了數據結構后,算法就容易得到了。有些時候事情也會反過來,我們根據特定算法來選擇數據結構與之適應。不論哪種情況,選擇合適的數據結構都是非常重要的。

    選擇了數據結構,算法也隨之確定,是數據而不是算法是系統構造的關鍵因素。這種洞見導致了許多種軟件設計方法和程序設計語言的出現,面向對象的程序設計語言就是其中之一。

1.3    課程設計的主要研究工作

       在計算機科學中,數據結構是一門研究非數值計算的程序設計問題中計算機的操作對象(數據元素)以及它們之間的關系和運算等的學科,而且確保經過這些運算后所得到的新結構仍然是原來的結構類型。

“數據結構”作為一門獨立的課程在國外是從1968年才開始設立的。 1968年美國唐·歐·克努特教授開創了數據結構的最初體系,他所著的《計算機程序設計技巧》第一卷《基本算法》是第一本較系統地闡述數據的邏輯結構和存儲結構及其操作的著作。“數據結構”在計算機科學中是一門綜合性的專業基礎課。數據結構是介於數學、計算機硬件和計算機軟件三者之間的一門核心課程。數據結構這一門課的內容不僅是一般程序設計(特別是非數值性程序設計)的基礎,而且是設計和實現編譯程序、操作系統、數據庫系統及其他系統程序的重要基礎。

計算機是一門研究用計算機進行信息表示和處理的科學。這里面涉及到兩個問題:信息的表示,信息的處理 。 而信息的表示和組織又直接關系到處理信息的程序的效率。隨着計算機的普及,信息量的增加,信息范圍的拓寬,使許多系統程序和應用程序的規模很大,結構又相當復雜。因此,為了編寫出一個“好”的程序,必須分析待處理的對象的特征及各對象之間存在的關系,這就是數據結構這門課所要研究的問題。眾所周知,計算機的程序是對信息進行加工處理。在大多數情況下,這些信息並不是沒有組織,信息(數據)之間往往具有重要的結構關系,這就是數據結構的內容。數據的結構,直接影響算法的選擇和效率。

計算機解決一個具體問題時,大致需要經過下列幾個步驟:首先要從具體問題中抽象出一個適當的數學模型,然后設計一個解此數學模型的算法(Algorithm),最后編出程序、進行測試、調整直至得到最終解答。尋求數學模型的實質是分析問題,從中提取操作的對象,並找出這些操作對象之間含有的關系,然后用數學的語言加以描述。計算機算法與數據的結構密切相關,算法無不依附於具體的數據結構,數據結構直接關系到算法的選擇和效率。運算是由計算機來完成,這就要設計相應的插入、刪除和修改的算法 。也就是說,數據結構還需要給出每種結構類型所定義的各種運算的算法。

數據是對客觀事物的符號表示,在計算機科學中是指所有能輸入到計算機中並由計算機程序處理的符號的總稱。 數據元素是數據的基本單位,在計算機程序中通常作為一個整體考慮。一個數據元素由若干個數據項組成。數據項是數據的不可分割的最小單位。有兩類數據元素:一類是不可分割的原子型數據元素,如:整數"5",字符 "N" 等;

另一類是由多個款項構成的數據元素,其中每個款項被稱為一個數據項。例如描述一個學生的信息的數據元素可由下列6個數據項組成。其中的出生日期又可以由三個數據項:"年"、"月"和"日"組成,則稱"出生日期"為組合項,而其它不可分割的數據項為原子項。關鍵字指的是能識別一個或多個數據元素的數據項。若能起唯一識別作用,則稱之為 "主" 關鍵字,否則稱之為 "次" 關鍵字。數據對象是性質相同的數據元素的集合,是數據的一個子集。數據對象可以是有限的,也可以是無限的。

數據處理是指對數據進行查找、插入、刪除、合並、排序、統計以及簡單計算等的操作過程。在早期,計算機主要用於科學和工程計算,進入八十年代以后,計算機主要用於數據處理。據有關統計資料表明,現在計算機用於數據處理的時間比例達到80%以上,隨着時間的推移和計算機應用的進一步普及,計算機用於數據處理的時間比例必將進一步增大。

 

 

系統需求分析與總體設計

2.1    系統需求分析

對單詞數量不少於2萬字的英文小說進行字符統計,用三種數據結構來實現,分別是基於順序表的實現、基於動態查找表以二叉搜索樹為結構來實現、基於HASH表的實現。抽象數據類型由單詞、出現次數、頁碼、行數組成。計算結果以文本文件的形式保存到本地目錄。以QT為用戶界面,以C語言為編程語言。

2.2    系統總體設計

(1)    首先用戶通過打開文件或者復制粘貼的方式把要分析的內容放在用戶界面上的文本框。文本框的內容用戶可以自己輸入或更改,完成后通過相應的按鈕進行計算並顯示。由於有三種數據結構來實現,因此需要把計算內容分別顯示。

(2)    基於順序表的實現有兩種,有序存儲結構和無序存儲結構。給用戶提供兩個按鈕來相應兩種結構的結果輸出。創建有序存儲先從文本內容里面取單詞,把取單詞的部分寫成單獨的函數,以便后序繼續使用此函數來取單詞,減少代碼量。然后從現有的存儲結構里面進行查找,如果找到了則單詞數目加一,否則進行插入。查找函數以折半查找算法為核心,作為與無序表性能對比分析的一種情形。為了更好的顯示出兩種存儲結構的優缺點,在這些函數運行時進行計時,當所有單詞統計出來以后,把總時間顯示到界面,以便用戶對比分析結果。表創建完成后進行遍歷輸出,輸出的內容有單詞內容,單詞出現次數、單詞出現的頁碼以及行數,所以以表格的形式在界面上進行顯示。

(3)    基於動態查找表以二叉搜索樹為結構來實現。首先從用戶輸入的內容里面進行讀取單詞,然后在現有的數據里面進行查找,如果沒有找到則進行創建。給用戶提供三種遍歷方式,前序、中序、后序。同樣,在此部分程序運行時進行計時,最后結果在界面上顯示,以便進行對比分析。

(4)    基於HASH表的實現,以每一個單詞的第一與第二個字母的ASCLL值的和作為哈希值進行創建,以線性探索來處理沖突,哈希表長度為52。在此部分程序運行時進行計時,最后把結果以表格的形式顯示在界面上。

(5)    計算並輸出完成后,用戶可以保存計算結果,保存的類型有txt、doc。保存位置由用戶決定,用戶打開對應的文件夾並輸入文件名以后進行輸出。

(6)    提供搜索功能,輸入單詞以后進行查找,找到單詞以后進行定位,並使用QT內部函數給單詞染色並突出顯示。

(7)    用戶界面上的所有按鈕可以用對應的快捷鍵來控制。QT界面引用CSS樣式表來設置界面顏色,總共提供四種風格。

程序整體流程圖為如下:

 

圖 2-1 系統整體運行流程圖

系統詳細設計

3.1    有關數據結構的定義

一共有四種數據結構,順序存儲結構、二叉樹存儲結構、HASH表存儲結構、行頁數存儲結構、高頻詞匯存儲結構。

(1)順序存儲結構

包含單詞內容、單詞出現次數、行數、頁數,詳細如下表:

表3-1 順序存儲結構數據類型

數據項

數據類型

名稱

單詞內容

Char []

word

出現次數

Int

count

行、頁數

row_next *

row_head

順序表的邏輯結構:

圖 3-1  順序表的邏輯結構

(1)二叉樹存儲結構

包含單詞內容、單詞出現次數、指向行頁數的指針、指向左右結點的指針,詳細如下表:

表 3-2 二叉樹存儲結構數據類型

數據項

數據類型

名稱

單詞內容

Char []

word

出現次數

Int

count

行、頁數

row_next *

row_head

左孩子結點

struct DtList *

Lchild

右孩子結點

struct DtList *

Rchild

 二叉樹邏輯存儲結構如下圖:

圖 3-2 二叉樹邏輯存儲結構

(1)HASH表存儲結構

包含單詞內容、單詞出現次數、指向行頁數的指針, 詳細如下表:

表 3-3 HASH表存儲結構類型

數據項

數據類型

名稱

單詞內容

Char []

word

出現次數

Int

count

行、頁數

row_next *

row_head

指向下一個結點的指針

struct Link_Node *

next

 HASH表邏輯存儲結構如下圖:

(1)行頁數存儲結構

包含行數、頁數、指向下一個結點的指針,詳細如下表:

表 3-4 行頁存儲結構類型

數據項

數據類型

名稱

行數

Int

row

頁數

Int

page

指向下一個結點的指針

struct row_next *

next

 

行頁結構邏輯存儲結構如下圖:

(1)高頻詞匯存儲結構

包含單詞內容、出現次數,詳細如下表:

表 3-5 高頻詞匯存儲結構類型

數據項

數據類型

名稱

單詞

Char []

word

次數

int

count

 

 

高頻詞匯邏輯存儲結構:

 

3.1    主要算法設計

這部分主要描述系統中的模塊實現的流程,可采用文字配合流程圖的方式表示各模塊的算法思想及流程。

  1. 有序存儲

首先初始化有序表,讀取單詞,從原有的順序表中進行折半查找,如果找到了則進行單詞數增加,並記錄行頁數。如果沒有找到,則進行插入。流程圖如下圖:

  1. 無序存儲

無序表創建過程與有序表一樣,只是在查找的時候不能用折半查找來實現,只能從頭開始一一比較。

  1. 二叉搜索樹

二叉搜索樹實現,首先獲取內容取單詞,創建二叉樹,並在原來基礎上查找結點,找到了則進行單詞數目增加,並記錄行頁數。沒有找到則進行插入。讀取文件完成后進行輸出,根據用戶需求分別用三種遍歷來輸出,輸出完成后計算出高頻詞匯,進行輸出,最后記錄運行總時間。流程圖如下:

 

 

  1. HASH表

HASH表實現流程基本上也一樣,實現的具體函數功能有所不一樣。下圖是整體實現過程:

系統實現與測試

4.1   系統實現

  1. 結構體

(1)  順序存儲結構

包含單詞內容、單詞出現次數、指向行頁數的指針

      

 1  typedef struct
 2 
 3         {
 4 
 5                char word[MAX_CHARACTER];// 存儲單詞,不超過50個字符
 6 
 7                int count;               // 單詞出現次數
 8 
 9                row_next *row_head;      //指向行頁數的指針
10 
11                row_next *row_tail;      //指向最后一個(方便后序插入)
12 
13         } ElemType;
14 
15  
16 
17         typedef struct
18 
19         {
20 
21                ElemType *elem;      // 存儲空間基址
22 
23                int length;          // 當前長度
24 
25                int listsize;        // 當前分配的存儲容量
26 
27 } SqList;

 

(2)  搜索二叉樹存儲結構

包含單詞內容、單詞出現次數、指向行頁數的指針、指向左右結點的指針

       
 1 typedef struct
 2 
 3         {
 4 
 5             char word[MAX_CHARACTER];  // 存儲單詞,不超過50個字符
 6 
 7             int count;                 // 單詞出現次數
 8 
 9             row_next *row_head;        //指向行頁數的指針
10 
11             row_next *row_tail;        //指向最后一個(方便后序插入)
12 
13         }DtElemType;                   //數據類型
14 
15  
16 
17         typedef struct DtList
18 
19         {
20 
21             DtElemType elem;                  //存儲單詞
22 
23             struct DtList *Lchild,*Rchild;    //左孩子以及右孩子
24 
25 }DtList;

 

(3)  HASH表存儲結構

包含單詞內容、單詞出現次數、指向行頁數的指針

      
 1  typedef struct Link_Node
 2 
 3         {
 4 
 5             char word[MAX_CHARACTER];    // 存儲單詞,不超過50個字符
 6 
 7             int count;                   //單詞出現次數
 8 
 9             row_next *row_head;          //指向行頁數的指針
10 
11             row_next *row_tail;          //指向最后一個(方便后序插入)
12 
13             struct Link_Node *next;
14 
15         }Link_Node;
16 
17         
18 
19         typedef struct Hash_Header
20 
21         {
22 
23             Link_Node *Link_head;      //哈希表頭
24 
25 }Hash_Header;

 

(4)  行頁數存儲結構

包含行數、頁數

       
typedef struct row_next{

            int row;                 //行數

            int page;                //頁數

            struct row_next *next;  //指向下一個單詞的行數

}row_next;

 

下面分別介紹具體實現的函數:

  1. 取單詞  pickword

參數為文件地址,字符數組,行數。從文件地址所指的文件中依次讀取一個字符,一律轉換為小寫字符保存在目的單詞數組中。目的字符數組長度定義為50個字符,如果超過了進行返回。當遇到換行符時行數增加,遇到非字母字符時讀取結束,返回讀取到的單詞。具體過程如下圖:

 

  1. HASH_founc函數

實現HASH表時,哈希值用每一個單詞的第一個字符與第二個字符的ascll碼相加再與HASH表長度取余

  1. SqList_search_disorder無序表查找函數

實現無序表時,需要進行單詞的搜索,但這時候很難實現有效的查找算法,只能從表頭開始一一比較。

  1. SqListBSearch順序表二分法查找

實現有序表時,需要進行單詞的搜索,由於創建表時按照字母字典循序創建的,因此查找可以使用二分查找來實現,可以節省時間,效率高。

  1. SqListInit順序表初始化

構造一個空的順序表,分配內存,並初始化表長度,表大小。

  1. Dt_Free使用棧來實現釋放二叉搜索樹
  2. DtListInsert二叉樹插入

首先找到插入位置,再分別判斷是否有左右孩子,分情況分析最后創建結點並插入到對應位置。

  1. DtListPrint_preOrder前序遍歷

用非遞歸算法來實現,使用棧來實現。

  1. InOrderTraverse中序遍歷

遞歸算法來實現

  1. Dt_List_postOrder后序遍歷

遞歸算法來實現

系統測試

 1.程序運行界面

2.有序表開始計算

3.無序表開始計算

4.

二叉搜索樹中序遍歷

5.

二叉搜索樹前序遍

 

6.二叉搜索樹—后序遍

7.HASH表

8.搜索功能

9.保存

 

 

10.保存文件演示

11.行頁數

12.結果分析

 

 13.運行時間窗口演示

14.源代碼演示窗口

15.幫助選項

 

 

源代碼

 

  1 #ifndef FRMMAIN_H
  2 #define FRMMAIN_H
  3 
  4 #include <string.h>
  5 #include <QDialog>
  6 
  7 
  8 //函數結果狀態代碼
  9 #define TRUE    1
 10 #define FALSE   0
 11 #define OK      1
 12 #define ERROR   0
 13 #define OVERFLOW -2
 14 
 15 
 16 // 線性表的動態分配順序存儲結構
 17 #define LIST_INIT_SIZE 100  // 線性表存儲空間的初始分配量
 18 #define LISTINCREMENT 10    // 線性表存儲空間的分配增量
 19 #define HASH_TABLE_LEN  52  // HASH表長
 20 #define PAGE_LINE 26        //每個頁行數
 21 
 22 
 23 const int MAX_CHARACTER = 50;       // 單詞最大長度定為50(TUT.txt文中最長單詞為production-education-researching)
 24 
 25 //行數結構
 26 typedef struct row_next{
 27     int row;
 28     int page;
 29     struct row_next *next;  //指向下一個單詞的行數
 30 }row_next;
 31 
 32 // 順序存儲結構
 33 typedef struct
 34 {
 35     char word[MAX_CHARACTER];       // 存儲單詞,不超過50個字符
 36     int count;          // 單詞出現次數
 37     row_next *row_head;            //行數
 38     row_next *row_tail;  //指向最后一個
 39 } ElemType;
 40 typedef struct
 41 {
 42     ElemType *elem;     // 存儲空間基址
 43     int length;         // 當前長度
 44     int listsize;       // 當前分配的存儲容量(以sizeof(ElemType)為單位)
 45 } SqList;
 46 
 47 
 48 // 線性存儲結構
 49 typedef struct
 50 {
 51     char word[MAX_CHARACTER];       // 存儲單詞,不超過50個字符
 52     int count;          // 單詞出現次數
 53     row_next *row_head;   //行數
 54     row_next *row_tail;   //
 55 }DtElemType;//數據類型
 56 
 57 typedef struct DtList
 58 {
 59     DtElemType elem;        //存儲單詞
 60     struct DtList *Lchild,*Rchild;  //左孩子以及右孩子
 61 }DtList;
 62 
 63 
 64 //HASH表結構
 65 typedef struct Link_Node
 66 {
 67     char word[MAX_CHARACTER];       // 存儲單詞,不超過50個字符
 68     int count;                      //計數
 69     row_next *row_head;             //行數
 70     row_next *row_tail;             //
 71     struct Link_Node *next;
 72 }Link_Node;
 73 
 74 //哈希表頭
 75 typedef struct Hash_Header
 76 {
 77     Link_Node *Link_head;
 78 }Hash_Header;
 79 
 80 
 81 typedef struct High_count{
 82     char word[MAX_CHARACTER];
 83     int count;
 84 }High_count;
 85 
 86 
 87 
 88 class QLineEdit;
 89 namespace Ui {
 90 class frmMain;
 91 }
 92 
 93 class frmMain : public QDialog
 94 {
 95     Q_OBJECT
 96 
 97 public:
 98     explicit frmMain(QWidget *parent = 0);
 99     ~frmMain();
100     int SqListInit ( SqList *L );
101     int pickword ( FILE *f, char *fword ,int *row);
102     int SqListInsert ( SqList *L, int i, char *fword );
103     int SqList_insert_disorder(SqList *L,char *fword,int row);
104     int SqListBSearch ( SqList *L, char *sword, int &i );
105     int SqList_search_disorder(SqList *L, char *sword, int &i);
106     void SqListPrint(SqList *L);
107 
108     int DtListSearch(DtList *L, char *e,DtList **i);
109     int DtListInsert (DtList **L,char *fword,int row );
110     int DtListPrint_preOrder(DtList **L);
111     int Dt_Free(DtList **L);
112     int InOrderTraverse(DtList *L);
113     int Dt_List_postOrder(DtList *L);
114     int DtBiao_Creat(DtList **head);
115 
116     int HASH_func(char *word);
117     int hash_List_Search(Link_Node *L,char *fword,Link_Node **p );
118     int hash_List_Insert (Link_Node **L,char *fword ,int row);
119     void HASH_List_print(Hash_Header *L);
120 
121     void High_word(SqList *L);
122 
123 
124 protected:
125     bool eventFilter(QObject *obj, QEvent *event);
126     void mouseMoveEvent(QMouseEvent *e);
127     void mousePressEvent(QMouseEvent *e);
128     void mouseReleaseEvent(QMouseEvent *);
129 
130 private slots:
131     void on_btnMenu_Close_clicked();
132 
133     void on_btnMenu_Max_clicked();
134 
135     void on_btnMenu_Min_clicked();
136 
137     void on_pushButton_clicked();
138 
139     void on_pushButton_2_clicked();
140 
141     void on_pushButton_3_clicked();
142 
143     int OnBtnOpen();//打開文件
144 
145     void OnBtnSave();//保存計算結果
146 
147     int OnStart();//有序表--開始計算
148 
149     int SqList_disorder_start();//無序表--開始計算
150 
151     void textFind(); //查找文本
152 
153     void findNext(); //查找下一個
154 
155     void createPdf();//打印pdf
156 
157     void Dt_createPdf();//線性表打印pdf
158 
159     void hash_createPdf();//哈希表打印pdf
160 
161     int DtBiao_OnStart();//動態表開始計算按鈕
162 
163     void clearTbWidget();//清空表格內容
164 
165     void Dt_Clear();//動態表表格清空
166 
167     void Dt_BtnSave();//動態表保存
168 
169     int DtBiao_Onstart_preOrder();//前序遍歷
170 
171     int DtBiao_Onstart_PostOrder();//后序遍歷
172 
173     int on_Btn_HASH_start();//HASH表開始計算按鈕
174 
175     void hash_BtnSave();//HASH表保存
176 
177     void hash_Clear();//HASH表內容清空
178 
179 
180 
181 private:
182     Ui::frmMain *ui;
183 
184     QPoint mousePoint;
185     bool mousePressed;
186     bool max;
187     QRect location;
188 
189     void InitStyle();
190 
191     QLineEdit *lineEdit;
192 
193 };
194 
195 #endif // FRMMAIN_H

 

 

靜態表

 

  1 //函數結果狀態代碼
  2 #define TRUE    1
  3 #define FALSE   0
  4 #define OK      1
  5 #define ERROR   0
  6 #define OVERFLOW -2
  7 
  8 
  9 // 線性表的動態分配順序存儲結構
 10 #define LIST_INIT_SIZE 100  // 線性表存儲空間的初始分配量
 11 #define LISTINCREMENT 10    // 線性表存儲空間的分配增量
 12 #define HASH_TABLE_LEN  52 // HASH表長
 13 
 14 
 15 const int MAX_CHARACTER = 50;       // 單詞最大長度定為50(TUT.txt文中最長單詞為production-education-researching)
 16 
 17 //行數結構
 18 typedef struct row_next{
 19     int row;
 20     struct row_next *next;  //指向下一個單詞的行數
 21 }row_next;
 22 
 23 // 順序存儲結構
 24 typedef struct
 25 {
 26     char word[MAX_CHARACTER];       // 存儲單詞,不超過50個字符
 27     int count;          // 單詞出現次數
 28     row_next *row_head;            //行數
 29 } ElemType;
 30 typedef struct
 31 {
 32     ElemType *elem;     // 存儲空間基址
 33     int length;         // 當前長度
 34     int listsize;       // 當前分配的存儲容量(以sizeof(ElemType)為單位)
 35 } SqList;
 36 
 37 
 38 /***************************
 39 
 40   主要功能函數___順序表的實現
 41 
 42   *************************/
 43 
 44 int frmMain::OnStart()
 45 {
 46 int j=0,pronum=0;
 47 
 48     /*計算所消耗的時間---開始時間*/
 49     DWORDstart,stop,search_began,search_end,search_time=0,Insert_began,Insert_end,Insert_time=0, order_began,order_end,search_all_Time=0,insert_all_Time=0;
 50 
 51     start = GetTickCount();
 52 
 53     FILE *f1;
 54     FILE* fp=fopen("C:\Qt\src\QUI\linshi.txt","wb");
 55 
 56     QString str=ui->plainTextEdit->toPlainText();
 57     fprintf(fp,"%s",str.toStdString().c_str());
 58     fclose(fp);
 59 
 60     SqList L;               // 建立線性表
 61     SqListInit ( &L );          // 初始化順序表
 62 
 63     char fword[MAX_CHARACTER];    // 使用fword數組保存文件中的單詞
 64     fword[MAX_CHARACTER - 1] = '\0';
 65     int i = -1;             // 設置i為插入位置
 66     int row=1;
 67     row_next *row_p;
 68     f1=fopen("QtsrcQUIlinshi.txt","r");
 69 
 70     if(f1==NULL) return 0;
 71 
 72     while ( !feof ( f1 ) )      // 讀文件未結束
 73     {
 74         int judge = pickword ( f1, fword ,&row); // 從f指向的文件中提取單詞到fword中
 75 
 76         if ( -1 == judge )          // 數組越界時提示並退出
 77         {
 78             printf ( "存在單詞字符長度超過數組界限\n" );
 79             return -1;
 80         }
 81 
 82         search_began=GetTickCount();
 83         if ( SqListBSearch ( &L, fword, i ) )   // i返回插入位置或單詞在順序表中位置
 84         {
 85             search_end=GetTickCount();
 86 
 87             if(search_time<(search_end-search_began)){
 88                 search_time=search_end-search_began;
 89 
 90             }
 91 
 92             search_all_Time=search_all_Time+(search_end-search_began);
 93 
 94             //qDebug() << tr("search:%1 ms").arg(search_time);
 95 
 96             // 在順序表中找到該單詞
 97             L.elem[i].count++;          // 單詞出現次數加1
 98 
 99             row_p=(row_next *)malloc(sizeof(row_next));
100             row_p->row=row;
101             row_p->next=L.elem[i].row_head->next;
102             L.elem[i].row_head->next=row_p;
103         }
104         else
105         {
106             Insert_began=GetTickCount();
107 
108             // 順序表中未找到該單詞
109             SqListInsert ( &L, i, fword );      // 在第i個位置上插入
110             L.elem[i].row_head=(row_next *)malloc(sizeof(row_next));
111             L.elem[i].row_head->row=row;
112             L.elem[i].row_head->next=NULL;
113 
114             Insert_end=GetTickCount();
115 
116             if(Insert_time<Insert_end-Insert_began){
117                 Insert_time=Insert_end-Insert_began;
118             }
119 
120             insert_all_Time=insert_all_Time+(Insert_end-Insert_began);
121         }
122 
123     }
124 
125     /****程序運行結束,計算時間並顯示****/
126     stop = GetTickCount();
127     //printf("time: %lld ms\n", stop - start);
128 
129     QString str1=tr("創建時間: %1 ms").arg(stop - start);
130     ui->TimeLine->setText(str1);
131     str1=tr("折半:%1 ms,最長:%2 ms").arg(search_all_Time).arg(search_time);
132     ui->Sq_search_ltimeline->setText(str1);
133     str1=tr("插入:%1 ms,最長:%2 ms").arg(insert_all_Time).arg(Insert_time);
134     ui->Sq_insert_timeline->setText(str1);
135 
136 
137     /*****進度條****/
138     for(i=0;i<=5;i++){
139         //ui->progressBar->setValue(pronum);
140         //Sleep(1);
141         for(pronum=0;pronum<=100;pronum++){
142             ui->progressBar->setValue(pronum);
143             //Sleep(1);
144         }
145     }
146 
147     //
148     ui->tableWidget->clearContents();
149     for(j=ui->tableWidget->rowCount();j>=0;j--){
150 
151         ui->tableWidget->removeRow(j);
152     }
153 
154     order_began=GetTickCount();
155 
156     // 將結果寫入f2指向的文件中
157     SqListPrint ( &L );
158 
159     order_end=GetTickCount();
160 
161     str1=tr("遍歷時間 : %1 ms").arg(order_end-order_began);
162     ui->Sq_order_line->setText(str1);
163 
164     i=0;
165     while(i<ui->tableWidget->rowCount()/3){
166        QComboBox *comBox = new QComboBox();
167         while(L.elem[i].row_head){
168             comBox->addItem(tr("%1").arg(L.elem[i].row_head->row));
169             L.elem[i].row_head=L.elem[i].row_head->next;
170         }
171         ui->tableWidget->setCellWidget(i,2,comBox);
172         i++;
173     }
174     free(L.elem);
175     L.length=0;
176     L.listsize=0;
177 
178 }
179 
180 int frmMain::SqList_disorder_start(){
181 
182     int j=0,pronum=0;
183 
184 
185     /*計算所消耗的時間---開始時間*/
186     DWORD start, stop,search_began,search_end,search_time=0,Insert_began,Insert_end,Insert_time=0,
187             order_began,order_end,search_all_time=0,insert_all_time=0;
188 
189     start = GetTickCount();
190 
191     FILE *f1;
192     FILE* fp=fopen("C:\Qt\src\QUI\linshi3.txt","wb");
193 
194     QString str=ui->plainTextEdit->toPlainText();
195     fprintf(fp,"%s",str.toStdString().c_str());
196     fclose(fp);
197 
198     SqList L;               // 建立線性表
199     SqListInit ( &L );          // 初始化順序表
200 
201     char fword[MAX_CHARACTER];          // 使用fword數組保存文件中的單詞
202     fword[MAX_CHARACTER - 1] = '\0';
203     int i = -1;             // 設置i為插入位置
204     int row=1;
205     row_next *row_p;
206 
207     f1=fopen("QtsrcQUIlinshi3.txt","r");
208 
209     if(f1==NULL) return 0;
210 
211     while ( !feof ( f1 ) )      // 讀文件未結束
212     {
213         int judge = pickword ( f1, fword ,&row); // 從f指向的文件中提取單詞到fword中
214 
215         if ( -1 == judge )          // 數組越界時提示並退出
216         {
217             printf ( "存在單詞字符長度超過數組界限\n" );
218             return -1;
219         }
220 
221         search_began=GetTickCount();
222         if ( SqList_search_disorder ( &L, fword, i ) )   // i返回插入位置或單詞在順序表中位置
223         {
224             search_end=GetTickCount();
225 
226             if(search_time<(search_end-search_began)){
227                 search_time=search_end-search_began;
228             }
229 
230             search_all_time=search_all_time+(search_end-search_began);
231 
232             //qDebug() << tr("search:%1 ms").arg(search_time);
233 
234             // 在順序表中找到該單詞
235             L.elem[i].count++;          // 單詞出現次數加1
236 
237 //            row_p=L.elem[i].row_head;
238 //            while(row_p){
239 //                row_p=row_p->next;
240 //            }
241             row_p=(row_next *)malloc(sizeof(row_next));
242             row_p->row=row;
243             row_p->next=L.elem[i].row_head->next;
244             L.elem[i].row_head->next=row_p;
245         }
246         else
247         {
248             Insert_began=GetTickCount();
249 
250             // 順序表中未找到該單詞
251             SqList_insert_disorder ( &L,fword ,row);      // 插入
252 
253             Insert_end=GetTickCount();
254 
255             if(Insert_time<Insert_end-Insert_began){
256                 Insert_time=Insert_end-Insert_began;
257             }
258 
259             insert_all_time=insert_all_time+(Insert_end-Insert_began);
260         }
261 
262     }
263 
264     /****程序運行結束,計算時間並顯示****/
265     stop = GetTickCount();
266 
267 
268     QString str1=tr("創建時間: %1 ms").arg(stop - start);
269     ui->TimeLine->setText(str1);
270     str1=tr("查找:%1 ms,最長:%2 ms").arg(search_all_time).arg(search_time);
271     ui->Sq_search_ltimeline->setText(str1);
272     str1=tr("插入:%1 ms,最長:%2 ms").arg(insert_all_time).arg(Insert_time);
273     ui->Sq_insert_timeline->setText(str1);
274 
275 
276     /*****進度條****/
277     for(i=0;i<=5;i++){
278         //ui->progressBar->setValue(pronum);
279         //Sleep(1);
280         for(pronum=0;pronum<=100;pronum++){
281             ui->progressBar->setValue(pronum);
282             //Sleep(1);
283         }
284     }
285 
286     //
287     ui->tableWidget->clearContents();
288     for(j=ui->tableWidget->rowCount();j>=0;j--){
289 
290         ui->tableWidget->removeRow(j);
291     }
292 
293     order_began=GetTickCount();
294 
295     // 將結果
296     SqListPrint ( &L );
297 
298     order_end=GetTickCount();
299 
300     str1=tr("遍歷時間 : %1 ms").arg(order_end-order_began);
301     ui->Sq_order_line->setText(str1);
302 
303     i=0;
304     while(i<ui->tableWidget->rowCount()/3){
305        QComboBox *comBox = new QComboBox();
306         while(L.elem[i].row_head){
307             comBox->addItem(tr("%1").arg(L.elem[i].row_head->row));
308             L.elem[i].row_head=L.elem[i].row_head->next;
309         }
310         ui->tableWidget->setCellWidget(i,2,comBox);
311         i++;
312     }
313 
314     free(L.elem);
315     L.length=0;
316     L.listsize=0;
317 
318 }
319 
320 /*********SqList_search_disorder**********/
321 
322 int frmMain::SqList_search_disorder ( SqList *L, char *sword, int &i )
323 {
324     if ( L->length == 0 )            // 當順序表為空時
325     {
326         i = 0;                  // i返回單詞插入位置
327         return ERROR;
328     }
329 
330     // 順序表不空時,在順序表L中查找元素sword,用i返回其在順序表中的位置
331     int low = 0, high = L->length - 1;
332 
333     while ( low <= high )
334     {
335         if(strcmp ( L->elem[low].word, sword )==0){
336             i=low;
337             return OK;
338         }
339         else{
340             low++;
341         }
342     }
343 
344     return ERROR;           // 順序表中不存在待查元素,函數返回值為0,i返回單詞插入位置
345 }
346 
347 /***********SqList_insert_disorder************/
348 
349 // 順序表的插入
350 int frmMain::SqList_insert_disorder( SqList *L,char *fword ,int row)
351 {
352     // 在順序線性表L中第i個位置之前插入新的元素e
353     // i的合法值為1≤i≤L.Length + 1
354 //    if ( i < 0 || i > L->length )
355 //    {
356 //        //printf ( "i的值不合法!" );
357 //        return ERROR;   // i的值不合法
358 //    }
359 
360     int i=L->length;
361 
362     if ( L->length >= L->listsize )
363     {
364         // 當前存儲空間已滿,增加分配
365         ElemType *newbase = ( ElemType * ) realloc ( L->elem,
366                             ( L->listsize + LISTINCREMENT ) * sizeof ( ElemType ) );
367 
368         if ( !newbase )
369             return OVERFLOW;    // 存儲分配失敗
370 
371         L->elem = newbase;       // 新基址
372         L->listsize += LISTINCREMENT;    // 增加存儲容量
373     }
374 
375     ElemType *p, *q;
376     q = &L->elem[i];
377 
378     strcpy ( q->word, fword );           // 復制fword中的字符到L->elem[i-1].word中
379     L->elem[i].count = 1;            // 設置計數初值為1
380     L->length++;                     // 表長增1
381 
382     L->elem[i].row_head=(row_next *)malloc(sizeof(row_next));
383     L->elem[i].row_head->row=row;
384     L->elem[i].row_head->next=NULL;
385 
386     return OK;
387 }
388 
389 
390 
391 
392 /****將結果顯示到界面****/
393 void frmMain::SqListPrint(SqList *L){
394     int i=0,j=0;
395 
396     row_next *row_p;
397 
398     while(i<L->length){
399 
400        ui->tableWidget->insertRow(i);
401        ui->tableWidget->setItem(i,0,new QTableWidgetItem(L->elem[i].word));
402        ui->tableWidget->setItem(i,1,new QTableWidgetItem(QString("%1").arg(L->elem[i].count)));
403        //ui->tableWidget->setItem(i,2,new QTableWidgetItem(QString("%1").arg(L->elem[i].row_head->row)));
404        //ui->tableWidget->update(i,2,new QTableWidgetItem(QString("%1").arg(L->elem[i].row_head->next->row)));
405 
406        i++;
407         }
408 }
409 
410 
411 // 順序表的插入
412 int frmMain::SqListInsert ( SqList *L, int i, char *fword )
413 {
414     // 在順序線性表L中第i個位置之前插入新的元素e
415     // i的合法值為1≤i≤L.Length + 1
416     if ( i < 0 || i > L->length )
417     {
418         //printf ( "i的值不合法!" );
419         return ERROR;   // i的值不合法
420     }
421 
422     if ( L->length >= L->listsize )
423     {
424         // 當前存儲空間已滿,增加分配
425         ElemType *newbase = ( ElemType * ) realloc ( L->elem,
426                             ( L->listsize + LISTINCREMENT ) * sizeof ( ElemType ) );
427 
428         if ( !newbase )
429             return OVERFLOW;    // 存儲分配失敗
430 
431         L->elem = newbase;       // 新基址
432         L->listsize += LISTINCREMENT;    // 增加存儲容量
433     }
434 
435     ElemType *p, *q;
436     q = &L->elem[i];
437 
438     for ( p = &L->elem[L->length - 1]; p >= q; p-- )   // 插入位置之后元素逐個右移
439     {
440         * ( p + 1 ) = *p;
441     }
442 
443     strcpy ( q->word, fword );           // 復制fword中的字符到L->elem[i-1].word中
444     L->elem[i].count = 1;            // 設置計數初值為1
445     L->length++;                     // 表長增1
446     return OK;
447 }
448 
449 
450 // 順序表二分法查找
451 int frmMain::SqListBSearch ( SqList *L, char *sword, int &i )
452 {
453     if ( L->length == 0 )            // 當順序表為空時
454     {
455         i = 0;                  // i返回單詞插入位置
456         return ERROR;
457     }
458 
459     // 順序表不空時,在順序表L中查找元素sword,用i返回其在順序表中的位置
460     int low = 0, high = L->length - 1, mid = L->length;
461 
462     while ( low <= high )
463     {
464         mid = ( low + high ) / 2;
465         int k = strcmp ( L->elem[mid].word, sword );
466 
467         if ( k == 0 )           // 待查單詞sword等於中間值,找到待查元素
468         {
469             i = mid;
470             return OK;          // 查找成功,函數返回值為1,用i返回所查元素在順序表中的位置
471         }
472         else if ( k > 0 )        // 待查單詞sword小於中間值,繼續在前半區間進行查找
473         {
474             high = mid - 1;
475             i = low;
476         }
477         else                // 待查單詞sword大於中間值,繼續在后半區間進行查找
478         {
479             low = mid + 1;
480             i = high + 1;
481         }
482     }
483 
484     return ERROR;           // 順序表中不存在待查元素,函數返回值為0,i返回單詞插入位置
485 }
486 
487 int frmMain::pickword ( FILE *f, char *fword , int *row)       // 從f指向的文件中提取單詞到fword中
488 {
489     char ch;                    // ch儲存待檢測字符
490 
491     for ( int j = 0 , flag = 0 ; !feof ( f ) ; )    // 逐個對字符進行檢測,flag用於標記,為0時表示單詞中無字母
492     {
493         if ( j >= MAX_CHARACTER )            // 判斷數組是否越界
494         {
495             return -1;
496         }
497 
498         ch = fgetc ( f );              // 獲取字符
499 
500 
501         if ( ch >= 'A' && ch <= 'Z' )         // 大寫字符轉小寫保存在fword數組中
502         {
503             fword[j++] = ch + 32;
504             flag = 1;
505         }
506 
507         if ( ( ch >= 'a' && ch <= 'z' ) )     // 小寫字符保存在fword數組中
508         {
509             fword[j++] = ch;
510             flag = 1;
511         }
512 
513         if(ch=='\n')
514         {
515             (*row)++;
516             //return 0;
517         }
518 
519         if ( '-' == ch && fword[j - 1] >= 'a' && fword[j - 1] <= 'z' )    // 若單詞中帶連字符,將連字符保存在fword數組中
520         {
521             fword[j++] = ch;
522         }
523 
524 
525 
526         if ( ! ( ( ch >= 'A' && ch <= 'Z' ) || ( ch >= 'a' && ch <= 'z' ) || '-' == ch )
527                 && flag == 1 )              // 過濾單詞中的非字母字符
528         {
529             if ( fword[j - 1] == '-' )          // 排除類似於 a- 的單詞
530                 fword[j - 1] = '\0';
531 
532             fword[j] = '\0';                // fword數組以'\0'結尾
533             return 0;
534         }
535 
536 
537     }
538 }
539 
540 
541 // 順序表的初始化
542 int frmMain::SqListInit ( SqList *L )
543 {
544     // 構造一個空的順序表L
545     L->elem = ( ElemType * ) malloc ( LIST_INIT_SIZE * sizeof ( ElemType ) );
546 
547     if ( !L->elem ) return OVERFLOW;     // 存儲分配失敗
548 
549     L->length = 0;
550     L->listsize = LIST_INIT_SIZE;
551     return OK;
552 }

 

 

搜索二叉樹

 

  1 int frmMain::DtBiao_OnStart(){
  2 
  3     DWORD began,end;
  4 
  5     DtList *L;               // 建立線性表
  6     L=(DtList*)malloc(sizeof(DtList));//給頭指針分配內存
  7     strcpy(L->elem.word," ");
  8     L->elem.count=0;
  9     L->Lchild=L->Rchild=NULL;//左右孩子初始化
 10 
 11     DtBiao_Creat(&L);        //創建二叉樹
 12 
 13     began=GetTickCount();
 14     InOrderTraverse(L);     //中序遍歷
 15     end=GetTickCount();
 16 
 17     QString str=tr("中序: %1 ms").arg(end-began);
 18     ui->Dt_order_line->setText(str);
 19 
 20     Dt_Free(&L);            //釋放內存
 21 
 22 }
 23 
 24 int frmMain::DtBiao_Onstart_preOrder(){
 25 
 26     DWORD began,end;
 27 
 28     DtList *L;               // 建立線性表
 29     L=(DtList*)malloc(sizeof(DtList));//給頭指針分配內存
 30     strcpy(L->elem.word," ");
 31     L->elem.count=0;
 32     L->Lchild=L->Rchild=NULL;//左右孩子初始化
 33 
 34     DtBiao_Creat(&L);           //創建二叉樹
 35 
 36     began=GetTickCount();
 37     DtListPrint_preOrder(&L);   //前序遍歷
 38     end=GetTickCount();
 39 
 40     QString str1=tr("前序: %1 ms").arg(end-began);
 41     ui->Dt_order_line->setText(str1);
 42 
 43     Dt_Free(&L);        //釋放內存
 44 }
 45 
 46 int frmMain::DtBiao_Onstart_PostOrder(){
 47     DWORD began,end;
 48 
 49     DtList *L;               // 建立線性表
 50     L=(DtList*)malloc(sizeof(DtList));//給頭指針分配內存
 51     strcpy(L->elem.word," ");
 52     L->elem.count=0;
 53     L->Lchild=L->Rchild=NULL;//左右孩子初始化
 54 
 55     DtBiao_Creat(&L);       //創建二叉樹
 56 
 57     began=GetTickCount();
 58     Dt_List_postOrder(L);       //后序遍歷
 59     end=GetTickCount();
 60 
 61     QString str1=tr("后序: %1 ms").arg(end-began);
 62     ui->Dt_order_line->setText(str1);
 63 
 64     Dt_Free(&L);    //釋放內存
 65 }
 66 
 67 
 68 /*******二叉搜索樹創建*********/
 69 int frmMain::DtBiao_Creat(DtList **head){
 70 
 71     DtList *L=*head;
 72 
 73     int j=0,pronum=0,y=0,flag=0;
 74 
 75     /*****tablewidget 表格內容清理******/
 76     ui->DtBiao_tableWidget->clearContents();
 77     for(j=ui->DtBiao_tableWidget->rowCount();j>=0;j--){
 78 
 79         ui->DtBiao_tableWidget->removeRow(j);
 80     }
 81 
 82 
 83     /*****進度條****/
 84     for(y=0;y<=2;y++){
 85         Sleep(1);
 86         for(pronum=0;pronum<=75;pronum++){
 87             ui->progressBar->setValue(pronum);
 88             //Sleep(1);
 89         }
 90     }
 91 
 92 
 93     /*計算所消耗的時間---*/
 94     DWORD   start_create,           /*創建哈希表開始時間*/
 95             stop_create,            /*創建哈希表結束時間*/
 96             search_began_dt,        /*搜索開始時間*/
 97             search_end_dt,          /*搜索結束時間*/
 98             search_time_dt=0,       /*搜索時間*/
 99             Insert_began_dt,        /*插入開始時間*/
100             Insert_end_dt,          /*插入結束時間*/
101             Insert_time_dt=0,       /*插入時間*/
102             search_all_time=0,      /*搜索總時間*/
103             insert_all_time=0;      /*插入總時間*/
104 
105     start_create = GetTickCount();
106 
107     FILE *f1;
108     FILE* fp=fopen("C:\Qt\src\QUI\linshi2.txt","wb");
109 
110     QString str=ui->DtBiao_Plaintext->toPlainText();
111     fprintf(fp,"%s",str.toStdString().c_str());     //把獲取的內容寫進本地txt文件里面
112     fclose(fp);
113 
114 
115 
116     char fword[MAX_CHARACTER];          // 使用fword數組保存文件中的單詞
117     fword[MAX_CHARACTER - 1] = '\0';
118     DtList *i = NULL;             // 設置i為插入位置
119     int row=1;
120     row_next *row_p;
121 
122 
123     f1=fopen("QtsrcQUIlinshi2.txt","r");
124 
125     if(f1==NULL) return 0;
126 
127     while ( !feof ( f1 ) )      // 讀文件未結束
128     {
129 
130         int judge = pickword ( f1, fword ,&row); // 從f指向的文件中提取單詞到fword中
131 
132         if(flag==0){    //根結點
133             strcpy(L->elem.word,fword);
134             L->elem.count=1;
135             L->elem.row_head=(row_next *)malloc(sizeof(row_next));
136             L->elem.row_head->row=row%PAGE_LINE;
137             L->elem.row_head->page=row/PAGE_LINE+1;
138             L->elem.row_head->next=NULL;
139             L->elem.row_tail=L->elem.row_head;
140             flag=1;
141             continue;
142         }else{
143             if ( -1 == judge )          // 數組越界時提示並退出
144             {
145                 printf ( "存在單詞字符長度超過數組界限\n" );
146                 return -1;
147             }
148 
149             if( -2 == judge ){
150                 continue;       //如果是換行符、文件結束符(-1/255)
151             }
152 
153             search_began_dt=GetTickCount();
154             if ( DtListSearch ( L, fword, &i ) )   // i返回插入位置或單詞在線性表中位置
155             {
156                 search_end_dt=GetTickCount();
157 
158                 if(search_time_dt<(search_end_dt-search_began_dt)){
159                     search_time_dt=search_end_dt-search_began_dt;      //記錄最長時間
160                 }
161 
162                 search_all_time=search_all_time+(search_end_dt-search_began_dt);//記錄總搜索時間
163 
164                 // 在線性表中找到該單詞
165                 i->elem.count++;          // 單詞出現次數加1
166 
167                 row_p=(row_next *)malloc(sizeof(row_next));     //為新單詞的行數頁數分配空間
168                 row_p->row=row%PAGE_LINE;   //獲取當前總行數,並計算賦值
169                 row_p->page=row/PAGE_LINE+1;//頁數
170                 row_p->next=NULL;
171                 i->elem.row_tail->next=row_p;//添加到尾指針的next
172                 i->elem.row_tail=i->elem.row_tail->next;//尾指針指向最后
173             }
174             else
175             {
176                 Insert_began_dt=GetTickCount();
177                 // 順序表中未找到該單詞
178                 DtListInsert ( &L,fword,row );      // 插入
179 
180                 Insert_end_dt=GetTickCount();
181 
182                 if(Insert_time_dt<(Insert_end_dt-Insert_began_dt)){
183                     Insert_time_dt=Insert_end_dt-Insert_began_dt;//最長插入時間
184                 }
185                 //插入總時間
186                 insert_all_time=insert_all_time+(Insert_end_dt-Insert_began_dt);
187             }
188 
189         }
190 
191     }
192 
193     /****程序運行結束,計算時間並顯示****/
194     stop_create = GetTickCount();
195 
196     //qDebug() << tr("shijian:%1 ms").arg(stop - start);
197     QString str1=tr("創建時間:%1 ms").arg(stop_create - start_create);
198     ui->DtBiao_TimeLine->setText(str1);
199     str1=tr("搜索:%1 ms,最長:%2 ms").arg(search_all_time).arg(search_time_dt);
200     ui->Dt_search_ltimeline->setText(str1);
201     str1=tr("插入:%1 ms,最長:%2 ms").arg(insert_all_time).arg(Insert_time_dt);
202     ui->Dt_insert_timeline->setText(str1);
203 
204 
205     /*****進度條****/
206     for(y=0;y<=1;y++){
207         Sleep(1);
208         for(pronum=0;pronum<=100;pronum++){
209             ui->progressBar->setValue(pronum);
210             //Sleep(1);
211         }
212     }
213 
214 
215 }
216 
217 
218 
219 /**free Destroy***
220 
221 使用棧來實現釋放二叉搜索樹
222 
223 *****************/
224 int frmMain::Dt_Free(DtList **L){
225     int top = -1;
226     DtList *stack[1000], *p, *q;
227     p = *L;
228     if (p == NULL){
229             free(*L);
230             return OK;
231     }
232     stack[++top] = *L;
233     while (top>-1) {
234             p = stack[top--];
235             q = p;
236             if (p->Rchild)  //釋放右孩子
237                     stack[++top] = p->Rchild;
238             if (p->Lchild)  //是放左孩子
239                     stack[++top] = p->Lchild;
240             free(q);    //釋放頭節點
241     }
242 
243  return OK;
244 }
245 
246 /*******二叉樹搜索********/
247 int frmMain::DtListSearch(DtList *T, char *e,DtList **i){
248         int top = -1;
249         DtList *stack[1000], *p;
250         p = T;
251         if(strcmp(p->elem.word,e)==0){
252             *i=p;
253             return 1;
254         }
255         //首元素進棧
256         stack[++top] = T;
257         while (top>-1) {
258                 p = stack[top--];
259                 if (p->Rchild) {
260                     if (strcmp(p->Rchild->elem.word,e) == 0){
261                         *i=p->Rchild;   //如果找到了則返回該結點地址
262                         return 1;
263                     }
264                 stack[++top] = p->Rchild;//不一樣則進棧
265                 }
266                 if (p->Lchild) {
267                     if (strcmp(p->Lchild->elem.word,e) == 0){
268                         *i=p->Lchild;   ////如果找到了則返回該結點地址
269                         return 1;
270                     }
271                 stack[++top] = p->Lchild;//不一樣則進棧
272                 }
273         }
274         //free(stack);
275 return 0;
276 }
277 
278 /********二叉樹插入********/
279 int frmMain::DtListInsert(DtList **L, char *fword,int row){
280 
281     DtList *p=*L,*q;
282 
283     while(p){       //首先找到插入位置
284         q=p;
285         if(strcmp(p->elem.word,fword)<0){
286 
287             p=p->Rchild;
288             continue;
289         }
290         if(strcmp(p->elem.word,fword)>0){
291             p=p->Lchild;
292             continue;
293         }
294         if(strcmp(p->elem.word,fword)==0){
295             break;
296         }
297 
298     }
299     if(q->Lchild){      //如果有左孩子,且右孩子為空
300         if(q->Rchild==NULL){
301             q->Rchild=(DtList*)malloc(sizeof(DtList));
302             q->Rchild->Lchild=q->Rchild->Rchild=NULL;
303             strcpy(q->Rchild->elem.word,fword);
304             q->Rchild->elem.count=1;
305 
306             q->Rchild->elem.row_head=(row_next *)malloc(sizeof(row_next));
307             q->Rchild->elem.row_head->row=row%PAGE_LINE;
308             q->Rchild->elem.row_head->page=row/PAGE_LINE+1;
309             q->Rchild->elem.row_head->next=NULL;
310             q->Rchild->elem.row_tail=q->Rchild->elem.row_head;
311             return 1;
312         }
313     }
314     if(q->Rchild){      //如果有右孩子,且左孩子為空
315         if(q->Lchild==NULL){
316             q->Lchild=(DtList*)malloc(sizeof(DtList));
317             q->Lchild->Lchild=q->Lchild->Rchild=NULL;
318             strcpy(q->Lchild->elem.word,fword);
319             q->Lchild->elem.count=1;
320 
321             q->Lchild->elem.row_head=(row_next *)malloc(sizeof(row_next));
322             q->Lchild->elem.row_head->row=row%PAGE_LINE;
323             q->Lchild->elem.row_head->page=row/PAGE_LINE+1;
324             q->Lchild->elem.row_head->next=NULL;
325             q->Lchild->elem.row_tail=q->Lchild->elem.row_head;
326             return 1;
327         }
328     }
329     if(q->Lchild==NULL && q->Rchild==NULL){     //如果是葉子結點
330 
331         if(strcmp(q->elem.word,fword)<0){       //插入到左孩子
332             q->Rchild=(DtList*)malloc(sizeof(DtList));
333             q->Rchild->Lchild=q->Rchild->Rchild=NULL;
334             strcpy(q->Rchild->elem.word,fword);
335             q->Rchild->elem.count=1;
336 
337             q->Rchild->elem.row_head=(row_next *)malloc(sizeof(row_next));
338             q->Rchild->elem.row_head->row=row%PAGE_LINE;
339             q->Rchild->elem.row_head->page=row/PAGE_LINE+1;
340             q->Rchild->elem.row_head->next=NULL;
341             q->Rchild->elem.row_tail=q->Rchild->elem.row_head;
342             return 1;
343         }
344         else{       //插入到右孩子
345             q->Lchild=(DtList*)malloc(sizeof(DtList));
346             q->Lchild->Lchild=q->Lchild->Rchild=NULL;
347             strcpy(q->Lchild->elem.word,fword);
348             q->Lchild->elem.count=1;
349 
350             q->Lchild->elem.row_head=(row_next *)malloc(sizeof(row_next));
351             q->Lchild->elem.row_head->row=row%PAGE_LINE;
352             q->Lchild->elem.row_head->page=row/PAGE_LINE+1;
353             q->Lchild->elem.row_head->next=NULL;
354             q->Lchild->elem.row_tail=q->Lchild->elem.row_head;
355             return 1;
356         }
357     }
358 
359     return 0;
360 }
361 
362 /*********preOrder********/
363 int frmMain::DtListPrint_preOrder(DtList **Q){
364     DtList *stack[1000],*p,*L=*Q;
365     long all_count=0;
366     int top=-1,i=0,HIGH_LENTH=100,j;
367     High_count high_word[HIGH_LENTH],*r,*q;     //高頻詞匯數組
368 
369     while(i<HIGH_LENTH){
370         high_word[i].count=0;       //初始化
371         i++;
372     }
373 
374     i=0;
375     p=L;
376     stack[++top]=L;     //首元素進棧
377 
378     while (top>-1) {
379         p = stack[top--];
380         ui->DtBiao_tableWidget->insertRow(i);//插入新行
381         ui->DtBiao_tableWidget->setItem(i,0,new QTableWidgetItem(p->elem.word));
382         ui->DtBiao_tableWidget->setItem(i,1,new QTableWidgetItem(QString("%1").arg(p->elem.count)));
383         ui->DtBiao_tableWidget->setItem(i,2,new QTableWidgetItem(QString(" ( %1 , %2 )").arg(p->elem.row_head->row).arg(p->elem.row_head->page)));
384         all_count+=p->elem.count;//所有單詞求和
385 
386         //如果當前單詞出現次數比高頻詞匯數組的最后一個元素大,則進行插入
387         if(p->elem.count>high_word[HIGH_LENTH-1].count){
388             j=0;
389             while(j<HIGH_LENTH){
390                 if(p->elem.count>high_word[j].count){
391                     q=&high_word[j];
392                     for ( r = &high_word[HIGH_LENTH-1]; r >= q; r-- )   // 插入位置之后元素逐個右移
393                     {
394                         * ( r + 1 ) = *r;
395                     }
396                     high_word[j].count=p->elem.count;
397                     strcpy(high_word[j].word,p->elem.word);
398                     break;
399                 }
400                 j++;
401             }
402 
403         }
404 //        if(i<100){
405 //            QComboBox *comBox = new QComboBox();
406 //            while(p->elem.row_head!=p->elem.row_tail->next){
407 //                comBox->addItem(tr(" ( %1 , %2 )").arg(p->elem.row_head->row).arg(p->elem.row_head->page));
408 //                p->elem.row_head=p->elem.row_head->next;
409 //            }
410 //            ui->DtBiao_tableWidget->setCellWidget(i,2,comBox);
411 //        }
412         i++;
413         if (p->Rchild)
414              stack[++top] = p->Rchild;//右孩子進棧
415         if (p->Lchild)
416              stack[++top] = p->Lchild;//左孩子進棧
417     }
418     ui->DtBiao_tableWidget->setItem(0,5,new QTableWidgetItem(QString("總種類:%1").arg(i)));
419     ui->DtBiao_tableWidget->setItem(1,5,new QTableWidgetItem(QString("總單詞:%1").arg(all_count)));
420 
421     i=0;
422     while(i<HIGH_LENTH){//高頻詞匯
423         if(high_word[i].count>1){
424             ui->DtBiao_tableWidget->setItem(i,3,new QTableWidgetItem(high_word[i].word));
425             ui->DtBiao_tableWidget->setItem(i,4,new QTableWidgetItem(QString("%1").arg(high_word[i].count)));
426         }
427        i++;
428         }
429 }
430 
431 /**********InOrder**********/
432 int frmMain::InOrderTraverse(DtList *T){
433     int i=0;
434 
435         if(T!=NULL){
436                 InOrderTraverse(T->Rchild);
437                 ui->DtBiao_tableWidget->insertRow(i);
438                 ui->DtBiao_tableWidget->setItem(i,0,new QTableWidgetItem(T->elem.word));
439                 ui->DtBiao_tableWidget->setItem(i,1,new QTableWidgetItem(QString("%1").arg(T->elem.count)));
440                 ui->DtBiao_tableWidget->setItem(i,2,new QTableWidgetItem(QString(" ( %1 , %2 )").arg(T->elem.row_head->row).arg(T->elem.row_head->page)));
441                 /*
442                 if(i<500){
443                     QComboBox *comBox = new QComboBox();
444                     while(T->elem.row_head){
445                         comBox->addItem(tr("%1").arg(T->elem.row_head->row));
446                         T->elem.row_head=T->elem.row_head->next;
447                     }
448                     ui->DtBiao_tableWidget->setCellWidget(i,2,comBox);
449                 }
450                 */
451                 InOrderTraverse(T->Lchild);
452                 return OK;
453         }
454         return FALSE;
455 }
456 
457 /************postOrder**************/
458 int frmMain::Dt_List_postOrder(DtList *T){
459     int i=0;
460         if (T != NULL) {
461                 Dt_List_postOrder(T->Lchild);
462                 Dt_List_postOrder(T->Rchild);
463                 ui->DtBiao_tableWidget->insertRow(i);
464                 ui->DtBiao_tableWidget->setItem(i,0,new QTableWidgetItem(T->elem.word));
465                 ui->DtBiao_tableWidget->setItem(i,1,new QTableWidgetItem(QString("%1").arg(T->elem.count)));
466                 ui->DtBiao_tableWidget->setItem(i,2,new QTableWidgetItem(QString(" ( %1 , %2 )").arg(T->elem.row_head->row).arg(T->elem.row_head->page)));
467 /*
468                 if(i<500){
469                     QComboBox *comBox = new QComboBox();
470                     while(T->elem.row_head){
471                         comBox->addItem(tr("%1").arg(T->elem.row_head->row));
472                         T->elem.row_head=T->elem.row_head->next;
473                     }
474                     ui->DtBiao_tableWidget->setCellWidget(i,2,comBox);
475                 }*/
476                 return OK;
477         }
478 return FALSE;
479 }

 

 

HASH表

 

  1 /******************************
  2 
  3           HASH表實現
  4 
  5   *******************************/
  6 
  7 
  8 /***哈希表遍歷****/
  9 void frmMain::HASH_List_print(Hash_Header *L){
 10 
 11     long all_count=0;
 12     int i=0,j=0,HIGH_LENTH=100,w;
 13     Link_Node *p=NULL;
 14     High_count high_word[HIGH_LENTH],*r,*q;
 15 
 16     while(i<HIGH_LENTH){
 17         high_word[i].count=0;
 18         i++;
 19     }
 20 
 21     for(i=0;i<HASH_TABLE_LEN;i++){
 22         p=L[i].Link_head;//頭指針
 23         while(p){/*當p不為空時*/
 24             ui->HASH_tableWidget->insertRow(j);//給表格添加新行
 25             ui->HASH_tableWidget->setItem(j,0,new QTableWidgetItem(p->word));
 26             ui->HASH_tableWidget->setItem(j,1,new QTableWidgetItem(QString("%1").arg(p->count)));
 27             ui->HASH_tableWidget->setItem(j,2,new QTableWidgetItem(QString(" ( %1 , %2 )").arg(p->row_head->row).arg(p->row_head->page)));
 28 
 29             all_count+=p->count;//所有單詞求和
 30 
 31             //如果當前單詞出現次數比高頻詞匯數組的最后一個元素大,則進行插入
 32             if(p->count>high_word[HIGH_LENTH-1].count){
 33                 w=0;
 34                 while(w<HIGH_LENTH){
 35                     if(p->count>high_word[w].count){
 36                         q=&high_word[w];
 37                         for ( r = &high_word[HIGH_LENTH-1]; r >= q; r-- )   // 插入位置之后元素逐個右移
 38                         {
 39                             * ( r + 1 ) = *r;
 40                         }
 41                         high_word[w].count=p->count;
 42                         strcpy(high_word[w].word,p->word);
 43                         break;
 44                     }
 45                     w++;
 46                 }
 47             }
 48 
 49 //            if(j<10){
 50 //                QComboBox *comBox = new QComboBox();
 51 //                while(p->row_head!=p->row_tail->next){
 52 //                    comBox->addItem(tr(" ( %1 , %2 )").arg(p->row_head->row).arg(p->row_head->page));
 53 //                    p->row_head=p->row_head->next;
 54 //                }
 55 //                ui->HASH_tableWidget->setCellWidget(j,2,comBox);
 56 //            }
 57 
 58             j++;//給表格添加新行
 59             p=p->next;
 60         }
 61     }
 62 
 63     ui->HASH_tableWidget->setItem(0,5,new QTableWidgetItem(QString("總種類:%1").arg(j)));
 64     ui->HASH_tableWidget->setItem(1,5,new QTableWidgetItem(QString("總單詞:%1").arg(all_count)));
 65 
 66     i=0;
 67     while(i<HIGH_LENTH){
 68         if(high_word[i].count>1){
 69             ui->HASH_tableWidget->setItem(i,3,new QTableWidgetItem(high_word[i].word));
 70             ui->HASH_tableWidget->setItem(i,4,new QTableWidgetItem(QString("%1").arg(high_word[i].count)));
 71         }
 72        i++;
 73     }
 74 
 75 
 76 }
 77 
 78 /***計算哈希值***
 79 
 80   取單詞的第一、二字符,把他們的ASCLL值求和並對表長取余
 81 
 82 ***************/
 83 int frmMain::HASH_func(char *word){
 84 
 85     int hash=0;
 86 
 87     if(strlen(word)==1){
 88         hash=word[0]%HASH_TABLE_LEN;
 89         return hash;
 90     }else{
 91         hash=(word[0]+word[1])%HASH_TABLE_LEN;
 92         return hash;
 93     }
 94 
 95 return -1;
 96 }
 97 
 98 /***搜索哈希值對應線性表***/
 99 int frmMain::hash_List_Search(Link_Node *L, char *fword, Link_Node **p){
100 
101     Link_Node *q=L;
102 
103     while(q){
104         if(strcmp(q->word,fword)==0){
105             *p=q;
106             return 1;//如果找到則返回
107         }
108         q=q->next;
109     }
110 return 0;
111 }
112 
113 /****哈希表插入****
114 
115   以后進先出的方式
116 
117 ****************/
118 int frmMain::hash_List_Insert(Link_Node **L, char *fword,int row){
119 
120     Link_Node *p=*L,*q;
121 
122     if((*L)==NULL){
123         *L=(Link_Node*)malloc(sizeof(Link_Node));
124         (*L)->count=1;
125         (*L)->next=NULL;
126         strcpy((*L)->word,fword);
127 
128         (*L)->row_head=(row_next*)malloc(sizeof(row_next));
129         (*L)->row_head->row=row%PAGE_LINE;
130         (*L)->row_head->page=row/PAGE_LINE+1;
131         (*L)->row_head->next=NULL;
132         (*L)->row_tail=(*L)->row_head;
133         return 1;
134     }else{
135 
136         q=(Link_Node*)malloc(sizeof(Link_Node));
137         q->count=1;
138 
139         q->row_head=(row_next*)malloc(sizeof(row_next));
140         q->row_head->row=row%PAGE_LINE;
141         q->row_head->page=row/PAGE_LINE+1;
142         q->row_head->next=NULL;
143         q->row_tail=q->row_head;
144 
145         q->next=(*L)->next;
146         strcpy(q->word,fword);
147         (*L)->next=q;
148         return 1;
149     }
150 
151 return 0;
152 
153 }
154 
155 int frmMain::on_Btn_HASH_start(){
156 
157     /*計算所消耗的時間---*/
158     DWORD start_create,     /*創建哈希表開始時間*/
159           stop_create,      /*創建哈希表結束時間*/
160           search_began_dt,  /*搜索開始時間*/
161           search_end_dt,    /*搜索結束時間*/
162           search_time_dt=0, /*搜索時間*/
163           Insert_began_dt,  /*插入開始時間*/
164           Insert_end_dt,    /*插入結束時間*/
165           Insert_time_dt=0, /*插入時間*/
166           search_all_time=0,/*搜索總時間*/
167           insert_all_time=0,/*插入總時間*/
168           order_began_hash, /*遍歷開始時間*/
169           order_end_hash;   /*遍歷結束時間*/
170 
171     start_create = GetTickCount();//創建哈希表開始計時
172 
173 
174     Hash_Header L[HASH_TABLE_LEN];//哈希表數組聲明
175 
176     int i,j=0,pronum=0,y=0;
177 
178     /*哈希表數組初始化*/
179     for(i=0;i<HASH_TABLE_LEN;i++){
180         L[i].Link_head=NULL;
181     }
182 
183     /*清空表格內容*/
184     ui->HASH_tableWidget->clearContents();
185     for(j=ui->HASH_tableWidget->rowCount();j>=0;j--){
186 
187         ui->HASH_tableWidget->removeRow(j);
188     }
189 
190 
191     /*****進度條****/
192     for(y=0;y<=2;y++){
193         //ui->progressBar->setValue(pronum);
194         Sleep(1);
195         for(pronum=0;pronum<=75;pronum++){
196             ui->progressBar->setValue(pronum);
197             //Sleep(1);
198         }
199     }
200 
201 
202     FILE *f1;
203     FILE* fp=fopen("C:\Qt\src\QUI\linshi4.txt","wb");
204 
205     QString str=ui->HaSH_Plaintext->toPlainText();  //從plaintext中讀取用戶輸入的數據
206     fprintf(fp,"%s",str.toStdString().c_str());     //把讀取到的文本內容臨時保存到text文件
207     fclose(fp); //關閉文件
208 
209     char fword[MAX_CHARACTER];          // 使用fword數組保存文件中的單詞
210     fword[MAX_CHARACTER - 1] = '\0';    //字符串數組最后以'\0'結束
211     Link_Node *p = NULL;             // 設置p為在HASH 表中的位置
212     int hash_value=-1;              //hash_value 為對應單詞哈希值
213     int row=1;
214     row_next *row_p;
215 
216 
217     f1=fopen("QtsrcQUIlinshi4.txt","r");
218 
219     if(f1==NULL) return 0;
220 
221     while ( !feof ( f1 ) )      // 讀文件未結束
222     {
223 
224         int judge = pickword ( f1, fword ,&row); // 從f指向的文件中提取單詞到fword中
225 
226         if ( -1 == judge )          // 數組越界時跳過該單詞
227         {
228             continue;
229         }
230 
231         if ( -2 == judge ){
232             continue;
233         }
234 
235         hash_value=HASH_func(fword);   //計算哈希值
236 
237         //qDebug() << tr("hash_value:%1 ms").arg(hash_value);
238 
239         if(hash_value==-1)      /**無單詞***/
240             return 0;
241 
242         search_began_dt=GetTickCount();/*搜索開始計時*/
243 
244         if ( hash_List_Search ( L[hash_value].Link_head, fword, &p ) )
245         {
246             search_end_dt=GetTickCount();/*搜索結束計時*/
247 
248             /*記錄最長時間*/
249             if(search_time_dt<(search_end_dt-search_began_dt)){
250                 search_time_dt=search_end_dt-search_began_dt;
251             }
252             /*記錄總時間*/
253             search_all_time=search_all_time+(search_end_dt-search_began_dt);
254 
255             // 在HASH表中找到該單詞
256             p->count++;          // 單詞出現次數加1
257 
258             row_p=(row_next*)malloc(sizeof(row_next));
259             row_p->row=row%PAGE_LINE;
260             row_p->page=row/PAGE_LINE+1;
261             p->row_tail->next=row_p;
262             p->row_tail=p->row_tail->next;
263         }
264         else
265         {
266             /*插入開始計時*/
267             Insert_began_dt=GetTickCount();
268 
269             // HASH表中未找到該單詞
270             hash_List_Insert ( &(L[hash_value].Link_head),fword,row);      // 插入
271 
272             /*插入結束計時*/
273             Insert_end_dt=GetTickCount();
274 
275             /*記錄最長時間*/
276             if(Insert_time_dt<(Insert_end_dt-Insert_began_dt)){
277                 Insert_time_dt=Insert_end_dt-Insert_began_dt;
278             }
279 
280             /*記錄總時間*/
281             insert_all_time=insert_all_time+(Insert_end_dt-Insert_began_dt);
282         }
283 
284     }
285     fclose(f1);//關閉文件
286 
287     order_began_hash=GetTickCount();/*遍歷開始計時*/
288 
289 //    j=0;
290 //    for(i=0;i<HASH_TABLE_LEN;i++){
291 //        p=L[i].Link_head;
292 //        while(p){
293 //            ui->HASH_tableWidget->insertRow(j);
294 //        ui->HASH_tableWidget->setItem(j,0,new QTableWidgetItem(p->word));
295 //ui->HASH_tableWidget->setItem(j,1,newQTableWidgetItem(QString("%1").arg(p->count)));
296 //ui->HASH_tableWidget->setItem(j,2,newQTableWidgetItem(QString("( %1 , %2 )").arg(p->row_head->row).arg(p->row_head->page)));
297 //            j++;
298 //            p=p->next;
299 //        }
300 //    }
301 
302     order_end_hash=GetTickCount();/*遍歷結束計時*/
303 
304 
305     /*****進度條****/
306     for(y=0;y<=1;y++){
307         Sleep(1);
308         for(pronum=0;pronum<=100;pronum++){
309             ui->progressBar->setValue(pronum);
310             //Sleep(1);
311         }
312     }
313 
314     /****程序運行結束,計算時間並顯示****/
315     stop_create = GetTickCount();
316     QString str1=tr("創建時間:%1 ms").arg(stop_create - start_create);
317     ui->HASH_TimeLine->setText(str1);
318     str1=tr("搜索:%1 ms,最長:%2 ms").arg(search_all_time).arg(search_time_dt);
319     ui->hash_search_ltimeline->setText(str1);
320     str1=tr("插入:%1 ms,最長:%2 ms").arg(insert_all_time).arg(Insert_time_dt);
321     ui->hash_insert_timeline->setText(str1);
322     str1=tr("遍歷時間 : %1 ms").arg(order_end_hash-order_began_hash);
323     ui->hash_order_line->setText(str1);
324 
325     HASH_List_print(L);
326 /*
327     j=0;
328     for(i=0;i<HASH_TABLE_LEN;i++){
329         p=L[i].Link_head;
330         while(p){
331             QComboBox *comBox=new QComboBox;
332             while(p->row_head){
333                 comBox->addItem(tr("%1").arg(p->row_head->row));
334                 p->row_head=p->row_head->next;
335             }
336             ui->HASH_tableWidget->setCellWidget(j,2,comBox);
337             j++;
338             p=p->next;
339         }
340     }
341 */
342 }

 

 

以上是主要的功能源碼,整體源碼需要的請留言。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM