基本定义:
线性表的顺序存储就是顺序表,它是用一组“地址连续的存储单元”依次存储数据元素,从而使得逻辑上相邻的两个元素在物理位置上也是相邻的。
在进行分配数组的时候,可以进行静态分配。但由于数组的大小和空间事先已经固定,所以一旦空间占满,再加入新的数据就会产生溢出,进而导致程序崩溃。
//静态分配
typedef struct {
ElemType data[Maxsize];
int length;
}Static_Seqlist;
当然也可以进行动态分配,区别在于,一旦原来分配的数据空间占满,系统就另外开辟一块更大的存储空间,从而替换到原来的存储空间,再用delete(或者free)释放原来的区域,从而达到扩充存储空间的目的。
函数说明和使用:
以下是顺序表的基本操作函数说明(这里是基于动态分配)
//(1)初始化表
int Initlist(Seqlist& L)
//(2)创建一个长度为n的表
bool Creatlist(Seqlist& L, int n)
//(3)判别空表
bool Empty(Seqlist& L)
//(4)打印表
bool Printlist(Seqlist& L)
//(5)求表长
int Length(Seqlist& L)
//(6)按值查找,返回位置信息
int LocateElem(Seqlist& L, ElemType e)
//(7)按位i查找,返回数值e
bool GetElem(Seqlist& L, int i, ElemType& e)
//(8)在表的第i的位置插入值e
bool ListInsert(Seqlist& L, int i, ElemType e)
//(9)删除表中第i个位置的值,并把值暂时赋给e
bool ListDelete(Seqlist& L, int i, ElemType& e)
//(10)销毁表
bool DestroyList(Seqlist& L)
具体的函数内容和使用:
//sequence_list顺序表
#include<iostream>
using namespace std;
#define Maxsize 15 //定义线性表的最大长度
#define ElemType int
#define Initsize 6 //表长度的初始值
//静态分配
typedef struct {
ElemType data[Maxsize];
int length;
}Static_Seqlist;
//动态分配
typedef struct {
ElemType *data; //指示动态分配数组的(指针)
int length;
}Seqlist;
//(1)初始化表
int Initlist(Seqlist& L)
{
L.data = new ElemType[Initsize]; //为顺序表分配一个大小为Initsize的数组空间
if (!L.data)
exit(OVERFLOW); //存储空间分配失败
L.length = 0;
return 0;
}
//(2)创建一个长度为n的表
bool Creatlist(Seqlist& L, int n)
{
if (n<0 || n>Maxsize)
return false;
else
{
for (int i = 0; i < n; i++)
{
cin >> L.data[i]; //键入数据
L.length++;
}
return true;
}
}
//(3)判别空表
bool Empty(Seqlist& L)
{
if (L.length == 0)
return true;//是空表
else
return false;
}
//(4)打印表
bool Printlist(Seqlist& L)
{
if (Empty(L))
return false;
else
{
for (int i = 0; i < L.length; i++)
cout << L.data[i]<<" "; //不换行输出
return true;
}
}
//(5)求表长
int Length(Seqlist& L)
{
return L.length;
}
//(6)按值查找,返回位置信息
int LocateElem(Seqlist& L, ElemType e)
{
for (int i = 0; i < L.length; i++)
{
if (L.data[i] == e)
cout<< i + 1 << " ";//返回所有遇见的结果
//return i+1 //返回第一次遇见的结果
}
return 0;
}
//(7)按位i查找,返回数值e
bool GetElem(Seqlist& L, int i, ElemType& e)
{
if (i<1 || i>L.length)
return false;
else
{
e = L.data[i - 1];
return true;
}
}
//(8)在表的第i的位置插入值e
bool ListInsert(Seqlist& L, int i, ElemType e)
{
if (i<1 || i>L.length + 1) //判断i的范围是否有效
return false;
if (L.length >= Maxsize) //当前存储空间已满,不能插入
return false;
for (int j = L.length; j >= i; j--) //将第i个位置元素及以后的元素“后移”
L.data[j] = L.data[j - 1];
/*
for (int j = i; j < L.length + 1; j++)
L.data[j] = L.data[j - 1]; //这样是不行的,会把原来的数据覆盖
*/
L.data[i - 1] = e;
L.length++;
return true;
}
//(9)删除表中第i个位置的值,并把值暂时赋给e
bool ListDelete(Seqlist& L, int i, ElemType& e)
{
if (i < 1 || i > L.length)//判断i的范围是否有效
return false;
e = L.data[i - 1];
for (int j = i; j < L.length; j++)
L.data[j - 1] = L.data[j];
L.length--;
return true;
}
//(10)销毁表
bool DestroyList(Seqlist& L)
{
delete[] L.data;
cout << "销毁成功" << endl;
return true;
}
int main()
{
//(1)定义表
Seqlist L;
//(2)初始化表
Initlist(L);
//(3)创建大于初始化长度的表,表长为7
Creatlist(L, 7);
//(4)打印表
Printlist(L);
cout << endl;
//(5)查找数值为3的“所有”位置信息
LocateElem(L, 3);
cout << endl;
//(6)查找位置为4的数值,用e1暂存
ElemType e1;
GetElem(L, 4, e1);
cout << e1 << endl;
//(7)在第3个位置插入值9
ListInsert(L, 3, 9);
Printlist(L);
cout << endl;
//(8)删除第3分位置的值,用e2暂存
ElemType e2;
ListDelete(L, 3, e2);
Printlist(L);
//(9)销毁表
DestroyList(L);
system("pause");
return 0;
}
注:这里的销毁函数似乎有些问题,但我还没有改正
总结与思考:
(1)我明白了动态分配和静态分配的定义、区别和使用;
(2)在函数定义中,尤其是对插入和删除,因为顺序表数据会通过移动覆盖来达到删除和添加的功能,所以一定要小心使用,千万不要把原数据给覆盖掉;
(3)静态分配的函数操作基本一致;