线性表的两种实现

昨晚数据结构最简单也是最基础的线性表,有两种实现方式:

1、是逻辑结构与物理结构一致的顺序表,具体来说,就是用数组来实现

2、是数据的逻辑次序与物理次序很有可能不一致的链式表,通过结点来存储后继点的指针地址

顺序表定义:

const int MAX=100;
template<typename T>
class seqlist{
private:
  T data[MAX];
  int size;
public:
	seqlist(){size=0;}
	seqlist(T a[],int n){
	if(n>MAX)throw "n error";
	for(int i=0;i<n;i++)
	data[i]=a[i];
	size=n;}
	~seqlist(){}
	int getsize(){return size;}
    T get(int i);
    int loc(T x);
void insert(int i,T x);
T dele(int i);
void prt();};
template<typename T>
T seqlist<T>::get(int i){
if(i>size||i<1)throw"i error";
return data[i-1];}
template<typename T>
int seqlist<T>::loc(T x){
for(int i=0;i<size;i++)
  if(data[i]==x) return i+1;
return -1;}
template<typename T>
void seqlist<T>::insert(int i,T x){
if(size>=MAX)throw"overflow";
if(i>size+1||i<1)throw"i error";
for(int j=size;j>=i;j--)
  data[j]=data[j-1];
data[i-1]=x;
size++;}
template<typename T>
T seqlist<T>::dele(int i){
if(size<1)throw"downflow";
if(i<1||i>size)throw"i error";
T x=data[i-1];
for(int j=i;j<size;j++)
  data[j-1]=data[j];
size--;
return x;
}
template<typename T>
void seqlist<T>::prt(){
if(size<1)cout<<"empty"<<endl;
else {
for(int i=0;i<size;i++)
  cout<<data[i]<<" ";
cout<<endl;}}

链式表(以结点只含一个指针的单链表为例):

//link list
template<typename T>
struct node{
 T data;
 node<T>*next;};
 template<typename T>
 class linklist{
 private:node<T>*first;//单链表的头指针
		 int linksize;
 public:
	 linklist(){fisrt=new node<T>;
	 first->next=NULL;//无参构造构造空线性表
	 linksize=0;}
	 linklist(T a[],int n){
	 first=new node<T>;
	 first->next=NULL;//先构造空链表
	 linksize=n;
	 node<T>*p=first;
	 for(int i=0;i<n;i++)
	 {node<T>*s=new node<T>;
	 s->data=a[i];
	 s->next=p->next;//插入到头节点之后
	 p->next=s;}}
	 ~linklist(){
	 node<T>*p=first;
	 while(p){
	 node<T>*q=p;
	 p=p->next;
	 delete q;}}
     int size();
 T get(int i);
 int loc(T x);
 void insert(int i,T x);
 T del(int i);
 void prt();};
 template<typename T>
 int linklist<T>::size(){
 return  linksize;}
 template<typename T>
 T linklist<T>::get(int i){
 node<T>*p=first;
 int j=0;
 while(p&&j<i){
 p=p->next;
 j++;}
 if(!p) throw"i error";
 else return p->data;}
 template<typename T>
 int linklist<T>::loc(T x){
 node<T>*p=first;
 int j=0;
 while(p&&x!=p->data){
	 p=p->next;
 j++;}
 if(!p)throw"x no";
 else return j;}
 template<typename T>
 void linklist<T>::insert(int i,T x){
 node<T>*p=first;
 int j=0;
 while(p&&j<i-1){
	 p=p->next;
 j++;}//找到i-1
 if(!p)throw"insert error";
 else{
 node<T>*s=new node<T>;
 s->data=x;
 s->next=p->next;
 p->next=s;}
 linksize++;}
 template<typename T>
 T linklist<T>::del(int i){
 node<T>*p=first;
 int j=0;
 while(p&&j<i-1){
	 p=p->next;
 j++;}
 if(!p||!p->next)throw"del error";
 else{
	 T t=p->next->data;
	 p->next=p->next->next;
 return t;}
 linksize--;}
 template<typename T>
 void linklist<T>::prt(){
 node<T>*p=first;
 if(!p)cout<<"empty"<<endl;
  p=p->next;
 while(p){
	 cout<<p->data<<" ";
	 p=p->next;}
 cout<<endl;}

两者的调用类似,因为只是内部实现不一样,其接口还是不变。这体现了数据结构的封装性:

#include"2.h"
int main(){
int a[]={10,12,15,25,8,16,20};
seqlist<int>li(a,7);
linklist<int>l(a,7);
cout<<"the inf li:"<<endl;
li.prt();
cout<<"the inf of linklist:"<<endl;
l.prt();
try{
cout<<"the size of seqlist:"<<endl;
cout<<li.getsize()<<endl;
cout<<"the size of linksize:"<<endl;
cout<<l.size()<<endl;
cout<<"find the ith:"<<endl;
cout<<li.get(3)<<endl;
cout<<"find the ith:"<<endl;
cout<<l.get(3)<<endl;
cout<<"the loc of 15"<<endl;
cout<<li.loc(15)<<endl;
cout<<"the loc of 15:"<<endl;
cout<<l.loc(15)<<endl;
li.insert(3,100);
cout<<"the new after insert:"<<endl;
li.prt();
l.insert(3,100);
cout<<"the new after insert:"<<endl;
l.prt();
li.dele(3);
cout<<"the new after dele:"<<endl;
li.prt();
l.del(3);
cout<<"the new after dele:"<<endl;
l.prt();}
catch(string&s){
cout<<s<<endl;
}
system("pause");
return 0;}
两者的比较:

一、时间性能比较:

是指基于某种存储结构的算法时间复杂度。类如取出线性表内任意某个元素,使用顺序表快一点时间性能O(1),而链式表只能从表头开始依次向后扫描直至特定位置O(n);但是在进行相应插入与删除操作时候,在给出该处指针以后,增删所需时间O(1),而顺序表需平均移动一半元素,时间性能O(n),这对于大规模线性表来说,是不可忍受的。

二、空间性能比较:

首先定义存储密度:存储密度=(数据域占用的存储量)/(整个节点占用的存储量)

顺序表存储密度为1,而链式表数据域和指针域各占一部分节点,从这一层来说,顺序表更好;但是顺序表需要预先静态分配一定长度的存储空间,如果事先不知道线性表规模,会面临预分配过剩导致的浪费或者预分配过少导致的碎片,而单链表无需预分配。根据需要动态产生即可。故当线性表规模小或者规模已知时候用顺序表,否则用单链表。

你可能感兴趣的:(线性表的两种实现)