顺序表的插入与删除(简单版)--C语言

/*
日期:2021.11.17 &2023.8.2
作者:木子阳
编译工具:Visual C++6.0
本代码目的:算法实验,记录复习笔记
*/

0.补充:线性表的定义

请添加图片描述
线性表的定义:零个或多个数据元素的有限序列。在较复杂的线性表中一个数据元素可以由若干个数据项组成。例如下图,在一张学生表中,姓名、学号、性别等分开是数据项,由它们一起组成了表中的数据元素。
在这里插入图片描述

线性表的顺序表示

线性表的顺序表表示又称为顺序存储结构顺序映像
顺序存储定义:把逻辑上相邻的数据元素存储在物理上相邻的存储单元的存储结构。
线性表的第1个数据元素a1的存储位置,称为线性表的起始位置基地址
由线性表的特性可知道线性表顺序表存储结构占用一片连续的存储空间,所以知道某个元素的存储位置就可以计算其他元素的存储位置。
假设线性表的每个元素需占 L个存储单元,则第i+1个数据元素的存储位置和第i个数据元素的存储位置之间满足关系: LOC(a(i+1))=LOC(a(i))+L
例:如果每个元素占用8个存储单元,a(i)存储位置为2000单元,则a(i+1)存储位置是? 2008单元

线性表顺序存储结构图示
如何存储一个线性表:
由顺序表(元素)的特性:地址连续、依次存放、随机存取、类型相同可以让我们联想到C语言中的数组,用一维数组表示顺序表

  • 线性表长可变,通过插入删除等操作
  • 数组长度不可动态定义

用一变量表示顺序表的长度属性
既然有两个成员,所以我们需要把这个线性表定义成一个结构类型

一维数组的定义方式: 类型说明符 数组名[常量表达式]
说明:常量表达式中可以包含常量和符号常量,不能包含变量,即C语言中不允许对数组的大小动态定义
虽然说C已经新增了柔性数组,但要考虑到不同平台不同环境的稳定,还是当数组长度不可动态定义。
线性表定义框架:

#define LIST_INIT_SIZE 100     //宏定义,LIST_INIT_SIZE 是线性表存储空间的初始分配量,可以自己改,100改成200,300都行。
typedef stuct{
	ElemType elem[LIST_INIT_SIZE ];  //ElemType是一个抽象、、数据类型,具体场景具体更换,它里面存的就是线性表的数据元素,而一个数据元素又由数据项构成。
	int length; //当前长度
}SqList;

例如:图书表的顺序结构类型定义

#define MAXSIZE 1000  //图书表可能达到的最大长度
typedef struct{   //图书信息定义
	char no[20];   //图书ISBN
	char name[50];   //图书价格
	float price;
}BOOK;
typedef struct{
	BOOK *elem;   //存储空间的基地址
	int length;    //图书表中当前图书个数
}SqList;   //图书表的顺序存储结构类型为SqList

线性表的特点

同一性:线性表有同类数据元素组成,每一个元素必须属于同一数据对象
有穷性:线性表由有限个数据元素组成,表长度就是表中元素的个数
有序性:线性表中相邻数据元素之间存在序偶关系
线性表是一种最简单的数据结构,又是一种最常见的数据结构,因为矩阵、数组、字符串、堆栈、队列等符合线性条件。

1.线性表的顺序存储结构–顺序表

采用顺序存储结构的线性表通常称为顺序表
顺序存储结构:它是使用一片地址连续的有限内存单元空间存储数据元素的一种计算机存储数据方法。
线性表的顺序存储结构可用C语言定义如下:

#define OK 1
#define ERROR 0
#define maxsize 10 //10为线性表可能达到的最大长度,可以自己定义
typedef struct
{
	int elem[maxsize];//线性表占用的数组空间,int 也可以定义成char等(根据用户所储存元素来定义,在这里用来储存整型数字)
	int last;//记录线性表中最后一个元素在表中的位置(下标值),空表置为-1
}SeqList;

线序表的基本操作

以下所提及的运算时逻辑结构上定义的运算,只要给出这些运算的功能时“做什么”,至于“如何做”等实现细节,只有待确定了存储结构(例如链式和顺序存储结构)才考虑
后续内容将学习线性表的存储及在存储结构上各操作的实现,所有了解即可,这写相当于起了模板的作用。

InitList(&L) (Initialization List)初始化线性表

  • 操作结果:构造一个空的线性表L

DestroyList(&L)

  • 初始条件:线性表L已经存在
  • 操作结果:销毁线性表(线性表已经不存在内存中了)

ClearList(&L)

  • 初始条件:线性表L已经存在
  • 操作结果:将线性表重置为空表(线性表还在内存中,但表中没有元素)

ListEmpty(L)

  • 初始条件:线性表L已经存在
  • 操作结果:若线性表L为空表,则返回TURE;否则返回FALSE

ListLength(L)

  • 初始条件:线性表L已经存在
  • 操作结果:返回线性表L中的数据元素个数

GetElem(L,i,&e)

  • 初始条件:线性表L已经存在,1<=i<=ListLength(L)
  • 操作结果:用e返回线性表L中第i个数据元素的值

LocateElem(L,e,compare())

  • 初始条件:线性表L已经存在,compare()是数据元素判定函数
  • 操作结果:返回L中第1个与e满足compare()的数据元素的位序。这样的数据元素不存在则返回值为0

PriorElem(L,cur_e,&pre_e)

  • 初始条件:线性表L已经存在
  • 操作结果:若cur_e是L的数据元素,且不是第一个,则用pre_e返回它的前驱否则操作失败;pre_e无意义

