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