c++中實現通用資料結構
在程式設計當中經常會出現使用同種資料結構的不同例項的情況。例如:在乙個
程式中可以使用多個佇列、樹、圖等結構來組織資料。同種結構的不同例項,也
許只在資料元素的型別或數量上略有差異,如果對每個例項都重新定義,則非常麻
煩且容易出錯。那麼能否對同種型別資料結構僅定義一次呢?答案是肯定的,c++
提供的類模板(class template)就可以實現該功能。
一、類模板
類模板是c++提供的一種特殊機制,通過它我們可以定義一種特殊的類(稱為模板
類),在類的定義中可以包含待定的型別引數,在宣告類的例項時,系統會自動根據
傳遞的型別生成使用者想要生成的類例項。下面是用c++實現的乙個簡單的模板類
clist的定義。
template class clist
在這裡,t是型別引數,i是整型常量引數。t和i的實際值是在宣告具體類例項時指
定的。模板類的<>號內可以包括任意個型別引數和常量引數(至少要有乙個引數
)。型別引數和常量引數可以是任何合法的標準型別和使用者自定義型別,包括簡單
型別及各種結構體。同其他類一樣,類成員函式setitem的實現可以在類定義內完
成,也可以在類clist定義處實現:
templateint clist::setitem(int index, const t
&item)
值得注意的是,在類定義外完成函式實現時,必須以關鍵字template和類模板定義
中相同的參數列(<>號內的)開頭(上例為template),並且範圍
分解操作符前的類名後應跟上模板引數名清單(上例為clist)。另外,與非
模板類不同的是,必須將函式實現包括在呼叫它的每個原始檔中,使編譯器能從函
數實現產生**。通常的做法是將模板類的函式實現也放在定義該類的標頭檔案中
,這樣只需在呼叫的原始檔中包含該標頭檔案即可。
那麼,如何使用生成特定的類例項呢?我們可以像使用其他類一樣來使用模板類,
不過必須指定模板引數的值。例如採用如下宣告:
clist intlist;
則使intlist成為clist類的例項,每次出現的t引數都換成int, 每次出現的i引數
都換成100。這樣,intlist類中的buffer就是乙個長度為100的整型陣列,
setitem和getitem函式引數是int值的引用。例:
intlist.setitem(0, 5); //給陣列第乙個元素賦為整數5
模板類還可以像其他類一樣可以定義建構函式和析構函式。下面我們以一種簡單
的資料結構——堆疊為例,來說明如何用類模板來構造通用資料結構。
二、 利用類模板實現通用堆疊結構
任何抽象資料結構在計算機中的實現,歸根結底都只有兩種方式:順序儲存(用數
組實現),鏈式儲存(用指標實現)。堆疊也不例外,按其實現方式可分為順序棧(用
陣列實現)和鏈棧(用指標實現)。
1. 通用順序棧的實現
因為順序棧中的元素在空間上連續儲存,棧頂的元素位置需要註明,所以構造順序
棧的模板類應該有這樣的一些成員變數:乙個待定型別和長度的陣列buffer,乙個
記錄棧頂元素的陣列下標的整型變數top。堆疊的基本操作主要有:入棧(push)、
出棧(pop)、置空(setempty)、判斷當前狀態(isempty)等,它們應用模板類的成
員函式來實現。作為乙個標準的類,它還應該有自己的建構函式和析構函式。具
有這些功能的模板類,就可以作為乙個通用的順序棧來使用了。該類的定義如下
:template class carraystacktemp
;~ carraystacktemp (){};//析構函式
void setempty (); //置空堆疊
bool isempty(); //判斷堆疊是否為空
bool push(t element); //入棧
bool pop(t& element);//出棧
private:
t buffer[size];
int top;
};與堆疊的基本操作相對應的成員函式的實現如下:
template void carraystacktemp::
setempty ()
template bool carraystacktemp:: isempty
()template bool carraystacktemp:: push (t
element)
buffer[top]=element;
return true;
}template void carraystacktemp:: pop (t&
element)
根據實際需要,還可以擴充堆疊功能。例如:加入取棧頂元素、求堆疊長度等操作
,其方法如上。
2. 通用鏈棧的實現
模板類中允許使用指標和定義自己的結構,這就為實現鏈式結構提供了保證。這
裡採用乙個單鏈表來實現堆疊,棧頂指標指向鍊錶的第乙個結點,入棧和出棧均在
鍊錶的頭進行。該模板類的定義如下:
template class clinkstacktemp
;~clinkstacktemp(){}; //析構函式
//定義結點結構
struct node
;void setempty(); //置空堆疊
bool isempty(); //判斷堆疊是否為空
bool push(t element); //壓入堆疊
bool pop(t& element);//彈出堆疊
private:
node* top;
};該類的成員函式實現如下:
template void clinkstacktemp ::setempty()
}template bool clinkstacktemp ::isempty()
template bool clinkstacktemp ::push(t element)
template bool clinkstacktemp ::pop(t& element)
與順序棧的實現略有不同,鏈棧不必指定棧的容量,其大小可以是近似"無限"的。
為了程式的使用方便,我們同樣可以加入一些增強的功能。
三、 通用堆疊類的使用
通用堆疊類的使用較為簡單,堆疊類的例項就是乙個可以方便使用的堆疊。對堆
棧的操作都是通過類的成員函式來實現的。使用的具體步驟如下:
1. 在要使用堆疊類的程式**的檔案開頭包括模板類及其成員函式的定義。
2. 類的例項化,可宣告成變數,也可以宣告它的指標,如:
carraystacktemp intstack; //生成乙個長度為100的int型堆疊
//生成乙個元素為record型的堆疊,record為自定義結構
clinkstacktemp * recordstack;
recordstack=new clinkstacktemp;
應注意在定義順序棧時,必須指定棧的大小,而鏈棧則不必。另外在指定指標型別
和執行new操作時,必須對模板引數賦值,並且前後要一致。
3. 對堆疊進行操作,如:
intstack.push(3); //將整數3入棧
recordstack.setempty(); //將堆疊置空
無論我們使用哪種堆疊類,對使用者來講都是透明的,操作起來並無差別。
資料結構 C
本文將根據自己對資料結構的理解,介紹資料結構的基本型別 鍊錶。寫的不好的地方歡迎指正。首先是單鏈表。結點資料結構定義 struct node return false 3 刪除元素 bool delete node first,int x 現在介紹雙鏈表 首先也是結點結構定義 struct node...
C 資料結構
c c 陣列允許定義可儲存相同型別資料項的變數,但是結構是 c 中另一種使用者自定義的可用的資料型別,它允許您儲存不同型別的資料項。結構用於表示一條記錄,假設您想要跟蹤圖書館中書本的動態,您可能需要跟蹤每本書的下列屬性 為了定義結構,您必須使用struct語句。struct 語句定義了乙個包含多個成...
c 資料結構
類的成員函式是指那些把定義和原型寫在類定義內部的函式,就像類定義中的其他變數一樣。類成員函式是類的乙個成員,它可以操作類的任意物件,可以訪問物件中的所有成員。讓我們看看之前定義的類 box,現在我們要使用成員函式來訪問類的成員,而不是直接訪問這些類的成員 class box 成員函式可以定義在類定義...