数据结构--顺序表简单实现(总结)
Posted 庸人冲
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了数据结构--顺序表简单实现(总结)相关的知识,希望对你有一定的参考价值。
特点
- 顺序表是有序、有限,且元素数据类型相同的集合。
- 除第一个元素外,其他元素都有唯一的前驱元素。
- 除最后一个元素外,其他的元素都有唯一的后继元素。
- 顺序表中的元素总数
n(n ≥ 0)
即为顺序表的长度,n = 0
时,顺序表的长度为0,为空表。
功能实现
定义
#define SUC 1 // 定义SUC 作为状态返回值,成功
#define ERR 0 // 定义ERR 作为状态返回值,错误
#define TRUE 1 // 定义TRUE 作为真假返回值,真
#define FALSE 0 // 定义FALSE 作为真假返回值,假
#define MAXSIZE 20 // 定义MAXSIZE为存储空间最大容量,依据情况而定
typedef int Status; // 定义Status作为状态返回类型
typedef int Bool; // 定义Bool 作为判断真假返回类型
typedef int ElemType ; // ElemType 表示表中元素数据类型,依据情况而定
typedef struct // 定义存储结构
{
ElemType data[MAXSIZE]; // 定义数组,作为顺序表的存储结构
int len; // 定义len,表示【顺序表】长度
} SqList;
函数
初始化
功能:将顺序表长度初始化为0。
参数类型:SqList*
返回值类型:Status
Status InitList(SqList* L)
{
L->len = 0;
return SUC;
}
重置表
功能:将顺序表长度重置为0,置为空表,该操作是对于以创建顺序表的操作。
参数类型:SqList*
返回值类型:Status
Status ResetList(SqList* L)
{
L->len = 0;
return SUC;
}
获取表长
功能:获取顺序表的长度。
参数类型:SqList
返回值类型:int
int ListLength(SqList L)
{
return L.len;
}
判断是否为空表
功能:判断顺序表是否为空表
参数类型:SqList
返回值类型:Bool
Bool isEmpty(SqList L)
{
return L.len == 0 ? TRUE : FALSE;
}
访问元素
功能:输出指定元素至控制台
参数类型:ElemType
返回值类型:Status
Status visit(ElemType e)
{
printf("%d ",e);
return SUC;
}
遍历顺序表
功能:遍历顺序表中每个元素
参数类型:SqList
返回值类型:Status
Status ListTraverse(SqList L)
{
int i = 0;
int len = L.len;
for(i = 0; i < len; i++)
{
visit(L.data[i]);
}
printf("\\n");
return SUC;
}
获取元素
功能:将指定位置上的元素的值赋值给接收元素
参数类型:SqList
、ElemType*
(接收元素)、int
(位置)
返回值:Status
说明:
- 判断顺序表是否为空表?为空表返回ERR
- 判断指定位置是否合法?非法返回ERR
Status GetElem(SqList L, ElemType* e, int p)
{
if(L.len == 0 || p < 1 || p > L.len)
{
return ERR;
}
*e = L.data[p - 1];
return SUC;
}
查找元素
功能:查找指定元素在顺序表中的位置
参数类型:SqList
、ElemType
返回值:int
说明:
- 判断顺序表是否为空表,空表返回0
- 遍历顺序表查找到则返回该位置,否则返回0
int LocataElem(SqList L, ElemType e)
{
if(L.len == 0)
{
return 0; // 空表返回0
}
int i = 0;
for(i = 0; i < L.len; i++)
{
if(L.data[i] == e)
return i + 1; // 找到则返回位置
}
return 0; // 找不到则返回0
}
头插
功能:将元素添加至顺序表头。
参数类型:SqList*
、ElemType
(添加的元素)
返回值类型:Status
说明:
- 判断顺序表是否已满
- 将所有元素整体后移一位
- 将元素添加至表头,表长+1
Status PushFront(SqList* L, ElemType e)
{
int i = 0;
if (L->len == MAXSIZE) // 判断顺序表是否已满
{
return ERR;
}
for (i = L->len - 1; i >= 0; i--)
{
L->data[i + 1] = L->data[i]; // 将所有元素整体后移一位
}
L->data[0] = e; // 将元素添加至表头
L->len++; // 表长+1
return SUC;
}
尾插
功能:判断将元素添加至表尾
参数类型:SqList*
、ElemType
(添加的元素)
返回值类型:Status
说明:
- 判断顺序表是否已满
- 将元素添加至表尾,表长+1
Status PushBack(SqList* L, ElemType e)
{
if (L->len == MAXSIZE)
{
return ERR; // 顺序表已满,则返回ERR
}
L->data[L->len] = e; // 将元素添加至尾部,L->len是顺序表最后一个元素后一个位置,即表尾
L->len++; // 顺序表长度+1
return SUC;
}
指定位置插入元素
功能:将元素添加至顺序表中指定位置。
参数类型:SqList*
、ElemType
(添加的元素)、int
(位置)
返回值类型:Status
说明:
在添加元素前需要判断三点:
-
当前顺序表是否已满?
-
添加的位置是否不合理?
-
判断添加的位置是否在表尾?
如果在表尾添加元素则不需要移动表中其他元素,否则需要将添加位置后的所有元素整体向后移动一位(包括添加位置的当前元素)。
添加完毕后,将表长+1,返回SUC
。
Status InsertPos(SqList* L, ElemType e, int p)
{
if (L->len == MAXSIZE || p < 1 || p > L->len + 1) // 判断顺序表是否已满,或则插入位置是否合理
{ // L->len+1, 连续线性表,中间不能存在空位置
return ERR;
}
if (p <= L->len) // 判断添加位置是否在表尾,表尾不需要移动表中其他元素
{ // 进入语句,说明p不在表尾
int i = 0;
for (i = L->len - 1; i >= p - 1; i--)
{
L->data[i + 1] = L->data[i]; // 则需要将添加位置后的所有元素向后移动一位
}
}
L->data[p - 1] = e; // 将指定元素添加到指定位置
L->len++; // 表长+1
return SUC;
}
头删
功能:将顺序表头的元素删除
参数类型:SqList*
、 ElemType*
(接收删除的元素)
返回值类型:Status
说明:
- 判断表是否为空,为空返回ERR;
- 将顺序表说有元素整体前移一位
- 顺序表长度-1
Status PopFront(SqList* L, ElemType* e)
{
if (L->len == 0)
return ERR; // 顺序表为空,返回ERR
*e = L->data[0]; // 将被删除的元素赋值给*e
int i = 0;
for (i = 0; i < L->len - 1; i++)
{
L->data[i] = L->data[i + 1]; // 将所有元素整体前移一位
}
L->len--; // 顺序表长度减1
return SUC; // 返回SUC
}
尾删
功能:将顺序表尾的元素删除
参数类型:SqList*
、 ElemType*
(接收删除的元素)
返回值类型:Status
说明:
- 判断表是否为空,为空返回ERR
- 变量接收被删除的元素
- 顺序表长度-1
Status PopBack(SqList* L, ElemType* e)
{
if (L->len == 0)
return ERR; // 顺序表为空,返回ERR
*e = L->data[L->len - 1]; // 被删除的元素赋值给*e, L->len - 1为最后一个元素的下标
L->len--; // 将表长-1,达到删除表尾元素目的
return SUC;
}
指定位置删除元素
功能:删除顺序表指定位置元素
参数类型:SqList*
、ElemType*
(接收删除的元素)、int
(指定删除的位置)
返回值类型:Status
说明:
- 判断表是否为空,或者删除位置是否合法,如果为真,则返回ERR。
- 将被删除的元素赋值给外部变量。
- 判断删除位置是否为最后一个元素,若不是是最后一个元素则将删除位置后的所有元素整体前移一位。
- 顺序表长度-1。
- 返回SUC。
Status DeletePos(SqList* L, ElemType* e, int p)
{
if (L->len == 0 || p < 1 || p > L->len) // 判断表是否为空,或者位置是否合法
return ERR;
*e = L->data[p - 1]; // 将被删除的元素赋值给*e
if (p < L->len) // 判断删除位置是否为最后一个元素
{
int i = 0;
for (i = p; i < L->len; i++)
{
L->data[i - 1] = L->data[i]; // 若不是最后一个元素则将删除位置后的所有元素整体前移一位
}
}
L->len--;
return SUC;
}
指定元素删除
功能:将指定的元素从顺序表中删除
参数类型:SqList*
、ElemType
(指定删除元素)
返回值类型:Status
说明:
- 调用
LocataElem()
函数获取指定元素的位置 - 如果
LocataElem()
的返回值不为 0,调用DeletePos
() 函数将指定元素删除,并返回SUC - 否则返回ERR;
Status DeleteElem(SqList* L, ElemType* e)
{
int p = LocataElem(*L, *e);
if (p)
{
DeletePos(L, e, p);
return SUC;
}
return ERR;
}
合并表
功能:将存在于表b
,不存在于表a
的元素,添加进表a
末尾
参数类型:SqList*
、SqList
返回值类型:void
说明:
- 访问
表b
中的问一个元素,需要用到GetElem()
函数。 - 将获取的元素与
La
中的每一个元素进行对比。需要用到LocateElem()
。 LocateElem()
的返回值为0,则说明La中不存在这个元素。- 调用
PushBack()
函数,将该元素添加至La表尾.
void UnionList(SqList* La, SqList Lb)
{
ElemType e; // 元素e 用来比较两表中是否存在元素e
// 获取两个表的长度
int La_len = La->len;
int Lb_len = Lb.len;
int i = 0;
for (i = 1; i <= Lb_len; i++) // 获取Lb中的每一个元素
{
GetElem(Lb, &e, i);
if (!LocataElem(*La, e)) // 如果La中没有该元素,将该元素添加至表尾。
{
PushBack(La, e);
}
}
}
测试代码
#define SUC 1 // 定义SUC 作为状态返回值,成功
#define ERR 0 // 定义ERR 作为状态返回值,错误
#define TRUE 1 // 定义TRUE 作为真假返回值,真
#define FALSE 0 // 定义FALSE 作为真假返回值,假
#define MAXSIZE 20 // 定义MAXSIZE为存储空间最大容量,依据情况而定
typedef int Status; // 定义Status作为状态返回类型
typedef int Bool; // 定义Bool 作为判断真假返回类型
typedef int ElemType ; // ElemType 表示表中元素数据类型,依据情况而定
typedef struct // 定义存储结构
{
ElemType data[MAXSIZE]; // 定义数组,作为线性表的存储结构
int len; // 定义len,表示【线性表】长度
} SqList;
// 初始化
Status InitList(SqList* L)
{
L->len = 0; // 将表长初始化为0,该操作是是对于新创建的表
return SUC;
}
// 重置表
Status ResetList(SqList* L)
{
L->len = 0; // 将顺序表长度重置为0,置为空表,该操作是对于以创建顺序表的操作。
return SUC;
}
// 判断是否为空表
Bool isEmpty(SqList L)
{
return L.len == 0 ? TRUE : FALSE;
}
// 获取表长
int ListLength(SqList L)
{
return L.len;
}
// 访问元素
Status visit(ElemType e)
{
printf("%d ", e); // 打印元素
return SUC;
}
// 遍历表
Status ListTraverse(SqList L)
{
int i = 0;
int len = L.len;
for (i = 0; i < len; i++)
{
visit(L.data[i]); // 调用visit函数依次打印顺序表中的元素
}
printf("\\n");
return SUC;
}
// 获取元素
Status GetElem(SqList L, ElemType* e, int p)
{
if (L.len == 0 || p < 1 || p > L.len)
{
return ERR; // 空表,或位置不合法返回ERR
}
*e = L.data[p - 1]; // 将指定位置的元素赋值给e,e为真正的返回值
return SUC; // SUC为返回的状态
}
// 查找元素
int LocataElem(SqList L, ElemType e)
{
if (L.len == 0)
{
return 0; // 空表返回0
}
int i = 0;
for (i = 0; i < L.len; i++)
{
if (L.data[i] == e)
return i + 1; // 找到则返回位置
}
return 0; // 找不到则返回0
}
// 头插
Status PushFront(SqList* L, ElemType e)
{
int i = 0;
if (L->len == MAXSIZE)
{
return ERR; // 顺序表已满,则返回ERR
}
for (i = L->len - 1; i >= 0; i--)
{
L->data[i + 1] = L->data[i]; // 将所有元素整体后移一位
}
L->data[0] = e; // 将元素添加至表头
L->len++; // 表长+1
return SUC;
}
// 尾插
Status PushBack(SqList* L, ElemType e)
{
if (L->len == MAXSIZE)
{
return ERR; // 顺序表已满,则返回ERR
}
L->data[L->len] = e; // 将元素添加至尾部,L->len是顺序表最后一个元素后一个位置,即表尾
L->len++; // 顺序表长度+1
return SUC;
}
// 按位置插入
Status InsertPos(SqList* L, ElemType e, int p)
{
if (L->len == MAXSIZE || p < 1 || p > L->len + 1) // 判断顺序表是否已满,或则插入位置是否合理
{ // L->len+1, 连续线性表,中间不能存在空位置
return ERR;
}
if (p <= L->len) // 判断添加位置是否在表尾,表尾不需要移动表中其他元素
{ // 进入语句,说明p不在表尾
int i = 0;
for (i = L->len - 1; i >= p - 1; i--)
{
L->data[i + 1] = L->data[i]; // 则需要将添加位置后的所有元素向后移动一位
}
}
L->data[p - 1] = e; // 将指定元素添加到指定位置
L->len++; // 表长+1
return SUC;
}
// 头删
Status PopFront(SqList* L, ElemType* e)
{
if (L->len == 0)
return ERR; // 顺序表为空,返回ERR
*e = L->data[0]; // 将被删除的元素赋值给*e
int i = 0;
for (i = 0; i < L->len - 1; i++)
{
L->data[i] = L->data[i + 1]; // 将所有元素整体前移一位
}
L->len--; // 顺序表长度减1
return SUC; // 返回SUC
}
// 头删
Status PopBack(SqList* L, ElemType* e)
{
if (L->len == 0)
return ERR; // 顺序表为空,返回ERR
*e = L->data[L->len - 1]; // 被删除的元素赋值给*e, L->len - 1为最后一个元素的下标
L->len--; // 将表长-1,达到删除表尾元素目的
return SUC;
}
// 指定位置删除
Status DeletePos(SqList* L, ElemType* e, int p)
{
if (L->len == 0 || p < 1 || p > L->len) // 判断表是否为空,或者位置是否合法
return ERR;
*e = L->data[p - 1]; // 将被删除的元素赋值给*e
if (p < L->len) // 判断删除位置是否为最后一个元素
{
int i = 0;
for (i = p; i < L->len; i++)
{
L->data[i - 1] = L->data[i]; // 若不是最后一个元素则将删除位置后的所有元素整体前移一位
}
}
L->len--;
return SUC;
}
// 指定元素删除
Status DeleteElem(SqList* L, ElemType* e)
{
int p = LocataElem(*L, *e);
if (p)
{
DeletePos(L, e, p);
return SUC;
}以上是关于数据结构--顺序表简单实现(总结)的主要内容,如果未能解决你的问题,请参考以下文章