线性表是数据结构入门的第一课,其也是最基本、最常用的一种数据结构
文章目录
一、什么是线性表
线性表(Linear_List):n(n≥0)个相同特性的数据元素的有限序列,数据元素之间具有线性关系。
接下来我将介绍两种顺序表的存储结构:顺序存储和链式存储。
二、顺序存储结构ADT实现
1、什么是顺序存储结构
利用数据元素的存储位置表示线性表中相邻数据元素之间的前后关系,即线性表的逻辑结构与存储结构(物理结构)一致,逻辑位置相邻,存储位置也相邻。
顺序存储就好比买东西时候的排队,都紧密排在一起,有些人不想买就先走了,有些人没素质还插队。
2、顺序存储结构的实现
(1)、存储方式
用地址连续的一组存储单元依次存储线性表的各个单元。先在内存中找到一个初始的地址,然后通过占位,把连续的一定地址给占了,然后把数据类型相同的元素存到这片地址上。一般用数组来实现。
线性表的数据操作和数组有关,操作数组元素实现相应功能。
(2)、具体实现
1)、模板类的实现
const int MaxSize=1000;
template <class DataType>
class setList
{
public:
setList(){length=0;}//无参数的构造函数
setList(DataType a[],int n);//带参数的构造函数
~setList() {}//析构函数
void Locate(DataType x);//查找X在表中的位置
void Insert(int i,DataType x);//在第i个元素插入X
DataType Delete1(int i);//按值删除
DataType Delete2(int i);//按位删除
DataType GetData(setList &A,int i);//按位查找
DataType Search(setList l,DataType x);//按值查找
void PrintList();//打印表
void Cross(setList &A,setList &B,setList &C);//两个列表交操作
void Union(setList &A,setList &B);//两个列表并操作
void Sort(setList &a);//对表进行排序
private:
DataType data[MaxSize];//定义数组
int length;
};
顺序表的封装需要三个属性:
1、存储空间的起始位置。数组data的存储位置就是线性表存储空间的存储位置
2、线性表的最大存储容量。数组长度MAXSIZE
3、线性表的当前长度length
注意:数组的长度与线性表的当前长度是不一样的。数组的长度是存放线性表的存储空间的总长度,一般初始化后不变。而线性表的当前长度是线性表中元素的个数,是会改变的。
2)、带参数的构造函数
创建一个长度为n的顺序表,需要将给定的数组元素作为线性表的数据元素传入顺序表中,并将传入的元素个数作为顺序表的长度。
template <class DataType>
setList<DataType>::setList(DataType a[],int n)
{
if(n>MaxSize)
{
cout<<"Wrong!"<<endl;
return ;
}
for(int i=0; i<n; i++)
{
data[i]=a[i];
}
length=n;
}
3)、查找X在表中的位置
通过遍历表来确定元素X的位置。
template <class DataType>
void setList<DataType>::Locate(DataType x)
{
int flag=0,t1;
for(int i=0; i<length; i++)
{
if(x==data[i])
{
flag=1;
t1=i+1;
}
}
if(flag)
{
cout<<x<<" is located at index of "<<t1<<endl;
}
else{
cout<<x<<" is not found"<<endl;
}
}
4)、在第i个元素插入X
插入的过程中需要注意元素移动的方向,必须从最后一个元素开始移动,如果表满了,则引发上溢;如果插入位置不合理,则引发位置异常。
template <class DataType>
void setList<DataType>::Insert(int i,DataType x)
{
if(length>MaxSize)
{
cout<<"Wrong!"<<endl;
return ;
}
for(int j=length;j>=i;j--)
{
data[j]=data[j-1];
}
data[i-1]=x;
length++;
}
5)、按值删除
从第m+1个元素开始(m是要删除的元素对应的数组下标),将后一位赋给前一位,达到删除。
template <class DataType>
DataType setList<DataType>::Delete1(int i)
{
int m;
for(int z=0;z<length;z++)//查找这个元素在表中的位置
{
if(i==data[z])
{
m=z;
}
}
for(int j=m+1;j<length;j++)
{
data[j-1]=data[j];
}
length--;
}
6)、按位删除
原理如上
template <class DataType>
DataType SeqList<DataType>::Delete2(int i)
{
int x;
x = data[i-1];//将要删除的元素赋给x
for(int j=i;j<length;j++)
data[j-1] = data[j];
length--;
return x;
}
7)、按位查找
返回第i个元素
template <class DataType>
DataType setList<DataType>::GetData(setList &a,int i)
{
return a.data[i-1];
}
8)、按值查找
通过遍历数组来找到这个元素的位置,返回值为数组下标+1(位置)
template <class DataType>
DataType setList<DataType>::Search(setList l,DataType x)
{
int i=0;
while(i<=l.length&&l.data[i]!=x)//遍历数组直到l.data[i]==x
{
i++;
}
if(i>l.length)//没有找到返回-1
{
return -1;
}
else{
return i+1;
}
}
9)、打印表
遍历数组即可
template <class DataType>
void setList<DataType>::PrintList()
{
for(int i=0; i<length; i++)
{
cout<<data[i]<<" ";
}
cout<<endl;
}
10)、两个列表交操作
通过增加一个表c,通过嵌套循环,依次从q中寻找有无和p中相同的元素,如果有则在c中进行添加。
template <class DataType>
void setList<DataType>::Cross(setList &p,setList &q,setList &c)
{
int t=0;
for(int i=0;i<p.length;i++)
{
for(int j=0;j<q.length;j++)
{
if(p.data[i]==q.data[j])
{
c.data[t]=p.data[i];
t++;
}
}
}
cout<<"A cross B is ";
for(int i=0;i<t;i++)
{
cout<<c.data[i]<<" ";
}
cout<<endl;
}
11)、两个列表并操作
遍历q,在p中寻找有无和q中相同的元素,如果没有,就在p的尾部进行添加。
template <class DataType>
void setList<DataType>::Union(setList &p,setList &q)
{
int t;
for(int i=0;i<q.length;i++)
{
t=Search(p,q.data[i]);
if(t<0)
{
Insert(p.length+1,q.data[i]);
}
}
}
12)、对表进行排序
由于是C++数组排序,我就直接调用C++的sort函数了
template <class DataType>
void setList<DataType>::Sort(setList &p)
{
sort(p.data,p.data+p.length);
}
3、完整程序
#include <iostream>
#include <algorithm>
using namespace std;
const int MaxSize=1000;
template <class DataType>
class setList
{
public:
setList(){length=0;}//无参数的构造函数
setList(DataType a[],int n);//带参数的构造函数
~setList() {}//析构函数
void Locate(DataType x);//查找X在表中的位置
void Insert(int i,DataType x);//在i处插入X
DataType Delete(int i);//删除第i个元素
DataType GetData(setList &A,int i);//按位查找
void PrintList();//打印表
void Cross(setList &A,setList &B,setList &C);//两个列表交操作
void Union(setList &A,setList &B);//两个列表并操作
DataType Search(setList l,DataType x);//按值查找
void Sort(setList &a);//对表进行排序
private:
DataType data[MaxSize];//定义数组
int length;
};
template <class DataType>
DataType setList<DataType>::GetData(setList &a,int i)
{
return a.data[i-1];
}
template <class DataType>
DataType setList<DataType>::Search(setList l,DataType x)
{
int i=0;
while(i<=l.length&&l.data[i]!=x)
{
i++;
}
if(i>l.length)
{
return -1;
}
else{
return i+1;
}
}
template <class DataType>
void setList<DataType>::Sort(setList &p)
{
sort(p.data,p.data+p.length);
}
template <class DataType>
setList<DataType>::setList(DataType a[],int n)
{
if(n>MaxSize)
{
cout<<"Wrong!"<<endl;
return ;
}
for(int i=0; i<n; i++)
{
data[i]=a[i];
}
length=n;
}
template <class DataType>
void setList<DataType>::PrintList()
{
for(int i=0; i<length; i++)
{
cout<<data[i]<<" ";
}
cout<<endl;
}
template <class DataType>
void setList<DataType>::Locate(DataType x)
{
int flag=0,t1;
for(int i=0; i<length; i++)
{
if(x==data[i])
{
flag=1;
t1=i+1;
}
}
if(flag)
{
cout<<x<<" is located at index of "<<t1<<endl;
}
else{
cout<<x<<" is not found"<<endl;
}
}
template <class DataType>
void setList<DataType>::Insert(int i,DataType x)
{
if(length>MaxSize)
{
cout<<"Wrong!"<<endl;
return ;
}
for(int j=length;j>=i;j--)
{
data[j]=data[j-1];
}
data[i-1]=x;
length++;
}
template <class DataType>
DataType setList<DataType>::Delete(int i)
{
int m;
for(int z=0;z<length;z++)
{
if(i==data[z])
{
m=z;
}
}
for(int j=m+1;j<length;j++)
{
data[j-1]=data[j];
}
length--;
}
template <class DataType>
void setList<DataType>::Cross(setList &p,setList &q,setList &c)
{
int t=0;
for(int i=0;i<p.length;i++)
{
for(int j=0;j<q.length;j++)
{
if(p.data[i]==q.data[j])
{
c.data[t]=p.data[i];
t++;
}
}
}
cout<<"A cross B is ";
for(int i=0;i<t;i++)
{
cout<<c.data[i]<<" ";
}
cout<<endl;
}
template <class DataType>
void setList<DataType>::Union(setList &p,setList &q)
{
int t;
for(int i=0;i<q.length;i++)
{
t=Search(p,q.data[i]);
if(t<0)
{
Insert(p.length+1,q.data[i]);
}
}
}
int main()
{
int n,a[1000],m,b[1000],x1,y1,x2,x3,x4;
cin>>n;
for(int i=0;i<n;i++)
{
cin>>a[i];
}
setList<int> p(a,n);
cout<<"A is created as: ";
p.PrintList();
cin>>x1>>y1;
p.Insert(x1,y1);
cout<<"After inserted A is ";
p.PrintList();
cin>>x2;
p.Delete(x2);
cout<<"After deleted A is ";
p.PrintList();
cin>>x3;
p.Locate(x3);
cin>>x4;
p.Locate(x4);
cin>>m;
for(int i=0;i<m;i++)
{
cin>>b[i];
}
setList<int> q(b,m);
cout<<"B is created as: ";
q.PrintList();
setList<int> r;
r.Cross(p,q,r);
p.Union(p,q);
cout<<"A union B is ";
p.PrintList();
p.Sort(p);
cout<<"A union B in sequence is ";
p.PrintList();
return 0;
}
4、说明
data数组在类中定义后,通过类定义的表都可以调用。