NextElem(L,cur_e,&next_e)

  • 初始条件:线性表L已经存在
  • 操作结果:若cur_e是L的数据元素,且不是最后一个,则用pre_e返回它的后继否则操作失败;next_e无意义

ListInsert(&L,i,e)

  • 初始条件:线性表L已经存在,1<=i<=ListLength(L)+1
  • 操作结果:在L的第i个位置之前插入新的数据元素e,L的长度加1

ListDelete(&L,i,&e)

  • 初始条件:线性表L已经存在,1<=i<=ListLength(L)
  • 操作结果:删除L的第i个数据元素,并用e返回其值,L的长度减1

ListTraverse(&L,visited)

  • 初始条件:线性表L已经存在
  • 操作结果:依次对线性表中每个元素调用visited()

在计算机内,线性表有两种基本的存储结构:顺序存储结果链式存储结构

在这里简单讲下删除和插入操作

1、删除操作

线性表的删除操作运算是指删去表的第i个元素,如下图,第7个位置的元素后,后面的元素都依次前进一格。

在这里插入图片描述代码如下:

/*删除操作*/
int DelList(SeqList *L,int i,int *e)//i为被删除元素位置,通过指针参数e返回其值
{
	int k;
	if(i<0||i>L->last+1)//i所能删除的位置为:1<=i<=L->last+1
	{
		printf("删除位置不合法!\n");
		return(ERROR);//判断删除错误后直接退出调用函数
	}
	*e=L->elem[i-1];
	for(k=i;k<=L->last;k++)
		L->elem[k-1]=L->elem[k];//将表格中删除元素的后面的元素依次前移
	L->last--;//成功删除元素后,下标-1
	return(OK);
}

2、插入操作

线性表的插入运算是指在表的第i个位置,插入一个新元素e,使长度为n的线性表变成长度为n+1的线性表。

/*插入操作*/ 
int InsList(SeqList *L,int i,int e)//i为插入位置,e为插入元素
{
	int k;
	if(i<1||i>L->last+2)
	{
		printf("插入位置不合理!\n");
		return(ERROR);
	}
	else if(L->last==maxsize)//注意是'=='
	{
		printf("表已满无法插入!\n");
		return(ERROR);
	}
	for(k=L->last;k>=i-1;k--)
		L->elem[k+1]=L->elem[k];//先将插入位置元素及其后面元素依次后移
	L->elem[i-1]=e;//插入 即将'插入元素'覆盖'原来的位置元素的值'
	L->last++;//插入成功后,下标+1
	return(OK);
}

2、综合操作运用

#include<stdio.h>//输入输出函数
#include<stdlib.h>//动态存储分配函数,链表中会用到

#define OK 1
#define ERROR 0
#define maxsize 10 //10为线性表可能达到的最大长度,可以自己定义
typedef struct
{
	int elem[maxsize];//线性表占用的数组空间,int 也可以定义成char等(根据用户所储存元素来定义,在这里用来储存整型数字)
	int last;//记录线性表中最后一个元素在表中的位置(下标值),空表置为-1
}SeqList;
/*函数说明*/
int DelList(SeqList *L,int i,int *e);
int InsList(SeqList *L,int i,int e);
/*删除操作*/
int DelList(SeqList *L,int i,int *e)//i为被删除元素位置,通过指针参数e返回其值
{
	int k;
	if(i<0||i>L->last+1)//i所能删除的位置为:1<=i<=L->last+1
	{
		printf("删除位置不合法!\n");
		return(ERROR);//判断删除错误后直接退出调用函数
	}
	*e=L->elem[i-1];
	for(k=i;k<=L->last;k++)
		L->elem[k-1]=L->elem[k];//将表格中删除元素的后面的元素依次前移
	L->last--;//成功删除元素后,下标-1
	return(OK);
}
/*插入操作*/ 
int InsList(SeqList *L,int i,int e)//i为插入位置,e为插入元素
{
	int k;
	if(i<1||i>L->last+2)
	{
		printf("插入位置不合理!\n");
		return(ERROR);
	}
	else if(L->last==maxsize)//注意是'=='
	{
		printf("表已满无法插入!\n");
		return(ERROR);
	}
	for(k=L->last;k>=i-1;k--)
		L->elem[k+1]=L->elem[k];//先将插入位置元素及其后面元素依次后移
	L->elem[i-1]=e;//插入 即将'插入元素'覆盖'原来的位置元素的值'
	L->last++;//插入成功后,下标+1
	return(OK);
}
/*元素输出*/
void Display(SeqList *L)
{
	int i;
	printf("线性表元素如下:\n");
	for(i=0;i<L->last+1;i++)
		printf("%d ",L->elem[i]);
	printf("\n\n");
}
main()
{
	int i=0;
	int x,y,a,e;//x为插入元素变量,y为插入元素位置变量,a为被删除元素位置变量,e为被删除元素的值
	SeqList L;
	L.elem[0]=0;//先进行赋值
	L.last=-1;
	printf("请开始向线性表中填充5个元素:");
	for(i=0;i<=4;i++)
	{
		scanf("%d",&L.elem[i]);
		L.last++;
	}
	Display(&L);
    /*插入操作*/
	printf("请输入插入元素位置和插入元素(格式如:2 2):");
	scanf("%d %d",&x,&y);
	InsList(&L,x,y);
	Display(&L);
	/*删除操作*/
	printf("请输入删除元素位置:");
	scanf("%d",&a);
	DelList(&L,a,&e);
	printf("被删除元素是:%d\n",e);
	Display(&L);
}
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值