顺序表中基本操作的具体思路与实现(C语言版)
- 一、操作前的准备工作
- (1)定义操作算法中用到的预定义常量和类型
- (2)定义线性表中可能拥有的元素的最大个数
- (3)定义顺序表类型
- 二、具体操作的实现
- (1)创建顺序表
- (2)初始化顺序表
- (3)销毁顺序表
- (4)清除顺序表
- (5)求顺序表的长度
- (6)判断顺序表是否为空
- (7)顺序表的按位置查找(根据位置position获取相应位置数据元素的值)
- (8)顺序表的按值查找
- 方法一:使用for循环
- 方法二:使用while语句
- (9)顺序表的插入操作
- (10)顺序表的按位置删除操作
- (11)顺序表的求前驱节点操作
- (12)顺序表的求后继节点操作
- (13)显示顺序表操作
- 三、全部代码及其运行结果
一、操作前的准备工作
(1)定义操作算法中用到的预定义常量和类型
//函数结果状态代码:
#define TURE 1
#define FALSE 0
#define OK 1
#define ERROR 0
#define INFEASIBLE -1
#define OVERFLOW -2
//Status是函数的类型,其值是函数结果状态代码
typedef int Status;
typedef int Elemtype;
(2)定义线性表中可能拥有的元素的最大个数
#define MAXSIZE 5
(3)定义顺序表类型
typedef struct {
Elemtype *elem;
int length; //当前顺序表中实际拥有的元素个数,即当前顺序表的长度
}SqList;
二、具体操作的实现
(1)创建顺序表
//创建顺序表
Status List_Creat(SqList* L,int n)
{
int i;
if (n < 1 || n > MAXSIZE)
{
return ERROR;
}
L->elem = (Elemtype*)malloc(sizeof(Elemtype) * MAXSIZE);
L->length = n;
for (i = 0; i < L->length; i++)
{
int temp;
int number = i + 1;
printf("请输入顺序表中的第%d个元素个数:\n", number);
scanf("%d", &temp);
L->elem[i] = temp;
}
return OK;
}
(2)初始化顺序表
malloc(m)函数,开辟m字节长度的地址空间,并返回这段空间的首地址
sizeof(x)函数,计算变量x的长度
思路:
①为顺序表动态分配空间
②如果内存分配失败
③空表长度为0
Status InitList_Sq(SqList *L) {
//malloc(m)函数,开辟m字节长度的地址空间,并返回这段空间的首地址
//sizeof(x)函数,计算变量x的长度
//①为顺序表动态分配空间
L->elem = (Elemtype*)malloc(sizeof(Elemtype)*MAXSIZE);
//②如果内存分配失败
if (!(L->elem)) {
//exit(0) 表示程序正常退出
//exit⑴/exit(-1)表示程序异常退出
//exit() 结束当前进程/当前程序
//在整个程序中只要调用exit就结束
return ERROR;
exit(OVERFLOW);
}
//③空表长度为0
L->length = 0;
return OK;
}
(3)销毁顺序表
Status DestroyList(SqList *L){
if (!L->elem) {
return ERROR;
}
else
{
free(L->elem);
return OK;
}
}
(4)清除顺序表
Status ClearList(SqList *L) {
if (!L->elem) {
return ERROR;
}
else
{
L->length = 0;
return OK;
}
}
(5)求顺序表的长度
Status GetLength(SqList *L)
{
return L->length;
}
(6)判断顺序表是否为空
Status IsEmpty(SqList *L) {
if (L->length == 0) {
return 1;
}
else {
return 0;
}
}
(7)顺序表的按位置查找(根据位置position获取相应位置数据元素的值)
注意:此处的position指的是逻辑位序,从1开始,而物理位序即下标从0开始
Status GetElme(SqList *L, int position, Elemtype *e) {
//判断position的值是否合理,若不合理,返回error
if (position < 1 || position > L->length) {
return ERROR;
}
*e = L->elem[position - 1];//position - 1的单元存放着第position个数据
return OK;
}
(8)顺序表的按值查找
在线性表L中查找与指定值e相同的数据元素的位置
从表的一端开始,逐个进行记录的关键字和给定值的比较。
找到返回该元素的位置序号,未找到,返回0。
方法一:使用for循环
Status LocateElme(SqList *L,Elemtype e){
//法一:使用for循环
//在线性表L中查找值为e的数据元素,返回其序号(是第几个元素)
for (int i = 0; i < L->length; i++)
{
if (L->elem[i] == e) {
return i + 1;//查找成功,返回序号
}
}
return 0;//查找失败,返回0
}
方法二:使用while语句
Status LocateElme(SqList *L,Elemtype e){
//法二:使用while语句
//在线性表l中查找值为e的数据元素,返回其序号(是第几个元素)
int i = 0;
while (i < L->length && L->elem[i] != e)
{
i++;
}
if (i < L->length) {
return i + 1;//查找成功,返回序号
}
return 0;//查找失败,返回0
}
(9)顺序表的插入操作
- 顺序表的插入的含义:线性表的插入运算是指在表的第i (1 <= i <= n+1)个位置上,插入一个新结点e,使长度为n的线性表(a1,…,ai - 1, ai,…,an)变成长度为n+1的线性表(a1,…,ai-1,e,ai,…,an)
- 算法思想:
①判断插入位置i是否合法。
②判断顺序表的存储空间是否已满,若已满返回ERROR。
③将第n至第i位的元素依次向后移动一个位置,空出第i个位置。
④将要插入的新元素e放入第i个位置。
⑤表长加1,插入成功返回OK。
Status ListInsert_Sq(SqList *L, int i, Elemtype e) {
if (i < 1 || i > L->length + 1)
{
return ERROR; //i值不合法
}
if (L->length == MAXSIZE)
{
return ERROR; //当前存储空间已满
}
for (int j = L->length - 1; j >= i - 1; j--)
{
L->elem[j + 1] = L->elem[j]; //插入位置及之后的元素后移
}
L->elem[i - 1] = e;
L->length++;
return OK;
}
(10)顺序表的按位置删除操作
- 顺序表的删除运算的含义:顺序表的删除运算是指将表的第i(1 <= i <= n+1)个结点删除,使长度为n的线性表(a1,…,ai-1,ai,ai+1,…,an)变成长度为n-1的线性表(a1,…,ai-1,ai+1,…,an)。
- 算法思想:
①判断删除位置i是否合法(合法值为1<=i<=n+1)。
②将第i+1至第n位的元素依次向前移动一个位置。
③表长减1, 删除成功返回OK。
Status ListDelete_Sq(SqList *L, int i) {
if (i < 1 || i > L->length)
{
return ERROR; //i值不合法
}
int j;
for (j = i; j < L->length; j++)
{
L->elem[j - 1] = L->elem[j]; //插入位置及之后的元素后移
}
L->length--;
return OK;
}
(11)顺序表的求前驱节点操作
Status List_Prior(SqList* L, int i) {
if (i < 2 || i > L->length)
{
return ERROR;
}
return L->elem[i - 2];
}
(12)顺序表的求后继节点操作
Status List_Next(SqList* L, int i) {
if (i < 1 || i > L->length - 1)
{
return ERROR;
}
return L->elem[i];
}
(13)显示顺序表操作
void Show_Sq(SqList* L) {
for (int i = 0; i < L->length; i++)
{
printf("%d\t", L->elem[i]);
}
}
三、全部代码及其运行结果
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
//操作算法中用到的预定义常量和类型
//函数结果状态代码:
#define TURE 1
#define FALSE 0
#define OK 1
#define ERROR 0
#define INFEASIBLE -1
#define OVERFLOW -2
//Status是函数的类型,其值是函数结果状态代码
typedef int Status;
typedef int Elemtype;
//定义线性表中可能拥有的元素的最大个数
#define MAXSIZE 5
//定义顺序表类型
typedef struct {
Elemtype *elem;
int length; //当前顺序表中实际拥有的元素个数,即当前顺序表的长度
}SqList;
//创建顺序表
Status List_Creat(SqList* L,int n)
{
int i;
if (n < 1 || n > MAXSIZE)
{
return ERROR;
}
L->elem = (Elemtype*)malloc(sizeof(Elemtype) * MAXSIZE);
L->length = n;
for (i = 0; i < L->length; i++)
{
int temp;
int number = i + 1;
printf("请输入顺序表中的第%d个元素个数:\n", number);
scanf("%d", &temp);
L->elem[i] = temp;
}
return OK;
}
//初始化顺序表
Status InitList_Sq(SqList *L) {
//malloc(m)函数,开辟m字节长度的地址空间,并返回这段空间的首地址
//sizeof(x)函数,计算变量x的长度
//①为顺序表动态分配空间
L->elem = (Elemtype*)malloc(sizeof(Elemtype)*MAXSIZE);
//②如果内存分配失败
if (!(L->elem)) {
//exit(0) 表示程序正常退出
//exit⑴/exit(-1)表示程序异常退出
//exit() 结束当前进程/当前程序
//在整个程序中只要调用exit就结束
return ERROR;
exit(OVERFLOW);
}
//③空表长度为0
L->length = 0;
return OK;
}
//销毁顺序表
Status DestroyList(SqList *L){
if (!L->elem) {
return ERROR;
}
else
{
free(L->elem);
return OK;
}
}
//清除顺序表
Status ClearList(SqList *L) {
if (!L->elem) {
return ERROR;
}
else
{
L->length = 0;
return OK;
}
}
//求顺序表的长度
Status GetLength(SqList *L)
{
return L->length;
}
//判断顺序表是否为空
Status IsEmpty(SqList *L) {
if (L->length == 0) {
return 1;
}
else {
return 0;
}
}
//顺序表的取值(根据位置position获取相应位置数据元素的值)
//注意:此处的position指的是逻辑位序,从1开始,而物理位序即下标从0开始
Status GetElme(SqList *L, int position, Elemtype *e) {
//判断position的值是否合理,若不合理,返回error
if (position < 1 || position > L->length) {
return ERROR;
}
*e = L->elem[position - 1];//position - 1的单元存放着第position个数据
return OK;
}
//顺序表的按值查找
//在线性表L中查找与指定值e相同的数据元素的位置
//从表的一端开始,逐个进行记录的关键字和给定值的比较。找到返回该元素的位置序号,未找到,返回0。
Status LocateElme(SqList *L,Elemtype e){
//法一:使用for循环
//在线性表L中查找值为e的数据元素,返回其序号(是第几个元素)
//for (int i = 0; i < L->length; i++)
//{
// if (L->elem[i] == e) {
// return i + 1;//查找成功,返回序号
// }
//}
//return 0;//查找失败,返回0
//法二:使用while语句
//在线性表l中查找值为e的数据元素,返回其序号(是第几个元素)
int i = 0;
while (i < L->length && L->elem[i] != e)
{
i++;
}
if (i < L->length) {
return i + 1;//查找成功,返回序号
}
return 0;//查找失败,返回0
}
//顺序表的插入
//插入位置在最后
//插入位置在中间
//插入位置在最前面
//顺序表的插入的含义:线性表的插入运算是指在表的第i(1<=i<=n+1)个位置上,插入-个新结点e,
//使长度为n的线性表(a1,...,ai - 1, ai,...,an)变成长度为n+1的线性表(a1,...,ai-1,e,ai,...,an)
//算法思想:
//①判断插入位置i是否合法。
//②判断顺序表的存储空间是否已满,若已满返回ERROR。
//③将第n至第i位的元素依次向后移动一个位置,空出第i个位置。
//④将要插入的新元素e放入第i个位置。
//⑤表长加1,插入成功返回OK。
Status ListInsert_Sq(SqList *L, int i, Elemtype e) {
if (i < 1 || i > L->length + 1)
{
return ERROR; //i值不合法
}
if (L->length == MAXSIZE)
{
return ERROR; //当前存储空间已满
}
for (int j = L->length - 1; j >= i - 1; j--)
{
L->elem[j + 1] = L->elem[j]; //插入位置及之后的元素后移
}
L->elem[i - 1] = e;
L->length++;
return OK;
}
//顺序表的按位置删除
//线性表的删除运算是指将表的第i(1<=i<=n+1)个结点删除
//使长度为n的线性表(a1,...,ai-1,ai,ai+1,...,an)
//变成长度为n-1的线性表(a1,...,ai-1,ai+1,...,an)
//算法思想:
//①判断删除位置i是否合法(合法值为1<=i<=n+1)。
//②将第i+1至第n位的元素依次向前移动一个位置。
//③表长减1, 删除成功返回OK。
Status ListDelete_Sq(SqList *L, int i) {
if (i < 1 || i > L->length)
{
return ERROR; //i值不合法
}
int j;
for (j = i; j < L->length; j++)
{
L->elem[j - 1] = L->elem[j]; //插入位置及之后的元素后移
}
L->length--;
return OK;
}
//求前驱
Status List_Prior(SqList* L, int i) {
if (i < 2 || i > L->length)
{
return ERROR;
}
return L->elem[i - 2];
}
//求后继
Status List_Next(SqList* L, int i) {
if (i < 1 || i > L->length - 1)
{
return ERROR;
}
return L->elem[i];
}
//显示顺序表
void Show_Sq(SqList* L) {
for (int i = 0; i < L->length; i++)
{
printf("%d\t", L->elem[i]);
}
}
int main() {
printf("==================该顺序表可以拥有的元素的最大个数为5==================\n");
SqList L;
L.length = 0;
int select,status;
printf("1、 初始化顺序表\n");
printf("2、 创建顺序表\n");
printf("3、 求顺序表的长度\n");
printf("4、 判断顺序表是否为空\n");
printf("5、 按位置取顺序表中元素\n");
printf("6、 顺序表的按值查找\n");
printf("7、 在顺序表中插入元素\n");
printf("8、 按位置删除顺序表的元素\n");
printf("9、 求所输入的位置的元素的前驱\n");
printf("10、求所输入的位置的元素的后继\n");
printf("11、销毁顺序表\n");
printf("12、清除顺序表\n");
printf("13、展示顺序表中元素\n");
printf("14、结束程序\n");
while (1)
{
printf("请输入需要进行的操作的序号:\n");
scanf("%d", &select);
switch (select)
{
case 1: {
printf("开始初始化顺序表....\n");
status = InitList_Sq(&L);
if (status == OK)
{
printf("顺序表初始化成功!\n");
}
if (status == ERROR)
{
printf("顺序表内存分配失败!顺序表初始化失败!\n");
}
break;
}
case 2: {
int n;
printf("开始创建顺序表....\n");
printf("请输入顺序表中的元素个数(元素个数最大为5):\n");
scanf("%d", &n);
status = List_Creat(&L,n);
if (status == OK)
{
printf("顺序表创建成功!\n");
printf("创建完的顺序表中的元素为:");
Show_Sq(&L);
printf("\n");
}
if (status == ERROR)
{
printf("元素个数不符合要求!\n");
}
break;
}
case 3: {
int now = IsEmpty(&L);
if (now == 1)
{
printf("请先创建一个顺序表!");
break;
}
printf("开始查询顺序表长度....\n");
int result = GetLength(&L);
printf("顺序表的长度为:%d\n", result);
break;
}
case 4: {
printf("开始判断顺序表是否为空....\n");
int result = IsEmpty(&L);
if (result == 1)
{
printf("该顺序表为空!\n");
}
if (result == 0)
{
printf("该顺序表不为空!\n");
}
break;
}
case 5: {
int now = IsEmpty(&L);
if (now == 1)
{
printf("请先创建一个顺序表!");
break;
}
int position;
Elemtype e = 0;
printf("请输入要查找的元素的位置:\n");
scanf("%d",&position);
int result = GetElme(&L, position, &e);
if (result == ERROR)
{
printf("输入的位置的值不合理!\n");
}
if (result == OK)
{
printf("所查找元素的值为: %d\n",e);
}
break;
}
case 6: {
int now = IsEmpty(&L);
if (now == 1)
{
printf("请先创建一个顺序表!");
break;
}
Elemtype e;
printf("请输入要查找的元素的值:\n");
scanf("%d", &e);
int result = LocateElme(&L, e);
if (result == 0)
{
printf("查找失败!\n");
}
if (result != 0)
{
printf("要查找的元素的位置为: %d\n", result);
}
break;
}
case 7: {
int now = IsEmpty(&L);
if (now == 1)
{
printf("请先创建一个顺序表!");
break;
}
Elemtype e;
int position;
printf("请输入要插入的元素的位置:\n");
scanf("%d", &position);
printf("请输入要插入的元素的值:\n");
scanf("%d", &e);
int result = ListInsert_Sq(&L,position,e);
if (result == ERROR)
{
printf("插入失败!\n");
}
if (result == OK)
{
printf("插入成功!\n");
printf("插入完的顺序表中的元素为:");
Show_Sq(&L);
printf("\n");
}
break;
}
case 8: {
int now = IsEmpty(&L);
if (now == 1)
{
printf("请先创建一个顺序表!");
break;
}
int position;
printf("请输入要删除的元素的位置:\n");
scanf("%d", &position);
int result = ListDelete_Sq(&L, position);
if (result == ERROR)
{
printf("删除失败!\n");
}
if (result == OK)
{
printf("删除成功!");
printf("删除完的顺序表中的元素为:");
Show_Sq(&L);
printf("\n");
}
break;
}
case 9: {
int now = IsEmpty(&L);
if (now == 1)
{
printf("请先创建一个顺序表!");
break;
}
int position;
printf("请输入要求前驱的元素的位置:\n");
scanf("%d", &position);
int result = List_Prior(&L, position);
if (result == ERROR)
{
printf("输入的位置错误!\n");
}
if (result != ERROR)
{
printf("前驱为:%d\n",result);
}
break;
}
case 10: {
int now = IsEmpty(&L);
if (now == 1)
{
printf("请先创建一个顺序表!");
break;
}
int position;
printf("请输入要求后继的元素的位置:\n");
scanf("%d", &position);
int result = List_Next(&L, position);
if (result == ERROR)
{
printf("输入的位置错误!\n");
}
if (result != ERROR)
{
printf("后继为:%d\n", result);
}
break;
}
case 11: {
int result = DestroyList(&L);
if (result == ERROR)
{
printf("销毁失败!顺序表还未创建!\n");
}
if (result == OK)
{
printf("销毁成功!\n");
}
break;
}
case 12: {
int result = ClearList(&L);
if (result == ERROR)
{
printf("清除失败!顺序表还未创建!\n");
}
if (result == OK)
{
printf("清除成功!\n");
}
break;
}
case 13: {
int now = IsEmpty(&L);
if (now == 1)
{
printf("请先创建一个顺序表!");
break;
}
Show_Sq(&L);
printf("\n");
break;
}
case 14: {
printf("退出程序成功!\n");
return 0;
}
default: {
printf("请输入1~14内的整数!\n");
break;
}
}
}
}
嘿嘿,看到这里就说明你全部都看完啦!超详细的顺序表操作你学废了吗~