顺序表——用顺序存储的方式实现线性表。(逻辑相邻——>物理相邻)
#define MaxSize 10 //定义最大长度
typedef struct{
ElemType data[MaxSize]; // 用静态的“数组”存放数据元素
int length; // 顺序表的当前长度
}SqList; // 顺序表的类型定义(静态分配方式)
完整例子:
#include
#define MaxSize 10 // 定义最大长度
typdef struct{
int data[MaxSize]; // 用静态的“数组”存放数据元素
int length; // 顺序表的当前长度
}SqList; // 顺序表的类型定义
/* 基本操作——初始化表 */
void InitList(SqList &L){
for(int i = 0; i < MaxSize; i++)
L.data[i] = 0; // 将所有数据元素设置为默认初始值(可省略)
L.length = 0; // 顺序表初始长度为0
}
int main(){
SqList L; // 声明一个顺序表
InitList(L); // 初始化顺序表
/* 后续操作 */
return 0;
}
#define InitSize 10 // 顺序表的初始长度
typedef struct{
ElemType *data; // 指示动态分配数组的指针
int MaxSize; // 顺序表的最大容量
int length; // 顺序表的当前长度
}SeqList; // 顺序表的类型定义(动态分配方式)
完整例子:
#include
#include
#define InitSize 10 // 顺序表的初始长度
typedef struct{
ElemType *data; // 指示动态分配数组的指针
int MaxSize; // 顺序表的最大容量
int length; // 顺序表的当前长度
}SeqList; // 顺序表的类型定义(动态分配方式)
/* 初始化表 */
void InitList(SeqList &L){
L.data = (int *)malloc(InitSize * sizeof(int)); // 用malloc函数申请一片连续的存储空间
L.length = 0;
L.MaxSize = InitSize;
}
/* 增加动态数组的长度 */
void IncreaseSize(SeqList &L, int len){
// 指针p指向原本的L表
int *p = L.data;
// L表重新申请了增加长度后的相应大小内存空间
L.data = (int *)malloc((L.MaxSize + len) * sizeof(int));
// 此时p指向旧内存空间,L指向新内存空间,数据仍在旧内存空间中
for(int i = 0; i < L.length; i++){
L.data[i] = p[i]; // 将旧内存空间中的数据复制到新空间中
}
L.MaxSize = L.MaxSize + len; // 更新顺序表的最大容量
free(p); // 释放旧的内存空间
}
int main(){
SeqList L;
InitList(L);
/* ...... */
IncreaseSize(L, 5);
return 0;
}
顺序表特点:
ListInsert(&L, i, e)
插入操作,在表L中的第i个位置上插入制定元素e。
#include
#define MaxSize 10 // 定义最大长度
typdef struct{
int data[MaxSize]; // 用静态的“数组”存放数据元素
int length; // 顺序表的当前长度
}SqList; // 顺序表的类型定义
/* 基本操作——初始化表 */
void InitList(SqList &L){
for(int i = 0; i < MaxSize; i++)
L.data[i] = 0; // 将所有数据元素设置为默认初始值(可省略)
L.length = 0; // 顺序表初始长度为0
}
void ListInsert(SqList &L, int i, int e){
for(int j = L.length; j >= i; j--) // 将第i个元素及之后的元素后移
L.data[j] = L.data[j - 1];
L.data[i - 1] = e; // 在i位置放入e
L.length ++; // 长度+1
}
int main(){
SqList L; // 声明一个顺序表
InitList(L); // 初始化顺序表
/* 后续操作 */
return 0;
}
算法强壮性:
1
到length+1
之间用bool
函数实现(bool
的返回值要么是true要么是false)
bool ListInsert(SqList &L, int i, int 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];
L.data[i - 1] = e; // 在位置i处放入e
L.length++; // 长度+1
return true;
}
时间复杂度分析:
n p + ( n − 1 ) p + ( n − 2 ) p + . . . . . . + 1 ⋅ p = [ n ( n + 1 ) / 2 ] ⋅ [ 1 / n + 1 ] = n / 2 np+(n-1)p+(n-2)p+......+1·p=[n(n+1)/2]·[1/n+1]=n/2 np+(n−1)p+(n−2)p+......+1⋅p=[n(n+1)/2]⋅[1/n+1]=n/2
平均时间复杂度=O(n/2)=O(n)
ListDelete(&L, i, &e)
删除操作,删除表L中的第i个位置的元素,并用e返回删除元素的值。
代码实现:
bool ListDelete(SqList &L, int i, int &e){
if(i < 1 || i > L.length) // 判断i的范围是否有效
return false;
e = L.data[i - 1]; // 将被删除的元素复制给e
for(int j = i; j < L.length; j++) // 将第i个位置后的元素前移
L.data[j - 1] = L.data[j];
L.length--; // 线性表长度-1
return true;
}
时间复杂度分析:
GetElem(L, i)
按位查找操作。获取表L中第i个位置的元素的值。
ElemType GetElem(SqList L, int i){
return L.data[i - 1];
}
时间复杂度:O(1)
LocateElem(L, e)
按值查找操作。在表L中查找具有给定关键字值的元素。
int LocateElem(SeqList L, ElemType e){
for(int i = 0; i < L.length; i++)
if(L.data[i] == e)
return i + 1;
return 0;
}
时间复杂度:
#include
#include
#define MaxSize 10 // 定义表最大长度
#define InitSize 10 // 定义表初始长度
/* 静态分配方式定义 */
typedef struct{
int data[MaxSize]; // 存放数据元素
int length; // 当前表长
}SqList;
/* 动态分配方式定义 */
typedef struct{
int *data; // 指针指向动态分配数组
int DMaxSize; // 表的最大容量
int length; // 当前表长
}SeqList;
/* 初始化表——静态 */
void InitJList(SqList &L)
{
for(int i = 0; i < MaxSize; i++)
L.data[i] = 0; // 表中所有元素默认为0
L.length = 0; // 表长为0
}
/* 初始化表——动态 */
void InitDList(SeqList &L)
{
L.data = (int *)malloc(InitSize * sizeof(int)); // 用malloc函数申请一片连续的存储空间
L.length = 0;
L.DMaxSize = InitSize;
}
/* L1顺序表插入 */
bool SListInsert(SqList &L, int i, int 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];
L.data[i - 1] = e; // 在位置i处放入e
L.length++; // 长度+1
return true;
}
/* L1插入实现 */
void SteListInsert(SqList &L)
{
int i, e;
printf("在第几个位置插入几?\n");
scanf("%d %d",&i, &e);
if(SListInsert(L, i, e))
{
printf("插入成功\n");
printf("L1表的第%d个位置的值为%d\n", i, L.data[i-1]);
}
else
printf("插入错误\n");
printf("\n");
}
/* L2顺序表插入 */
bool LListInsert(SeqList &L, int i, int 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];
L.data[i - 1] = e; // 在位置i处放入e
L.length++; // 长度+1
return true;
}
/* L2插入实现 */
void LivListInsert(SeqList &L)
{
int i, e;
printf("在第几个位置插入几?\n");
scanf("%d %d",&i, &e);
if(LListInsert(L, i, e))
{
printf("插入成功\n");
printf("L2表的第%d个位置的值为%d\n", i, L.data[i-1]);
}
else
printf("插入错误\n");
printf("\n");
}
/* L1顺序表删除 */
bool SListDelete(SqList &L, int i, int &e)
{
if(i < 1 || i > L.length) // 判断i的范围是否有效
return false;
e = L.data[i - 1]; // 将被删除的元素复制给e
for(int j = i; j < L.length; j++) // 将第i个位置后的元素前移
L.data[j - 1] = L.data[j];
L.length--; // 线性表长度-1
return true;
}
/* L1删除实现 */
void SteListDelete(SqList &L)
{
int i, e;
printf("要删除第几个元素?\n");
scanf("%d", &i);
if(SListDelete(L, i, e))
{
printf("删除成功!\n");
printf("删除的元素为%d\n", e);
}
else
printf("删除失败\n");
printf("\n");
}
/* L2顺序表删除 */
bool LListDelete(SeqList &L, int i, int &e)
{
if(i < 1 || i > L.length) // 判断i的范围是否有效
return false;
e = L.data[i - 1]; // 将被删除的元素复制给e
for(int j = i; j < L.length; j++) // 将第i个位置后的元素前移
L.data[j - 1] = L.data[j];
L.length--; // 线性表长度-1
return true;
}
/* L2删除实现 */
void LivListDelete(SeqList &L)
{
int i, e;
printf("要删除第几个元素?\n");
scanf("%d", &i);
if(LListDelete(L, i, e))
{
printf("删除成功!\n");
printf("删除的元素为%d\n", e);
}
else
printf("删除失败\n");
printf("\n");
}
/* L1按位查找 */
int SGetElem(SqList L, int i)
{
if(i < 1 || i > L.length)
return 0;
else
return L.data[i - 1];
}
/* L1按位查找实现 */
void SteGetElem(SqList L)
{
int i;
printf("要查找第几个元素?\n");
scanf("%d", &i);
if(SGetElem(L, i) != 0)
printf("第%d个元素为%d\n", i, SGetElem(L, i));
else
printf("超出查询范围\n");
printf("\n");
}
/* L2按位查找 */
int LGetElem(SeqList L, int i)
{
if(i < 1 || i > L.length)
return 0;
else
return L.data[i - 1];
}
/* L2按位查找实现 */
void LivGetElem(SeqList L)
{
int i;
printf("要查找第几个元素?\n");
scanf("%d", &i);
if(LGetElem(L, i) != 0)
printf("第%d个元素为%d\n", i, LGetElem(L, i));
else
printf("超出查询范围\n");
printf("\n");
}
/* L1按值查找 */
int SLocateElem(SqList L, int e)
{
for(int i = 0; i < L.length; i++)
if(L.data[i] == e)
return i + 1;
return 0;
}
/* L1按值查找实现 */
void SteLocateElem(SqList L)
{
int e;
printf("请输入需要查找的数值\n");
scanf("%d", &e);
if(SLocateElem(L, e) == 0)
printf("未查询到此值\n");
else
printf("此值在第%d个位置\n",SLocateElem(L, e));
printf("\n");
}
/* L2按值查找 */
int LLocateElem(SeqList L, int e)
{
for(int i = 0; i < L.length; i++)
if(L.data[i] == e)
return i + 1;
return 0;
}
/* L2按值查找实现 */
void LivLocateElem(SeqList L)
{
int e;
printf("请输入需要查找的数值\n");
scanf("%d", &e);
if(LLocateElem(L, e) == 0)
printf("未查询到此值\n");
else
printf("此值在第%d个位置\n",LLocateElem(L, e));
printf("\n");
}
/* L1打印整表 */
void PrintSListElem(SqList L)
{
if(L.length == 0)
printf("此表为空,请先插入数值\n");
else
for(int i = 0; i < L.length; i++)
printf("第%d个值:%d\n", i+1, L.data[i]);
printf("\n");
}
/* L2打印整表 */
void PrintLListElem(SeqList L)
{
if(L.length == 0)
printf("此表为空,请先插入数值\n");
else
for(int i = 0; i < L.length; i++)
printf("第%d个值:%d\n", i+1, L.data[i]);
printf("\n");
}
int main()
{
int i;
SqList L1; // 声明顺序表(静态分配)
SeqList L2; // 声明顺序表(动态分配)
InitJList(L1); // 初始化静态分配顺序表
InitDList(L2); // 初始化动态分配顺序表
while(1)
{
printf("请输入操作:\n");
printf("1.L1表插入数值;\n");
printf("2.L2表插入数值;\n");
printf("3.L1表删除数值;\n");
printf("4.L2表删除数值;\n");
printf("5.L1表按位查找;\n");
printf("6.L2表按位查找;\n");
printf("7.L1表按值查找;\n");
printf("8.L2表按值查找;\n");
printf("9.打印L1表;\n");
printf("10.打印L2表;\n");
printf("11.退出;\n");
scanf("%d", &i);
switch(i)
{
case 1: SteListInsert(L1); break;
case 2: LivListInsert(L2); break;
case 3: SteListDelete(L1); break;
case 4: LivListDelete(L2); break;
case 5: SteGetElem(L1); break;
case 6: LivGetElem(L2); break;
case 7: SteLocateElem(L1); break;
case 8: LivLocateElem(L2); break;
case 9: PrintSListElem(L1); break;
case 10: PrintLListElem(L2); break;
}
if(i == 11)
break;
}
return 0;
}