線性表是一種動態的數據結構,它的表長可以變化。線性表的功能主要是對存儲在線性表中的數據進行檢索,插入,刪除等操作。主要有順序表,鏈表兩種形式。
順序表是在一組連續地址的存儲單元中存儲數據,這樣可以保證這些在邏輯上相鄰的數據在物理上也相鄰。
鏈表通過節點指針將數據串聯起來,可以保證數據邏輯上的相鄰性,但是無法保證數據物理上的相鄰性。
實現方法如下:
1.建立線性表的抽象類 linearlist.h
//線性表抽象類
template <class T>
class LinearList
{
protected: //繼承後派生類成員函數有訪問權限
int n; //線性表長度
public:
virtual bool isEmpty() const=0; //線性表是否爲空
virtual int length() const=0; //線性表長度
virtual bool find(int i,T &x) const=0; //尋找下標爲i的元素,找到函數返回true,元素賦值給x
virtual int search(T x) const=0; //搜索元素x,返回該元素下標
virtual bool insert(int i,T x)=0; //在下標i出插入元素x
virtual bool del(int i)=0; //刪除下標i處的元素
virtual void print() const=0; //輸出線性表
};
順序表的建立 seqlist.h,該順序表public繼承了上文的線性表抽象類
#include "linearlist.h"
template <class T>
class SeqList:public LinearList<T>
{
private:
T *elements;
int maxLength;
public:
SeqList(int maxLength);
~SeqList();
bool isEmpty() const;
int length() const;
bool find(int i,T &x) const;
int search(T x) const;
bool insert(int i,T x);
bool del(int i);
void print() const;
};
#include "seqlist.h"
template <class T>
SeqList<T>::SeqList(int maxSize)
{
maxLength=maxSize;
elements=new T[maxLength];
n=0;
}
template <class T>
SeqList<T>::~SeqList()
{
delete [] elements;
}
template <class T>
bool SeqList<T>::isEmpty() const
{
return n==0;
}
template <class T>
int SeqList<T>::length() const
{
return n;
}
template <class T>
bool SeqList<T>::find(int i,T &x) const
{
if(i<0||i>n-1)
{
cout<<"尋找下標越界"<<endl;
return false;
}
x=elements[i];
return true;
}
template <class T>
int SeqList<T>::search(T x) const
{
for(int j=0;j<n;j++)
{
if(elements[j]==x)
{
return j;
}
}
return -1;
}
template <class T>
bool SeqList<T>::insert(int i,T x)
{
if(i<0||i>n)
{
cout<<"插入下標越界"<<endl;
return false;
}
if(n==maxLength)
{
cout<<"內存不足"<<endl;
return false;
}
for(int j=n-1;j>i-1;j--)
{
elements[j+1]=elements[j];
}
elements[i]=x;
n++;
return true;
}
template <class T>
bool SeqList<T>::del(int i)
{
if(!n)
{
cout<<"無可刪除的元素"<<endl;
return false;
}
if(i<0||i>n-1)
{
cout<<"刪除下標越界"<<endl;
return false;
}
for(int j=i+1;j<n;j++)
{
elements[j-1]=elements[j];
}
n--;
return true;
}
template <class T>
void SeqList<T>::print() const
{
for(int j=0;j<n;j++)
{
cout<<elements[j]<<'\t';
}
cout<<endl;
}
1.要注意判斷下標是否越界
2.順序表插入刪除的效率較鏈表要低,但檢索效率較鏈表要高
3.單鏈表的建立 singlelist.h ,同樣也繼承了第1節中的linearlist抽象類
#include "linearlist.h"
template <class T> class SingleList;
template <class T>
class Node
{
private:
Node<T> *link;
T element;
friend class SingleList<T>;
};
template <class T>
class SingleList:public LinearList<T>
{
private:
Node<T> *first;
public:
SingleList();
~SingleList();
bool isEmpty() const;
int length() const;
bool find(int i,T &x) const;
int search(T x) const;
bool insert(int i,T x);
bool del(int i);
void print() const;
};
#include "singlelist.h"
template <class T>
SingleList<T>::SingleList()
{
first=new Node<T>;
n=0;
first->link=NULL;
}
template <class T>
SingleList<T>::~SingleList()
{
Node<T> *p;
while(first)
{
p=first;
first=first->link;
delete p;
}
}
template <class T>
bool SingleList<T>::isEmpty() const
{
return n==0;
}
template <class T>
int SingleList<T>::length() const
{
return n;
}
template <class T>
bool SingleList<T>::find(int i,T &x) const
{
if(i<0||i>n-1)
{
cout<<"find越界"<<endl;
return false;
}
Node<T> *p=first->link;
for(int j=0;j<i;j++)
{
p=p->link;
}
x=p->element;
return true;
}
template <class T>
int SingleList<T>::search(T x) const
{
int j;
Node<T> *p=first->link;
for(j=0;p&&p->element!=x;j++)
{
p=p->link;
}
if(p)
return j;
return -1;
}
template <class T>
bool SingleList<T>::insert(int i,T x)
{
if(i<0||i>n)
{
cout<<"插入元素越界"<<endl;
return false;
}
Node<T> *q=new Node<T>;
q->element=x;
Node<T> *p=first;
for(int j=0;j<i;j++)
{
p=p->link;
}
q->link=p->link;
p->link=q;
n++;
return true;
}
template <class T>
bool SingleList<T>::del(int i)
{
if(i<0||i>n-1)
{
cout<<"刪除元素越界"<<endl;
return false;
}
Node<T> *q=first->link;
Node<T> *p=first;
for(int j=0;j<i;j++)
{
q=q->link;
p=p->link;
}
p->link=q->link;
delete q;
n--;
return true;
}
template <class T>
void SingleList<T>::print() const
{
Node<T> *p=first->link;
for(int j=0;j<n;j++)
{
cout<<p->element<<' ';
p=p->link;
}
cout<<endl;
}
總結:
1.該單鏈表的實現是帶表頭的單鏈表,在帶表頭的單鏈表中的插入刪除操作可以不用考慮是否在表頭插入刪除的情況。