使用鏈表結構可以克服數組鏈表需要預先知道數據大小的缺點,鏈表結構可以充分利用計算機內存空間,實現靈活的內存動態管理。但是鏈表失去了數組隨機讀取的優點,同時鏈表由於增加了結點的指針域,空間開銷比較大。鏈表最明顯的好處就是,常規數組排列關聯項目的方式可能不同於這些數據項目在記憶體或磁盤上順序,數據的存取往往要在不同的排列順序中轉換。鏈表允許插入和移除表上任意位置上的節點,但是不允許隨機存取。鏈表有很多種不同的類型:單向鏈表,雙向鏈表以及循環鏈表。
#include<iostream>
using namespace std;
template <class T>
class Chain;
template <class T>
class ChainNode
{
friend class Chain<T>;
private:
T data;
ChainNode<T> *next;
};
template <class T>
class Chain
{
public:
Chain()
{
first = 0;
last = 0;
}
~Chain();
void Add(T& x);
bool IsEmpty()const{return first==0;}
int Length()const;
bool Find(int k, T& x)const;
int Search(const T& x)const;
void DeleteOfk(int k);//刪除第k個元素
void DeleteOfx(T& x);//刪除鏈表中值爲x的幾點,如果存在
void Insert(int k,const T& x);
void OutPut()const;
private:
ChainNode<T> *first;
ChainNode<T> *last;
};
template <class T>
Chain<T>::~Chain()
{//析構函數,刪除表中的所有節點
ChainNode<T> *next;
while(first)
{
next = first->next;
delete(first);
first = next;
}
}
template <class T>
void Chain<T>::Add(T& x)
{
ChainNode<T> *node = new ChainNode<T>;
node->data = x;
node->next = NULL;
if(first)
{//每次在鏈表的尾部插入一個節點
last->next = node;
last = node;
}
else
{//如果是空表 這新加入的節點既是頭結點也是尾節點
first = node;
last = node;
}
}
template <class T>
int Chain<T>::Length()const
{//返回鏈表的長度
ChainNode<T> *current = first;
int len = 0;
while(current)
{
len++;
current = current->next;
}
return len;
}
template<class T>
bool Chain<T>::Find(int k, T& x)const
{//查找第k個元素,如果純在將其保存在x中。
//如純在返回true,不存在返回false
if (k<1)
return false;
ChainNode<T> *current = first;
int index = 1;
while(index<k&¤t)
{
current = current->next;
index++;
}
if (current)
{
x = current->data;
return true;
}
else
{
return false;
}
}
template<class T>
int Chain<T>::Search(const T& x)const
{//尋找x,如果發現x,返回x的地址
//如果x不存在鏈表中則返回0
ChainNode<T> *current = first;
int index = 1;
while(current&¤t->data!=x)
{
index++;
current = current->next;
}
if(current)
return index;
return 0;
}
template <class T>
void Chain<T>::DeleteOfk(int k)//刪除第k個元素
{
T x;
if(Find(k,x))
{
int index = 1;
ChainNode<T> *current = first;
ChainNode<T> *temp=0;
if(k==1)
{//刪除頭結點
first = first->next;
delete (current);
}
else
{
while(k!=index)
{
index++;
temp = current;//temp始終指向current的上一個節點
current = current->next;
}
if(current)
{
temp->next = current->next;
if(!current->next)
{//如果刪除的是最後一個節點,則最後的一個節點應該變成temp。
last = temp;
}
delete (current);
}
}
}
}
template <class T>
void Chain<T>::DeleteOfx(T& x)//刪除鏈表中值爲x的幾點,如果存在
{
int k;
k = Search(x);
if(k!=0)
{
DeleteOfk(k);
}
else
{
cout<<"刪除的數據在鏈表中不存在"<<endl;
}
}
template <class T>
void Chain<T>::Insert(int k,const T& x)
{
ChainNode<T> *temp = new ChainNode<T>;
temp->data = x;
temp->next = NULL;
if(k==0)
{ //插入在頭結點的位置
temp->next = first;
first = temp;
}
else if(k>0&&k<=Length())
{
ChainNode<T> *current = first;
int index = 1;
while(index!=k)
{
index++;
current = current->next;
}
if(current)
{
temp->next = current->next;
current->next = temp;
}
else
{//插入在尾節點的位置
last = temp;
current->next = temp;
}
}
else
{
cout<<"插入數據不正確"<<endl;
}
}
template <class T>
void Chain<T>::OutPut()const
{
ChainNode<T> *current = first;
while(current)
{
cout<<current->data<<" ";
current = current->next;
}
cout<<endl;
}
int main()
{
Chain<int> list;
int x;
for(int i=0; i<5; i++)
{
cin>>x;
list.Add(x);
}
list.OutPut();
cout<<"length: "<<list.Length()<<endl;
x = 0;
if(list.Find(5,x))
{
cout<<"OK!! "<<x<<endl;
}
int y = list.Search(x);
cout << "y="<<y<<endl;
list.DeleteOfk(1);
list.OutPut();
list.DeleteOfx(x);
list.OutPut();
list.Insert(0,x);
list.OutPut();
}