C++教程:鏈表類(lèi)
2020-05-23 14:25:51
供稿:網(wǎng)友
鏈表結(jié)點(diǎn)類(lèi)編寫(xiě)好了,我們可以向鏈表類(lèi)進(jìn)軍了。鏈表是由一個(gè)個(gè)鏈表結(jié)點(diǎn)組成的,所以我們會(huì)在鏈表類(lèi)中使用到鏈表結(jié)點(diǎn)類(lèi)。鏈表結(jié)點(diǎn)類(lèi)是一個(gè)很簡(jiǎn)單的類(lèi),鏈表類(lèi)是一個(gè)功能更為強(qiáng)大的類(lèi)。正是將一個(gè)個(gè)類(lèi)不斷地組合與擴(kuò)充,使得面向?qū)ο蟮某绦蚬δ茉絹?lái)越強(qiáng)大。
讓我們感興趣的是,假設(shè)我們編寫(xiě)的鏈表需要有一個(gè)頭結(jié)點(diǎn)作為成員數(shù)據(jù),那么是先有鏈表呢,還是先有頭結(jié)點(diǎn)?我們又該如何在給鏈表作初始化的同時(shí)初始化頭結(jié)點(diǎn)呢?
當(dāng)一個(gè)對(duì)象中包含別的對(duì)象時(shí),我們可以在它的構(gòu)造函數(shù)定義中用以下格式調(diào)用其成員對(duì)象的構(gòu)造函數(shù):
類(lèi)名::構(gòu)造函數(shù)名(參數(shù)表):成員對(duì)象名1(參數(shù)表)[,……成員對(duì)象名n(參數(shù)表)]
前一段和普通的構(gòu)造函數(shù)一樣,冒號(hào)之后則表示該類(lèi)中的成員對(duì)象怎樣調(diào)用各自的構(gòu)造函數(shù)。
下面我們來(lái)看一個(gè)簡(jiǎn)單的面向?qū)ο蟮逆湵沓绦颍海ǔ绦?5.3)
//node.h同程序15.2.2
//linklist.h
#include "node.h"//需要使用鏈表結(jié)點(diǎn)類(lèi)
#include <iostream>
using namespace std;
class Linklist
{
public:
Linklist(int i,char c);//鏈表類(lèi)構(gòu)造函數(shù)
bool Locate(int i);//根據(jù)整數(shù)查找結(jié)點(diǎn)
bool Locate(char c);//根據(jù)字符查找結(jié)點(diǎn)
bool Insert(int i=0,char c='0');//在當(dāng)前結(jié)點(diǎn)之后插入結(jié)點(diǎn)
bool Delete();//刪除當(dāng)前結(jié)點(diǎn)
void Show();//顯示鏈表所有數(shù)據(jù)
void Destroy();//清除整個(gè)鏈表
private:
Node head;//頭結(jié)點(diǎn)
Node * pcurrent;//當(dāng)前結(jié)點(diǎn)指針
};
Linklist::Linklist(int i,char c):head(i,c)//類(lèi)名::構(gòu)造函數(shù)名(參數(shù)表):成員對(duì)象名1(參數(shù)表),鏈表類(lèi)構(gòu)造函數(shù),調(diào)用head對(duì)象的構(gòu)造函數(shù)重載1,詳見(jiàn)Node.h文件
{
cout<<"Linklist constructor is running..."<<endl;
pcurrent=&head;
}
bool Linklist::Locate(int i)
{
Node * ptemp=&head;
while(ptemp!=NULL)
{
if(ptemp->readi()==i)
{
pcurrent=ptemp;//將當(dāng)前結(jié)點(diǎn)指針指向找到的結(jié)點(diǎn)
return true;
}
ptemp=ptemp->readn();//查找下一個(gè)結(jié)點(diǎn)
}
return false;
}
bool Linklist::Locate(char c)
{
Node * ptemp=&head;
while(ptemp!=NULL)
{
if(ptemp->readc()==c)
{
pcurrent=ptemp;
return true;
}
ptemp=ptemp->readn();
}
return false;
}
bool Linklist::Insert(int i,char c)
{
if(pcurrent!=NULL)
{
Node * temp=new Node(i,c,pcurrent,pcurrent->readn());//調(diào)用Node類(lèi)構(gòu)造函數(shù)重載2
if (pcurrent->readn()!=NULL)
{
pcurrent->readn()->setp(temp);
}
pcurrent->setn(temp);
return true;
}
else
{
return false;
}
}
bool Linklist::Delete()
{
if(pcurrent!=NULL && pcurrent!=&head)//head結(jié)點(diǎn)不能刪除
{
Node * temp=pcurrent;
if (temp->readn()!=NULL)
{
temp->readn()->setp(pcurrent->readp());
}
temp->readp()->setn(pcurrent->readn());//先連
pcurrent=temp->readp();
delete temp;//后斷
return true;
}
else
{
return false;
}
}
void Linklist::Show()
{
Node * ptemp=&head;
while (ptemp!=NULL)//鏈表的遍歷
{
cout <<ptemp->readi() <<'/t' <<ptemp->readc() <<endl;
ptemp=ptemp->readn();
}
}
void Linklist::Destroy()
{
Node * ptemp1=head.readn();
while (ptemp1!=NULL)
{
Node * ptemp2=ptemp1->readn();
delete ptemp1;
ptemp1=ptemp2;
}
head.setn(NULL);//頭結(jié)點(diǎn)之后沒(méi)有其他結(jié)點(diǎn)
}
//main.cpp
#include "Linklist.h"
#include <iostream>
using namespace std;
int main()
{
int tempi;
char tempc;
cout <<"請(qǐng)輸入一個(gè)整數(shù)和一個(gè)字符:" <<endl;
cin >>tempi >>tempc;
Linklist a(tempi,tempc);//創(chuàng)建一個(gè)鏈表,頭結(jié)點(diǎn)數(shù)據(jù)由tempi和tempc確定
a.Locate(tempi);
a.Insert(1,'C');
a.Insert(2,'B');
a.Insert(3,'F');
cout <<"After Insert" <<endl;
a.Show();
a.Locate('B');
a.Delete();
cout <<"After Delete" <<endl;
a.Show();
a.Destroy();
cout <<"After Destroy" <<endl;
a.Show();
return 0;
}
運(yùn)行結(jié)果:
請(qǐng)輸入一個(gè)整數(shù)和一個(gè)字符:
4 G
Node constructor is running...
Linklist constructor is running...
Node constructor is running...
Node constructor is running...
Node constructor is running...
After Insert
4 G
3 F
2 B
1 C
After Delete
4 G
3 F
1 C
After Destroy
4 G
根據(jù)程序的運(yùn)行結(jié)果,我們發(fā)現(xiàn)頭結(jié)點(diǎn)的構(gòu)造函數(shù)比鏈表的構(gòu)造函數(shù)優(yōu)先運(yùn)行。這也不難理解:構(gòu)造函數(shù)的目的是要初始化成員數(shù)據(jù),初始化成員數(shù)據(jù)的時(shí)候這個(gè)成員數(shù)據(jù)是必須存在的。所以當(dāng)一個(gè)成員數(shù)據(jù)是一個(gè)對(duì)象的時(shí)候,應(yīng)當(dāng)先產(chǎn)生這個(gè)成員對(duì)象,于是就先調(diào)用了成員對(duì)象的構(gòu)造函數(shù)。