线性表的顺序存储结构练习过程中遇到的问题
前言
在学习线性表的顺序存储结构过程中,typedef了两个新的结构体,其中一个为指针形式的命名方式,在查阅资料后才明白这种写法。本文同时针对顺序线性表的元素获取、元素插入以及元素删除做了详细的注释,在此写下以备不时之需。
线性表顺序存储结构创建
#define MAXSIZE 20
typedef int ElemType;
typedef struct
{
ElemType data[MAXSIZE];
int length;
} SqList, *pSqList; //typedef 了两个新的数据类型(结构体),其中一个是指针方式的名字。
顺序存储结构三个属性:
- 存储空间起始位置: 数组data,他的存储位置就是存储空间的存储位置。
- 线性表的最大存储容量: 数组长度MAXSIZE。
- 线性表的当前长度: length。
关于“线性表的长度”和“数组的长度”: 线性表的当前长度表示的是线性表中元素的个数,会随着线性表的插入和删除随之改变;而数组的长度是存放线性表的存储空间长度。线性表的长度应该小于或者等于数组的长度。
结构体的声明及元素的访问
SqList L = {{0}, 0}; //SqList 声明的L是一个实体,声明了就已经有存储空间了。
pSqList pL = &L; //pSqList 声明的pL是一个指针(但这里不用加*号,因为pSqList已经被指定为指针),它可以指向一个struct的实体。
L.length = 10; //L的元素访问方式,实体方式
pL->length = 10; //pL的元素访问方式,指针方式
总结: 结构体名字去定义声明的变量是一个真正的变量,它在内存中分配有自己的存储空间;而用指针形式定义的变量是一个指针,使用的时候给它赋予一个结构体变量的地址。参考。
结构体变量直接访问使用实体方式,用“.”;
结构体指针变量访问使用指针方式,用“->”;
元素的获取
/*
功能:元素的获取
说明:获取顺序线性表L中第i个元素,通过e返回其值
*/
Status GetElem(SqList *L, int i, ElemType *e)
{
if (L->length == 0 || i > L->length || i < 1) //顺序线性表的长度为0,或者i不在正确的范围
return ERROR;
*e = L->data[i - 1]; //返回第i个元素的值
return OK;
}
元素的插入
/*
功能:元素的插入
说明:向顺序线性表L中插入一个元素e,L的长度加1
*/
Status ListInsert(SqList *L, int i, ElemType e)
{
int k;
if (L->length == MAXSIZE) //顺序线性表的长度已经达到最大值
return ERROR;
if (i < 1 || i > L->length + 1) //i不在正确的范围内
return ERROR;
if (i <= L->length) //如果插入的位置不是在顺序线性表尾
{
for (k = L->length - 1; k >= i - 1;k--) //将要插入位置后的元素向后移动一位
{
L->data[k + 1] = L->data[k];
}
}
L->data[i - 1] = e; //插入新的元素
L->length++; //表的长度加1
return OK;
}
元素的删除
/*
功能:元素的删除
说明:删除顺序线性表L的第i个元素,并用e返回其值,并且L的长度减1
*/
Status ListDelete(pSqList L, int i, ElemType *e)
{
int k;
if (L->length == 0 || i > L->length - 1 || i < 1) //顺序线性表L的长度已经为0,或者i不在正确的范围内
return ERROR;
*e = L->data[i - 1]; //获取删除元素的值
if (i < L->length) //如果删除的元素不是L的最后一个元素
{
for (k = i; k < L->length; k++) //将删除元素的位置后继元素前移
{
L->data[k - 1] = L->data[k];
}
}
L->length--; //L的长度减1
return OK;
}
完整代码
#include <stdio.h>
#define MAXSIZE 20
#define OK 1
#define ERROR 0
typedef int Status;
typedef int ElemType;
typedef struct
{
ElemType data[MAXSIZE];
int length;
} SqList, *pSqList; //typedef 了两个新的数据类型(结构体),其中一个是指针方式的名字。
/*
功能:元素的获取
说明:获取顺序线性表L中第i个元素,通过e返回其值
*/
Status GetElem(SqList *L, int i, ElemType *e)
{
if (L->length == 0 || i > L->length || i < 1) //顺序线性表的长度为0,或者i不在正确的范围
return ERROR;
*e = L->data[i - 1]; //返回第i个元素的值
return OK;
}
/*
功能:元素的插入
说明:向顺序线性表L中插入一个元素e,L的长度加1
*/
Status ListInsert(SqList *L, int i, ElemType e)
{
int k;
if (L->length == MAXSIZE) //顺序线性表的长度已经达到最大值
return ERROR;
if (i < 1 || i > L->length + 1) //i不在正确的范围内
return ERROR;
if (i <= L->length) //如果插入的位置不是在顺序线性表尾
{
for (k = L->length - 1; k >= i - 1;k--) //将要插入位置后的元素向后移动一位
{
L->data[k + 1] = L->data[k];
}
}
L->data[i - 1] = e; //插入新的元素
L->length++; //表的长度加1
return OK;
}
/*
功能:元素的删除
说明:删除顺序线性表L的第i个元素,并用e返回其值,并且L的长度减1
*/
Status ListDelete(pSqList L, int i, ElemType *e)
{
int k;
if (L->length == 0 || i > L->length - 1 || i < 1) //顺序线性表L的长度已经为0,或者i不在正确的范围内
return ERROR;
*e = L->data[i - 1]; //获取删除元素的值
if (i < L->length) //如果删除的元素不是L的最后一个元素
{
for (k = i; k < L->length; k++) //将删除元素的位置后继元素前移
{
L->data[k - 1] = L->data[k];
}
}
L->length--; //L的长度减1
return OK;
}
int main(void)
{
SqList L = {{0}, 0}; //SqList 声明的L是一个实体,声明了就已经有存储空间了。
pSqList pL = &L; //pSqList 声明的pL是一个指针(但这里不用加*号,因为pSqList已经被指定为指针),它可以指向一个struct的实体。
L.length = 10; //L的元素访问方式,实体方式
pL->length = 10; //pL的元素访问方式,指针方式
Status s = 0;
int i = 2;
ElemType get_elem = 0;
ElemType insert_elem = 20;
ElemType *e = &get_elem;
s = ListInsert(pL, i, insert_elem); //在第2个元素位置插入新元素20,返回结果
if (s) //如果插入成功则读取第2个元素
{
printf("Insert OK, Length is %d\n", L.length);
s = GetElem(pL, i, e);
printf("2th Elem is %d\n", *e);
}
printf("--------\n");
s = ListDelete(pL, i, e); //删除第2个元素,返回结果
if (s) //如果删除成功则读取第2个元素
{
printf("Delete OK, Length is %d\n", L.length);
s = GetElem(pL, i, e);
printf("2th Elem is %d\n", *e);
}
printf("--------\n");
return 0;
}