顺序表的要点在于:
一、表长(length)和表的最大存储空间(Maxsize)
两者的关系类似于一间教室里实际坐了多少人,和一间教室里最多能容纳多少人。
二、位序和数组下标的区分
1.顺序表数组空间静态分配
#include <iostream>
#include<stdlib.h>
using namespace std;
typedef int ElemType;//顺序表存储的元素类型,可更改
#define Maxsize 50//设置顺序表的最大容纳空间,可更改
//顺序表静态定义
typedef struct Sqlist {
ElemType data[Maxsize];//顺序表的静态数组
int length;//顺序表的长度
}Sqlist;
//顺序表初始化
void InitList(Sqlist &mylist)
{
mylist.length = 0;//先初始化顺序表长度
//依次输入整型数据存放在顺序表L中
ElemType temp;//temp作为临时变量存储输入的数据元素
int n;//n用来存放输入的数据元素个数
cout << "你将要向顺序表中输入的数据元素的个数为:" << '\t';
cin >> n;
cout << "依次输入" << n << "个整型数存入顺序表中:" << endl;
for (int i = 1; i <= n; i++)//依次输入n个整型数存入顺序表中
{
cout << "请输入第" << i << "个整型数依次存入顺序表。" << '\t';
cin >> temp;
mylist.data[i - 1] = temp;
mylist.length++;
}
cout << "已经将输入的" << n << "个整型数依次存入顺序表。" << endl;
}
//求表长
int Length(Sqlist mylist)
{
return mylist.length;
}
//按值查找,该值在表中第一个出现的位置
bool LocateElem(Sqlist mylist, ElemType &e, ElemType &num)
{
if (mylist.length <= 0)//若是空表返回错误
{
return 0;
}
for (int i = 1; i <= mylist.length; i++)
{
if (mylist.data[i-1] == e)
{
num = i;//用num表示该值第一次出现的位置
return true;
}
}
return false;
}
//插入操作,插入位序为i的元素之前
bool ListInsert(Sqlist &mylist, int i, int &e)
{
if (mylist.length >= Maxsize)//表长超出表存储空间的最大值
return false;//这里可以看出静态存储的缺点,一旦表长超出表的存储空间需要手动修改。
if (i<1 || i>mylist.length)//i超出范围
return false;
for (int j = mylist.length; j >= i; j--)//从后向前给插入的元素挪位置
{
mylist.data[j] = mylist.data[j - 1];
}
mylist.data[i - 1] = e;//将新元素插入
mylist.length++;//表长加一
return true;
}
//按位序删除操作
bool ListDelete(Sqlist &mylist, int i, ElemType &e)
{
if (mylist.length <= 0)//顺序表里没有元素
return false;
if (i<1 || i>mylist.length)//i超出范围
return false;
e = mylist.data[i - 1];//将删除的元素用e保存起来
for (int j = i; j <= mylist.length; j++)//从i开始后面的向前覆盖
{
mylist.data[j - 1] = mylist.data[j];
}
mylist.length--;//表长减一
return true;
}
//打印顺序表
void PrintList(Sqlist mylist)
{
for (int j=1; j <= mylist.length; j++)
{
cout << mylist.data[j - 1] << "\t";
}
cout << endl;
}
int main()
{
Sqlist mylist;
InitList(mylist);
PrintList(mylist);
//按值查找
int e = 3;
int num = 0;
if (LocateElem(mylist, e, num))
{
cout << e << "第一次出现的位序在" << num << endl;
}
else
{
cout << "查找失败" << endl;
}
//按位序删除
if (ListDelete(mylist, num, e))
{
PrintList(mylist);
}
else
{
cout << "删除失败" << endl;
}
return 0;
}
此时顺序表数组空间的静态分配缺点暴露,在插入元素时当length≥Maxsize是需要手动调整Maxsize。
2.顺序表数组空间的动态定义
#include <iostream>
#include<stdlib.h>
using namespace std;
#define ListInitSize 50//线性表的初始存储空间
#define ListIncrement 10//线性表存储空间的分配增量
typedef int ElemType;//顺序表存储的元素类型,可更改
//顺序表结构体定义
typedef struct Sqlist {
ElemType * elem;//存储空间基地址
int length;//顺序表的长度
int listsize;//当前分配的存储容量
}Sqlist;
//初始化顺序表
bool InitList(Sqlist &mylist)
{
//先初始化顺序表
mylist.elem = new ElemType[ListInitSize];
if (!mylist.elem)
return false;
else
{
mylist.length = 0;
mylist.listsize = ListInitSize;
//依次输入整型数据存放在顺序表L中
ElemType temp;//temp作为临时变量存储输入的数据元素
int n;//n用来存放输入的数据元素个数
cout << "你将要向顺序表中输入的数据元素的个数为:" << '\t';
cin >> n;
cout << "依次输入" << n << "个整型数存入顺序表中:" << endl;
for (int i = 1; i <= n; i++)//依次输入n个整型数存入顺序表中
{
cout << "请输入第" << i << "个整型数依次存入顺序表。" << '\t';
cin >> temp;
mylist.elem[i - 1] = temp;
mylist.length++;
}
cout << "已经将输入的" << n << "个整型数依次存入顺序表。" << endl;
return true;
}
}
//求表长
int Length(Sqlist mylist)
{
return mylist.length;
}
//按值查找,该值在表中第一个出现的位置
bool LocateElem(Sqlist mylist, ElemType &e, ElemType &num)
{
if (mylist.length <= 0)
{
return 0;
}
for (int i = 1; i <= mylist.length; i++)
{
if (mylist.elem[i - 1] == e)
{
num = i;
return true;
}
}
return false;
}
//插入操作,插入位序为i的元素之前
bool ListInsert(Sqlist &mylist, int i, int &e)
{
if (mylist.length >= ListInitSize)//表长超出存储空间
{
ElemType * newbase = new ElemType[mylist.listsize + ListIncrement];//新开辟一段空间
for (int j = 0; j < mylist.length; ++j)//复制数据到新分配的存储空间
newbase[j] = mylist.elem[j];
delete[](mylist.elem);//释放旧存储空间
mylist.elem = newbase;//新基址
mylist.listsize += ListIncrement;//增加存储容量
}
if (i<1 || i>mylist.length)//i超出范围
return false;
for (int j = mylist.length; j >= i; j--)
{
mylist.elem[j] = mylist.elem[j - 1];
}
mylist.elem[i - 1] = e;
mylist.length++;
return true;
}
//按位序删除操作
bool ListDelete(Sqlist &mylist, int i, ElemType &e)
{
if (mylist.length <= 0)
return false;
if (i<1 || i>mylist.length)
return false;
e = mylist.elem[i - 1];
for (int j = i; j <= mylist.length; j++)
{
mylist.elem[j - 1] = mylist.elem[j];
}
mylist.length--;
return true;
}
//打印顺序表
void PrintList(Sqlist mylist)
{
for (int j = 1; j <= mylist.length; j++)
{
cout << mylist.elem[j - 1] << "\t";
}
cout << endl;
}
//销毁顺序表
bool Deletelist(Sqlist &mylist)
{
if (mylist.elem)
{
delete[]mylist.elem;
return true;
}
else
{
return false;
}
}
int main()
{
Sqlist mylist;
InitList(mylist);
PrintList(mylist);
//按值查找
int e = 3;
int num = 0;
if (LocateElem(mylist, e, num))
{
cout << e << "第一次出现的位序在" << num << endl;
}
else
{
cout << "查找失败" << endl;
}
//按位序删除
if (ListDelete(mylist, num, e))
{
PrintList(mylist);
}
else
{
cout << "删除失败" << endl;
}
if (Deletelist(mylist))
{
cout << "已经销毁数组" << endl;
}
else
{
cout << "未能销毁数组" << endl;
}
return 0;
}