学习记录:第二章 线性表的顺序存储_顺序表_插入删除查找三种基本操作(代码、图示、C++)


前言

本文给出了顺序表的插入、删除、查找(按位、按值查找)三种基本操作的代码及相应图示助于理解,代码实现使用的是C语言在线工具。无概念解释,初学者建议配合书本食用。
【如果图片看不清楚,网页版是很清晰的。😦】


一、顺序表的插入操作

#include <stdio.h>
#define MaxSize 10
typedef 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 !!!!这步很重要!!!!
}

//基本操作——往顺序表中位序为i的位置插值
void ListInsert(SqList &L, int i, int e){
	for(int j=L.length;j>=i;j--)  	//将第i个元素及之后的元素后移
		L.data[j] = L.data[j-1]; 	//注意位序和数组下标的关系:i和j的关系
	L.data[i-1]=e;  				//在位置i处放入e:data数组的下标是位序i减1
	L.length++;  					//长度加1
}

int main(){
	SqList L;  					//声明一个顺序表
	InitList(L);  				//初始化顺序表
	for(int i = 0; i<5; i++){	//设置顺序表前5个元素的值
		L.data[i] = i;  
		L.length++;
	}
	ListInsert(L, 3, 999);		//往位序为3的位置插值
	for(int i = 0; i<L.length; i++)	//打印整个data数组
		printf("data[%d] = %d\n", i, L.data[i]);
	return 0;
}

在这里,定义的顺序表长度为10,设置前5个元素的值分别是0、1、2、3、4,往位序为3的位置插入值999,运行结果如下:
在这里插入图片描述

但是代码还有不完善的地方,好的代码应该具有健壮性。我们这里的顺序表最大长度为10,实际长度为5,往3的位置插值可以成功,那么往8的位置插值呢?最大长度为10,实际长度也为10的情况下再插值呢?当 i 超出顺序表长度的有效范围,或者存储空间已满,理论上这就不能继续插值了,但实际上结果如下:
在这里插入图片描述

因此需要修改代码,使得在 “ i 不在有效范围内” 或者 “当前存储空间已满” 的情况下不能继续插值。我们只需要修改ListInsert这段代码:

//基本操作——往顺序表位序为i的位置插值
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;
}

修改后再往8的位置插值结果如下:
在这里插入图片描述

二、顺序表的删除操作

#include <stdio.h>
#define MaxSize 10
typedef 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 !!!!这步很重要!!!!
}

//基本操作——在顺序表中删除位序为i的值
bool ListDelete(SqList &L, int i, int &e){  //注意这里&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;
}

int main(){
	SqList L;           		//声明一个顺序表
	InitList(L);   				//初始化顺序表
	for(int i = 0; i<5; i++){	//设置顺序表前5个元素的值
		L.data[i] = i;  
		L.length++;
	}
	int i = 8;
	int e = -1;    			   	//用变量e把删除位置的元素“带回来”,e初始值为-1
	if(ListDelete(L, i, e))
		printf("已删除第%d个元素,删除元素的值为e=%d\n", i, e);
	else
		printf("位序%d不合法,删除失败\n", i);
	printf("\n打印整个顺序表\n");
	for(int i = 0; i<L.length; i++)	//打印整个data数组
		printf("data[%d] = %d\n", i, L.data[i]);
	return 0;
}

在这里,定义的顺序表长度为10,设置前5个元素的值分别是0、1、2、3、4,删除3的位置的值,运行结果如下:
在这里插入图片描述

这个代码已经加强过健壮性了,因此在 i 不在有效范围内的情况下,比如删除位序为8的元素的值,运行结果如下:
在这里插入图片描述

三、顺序表的查找操作

1. 按位查找

按位查找:获取表L中第i个位置的元素的值,并返回这个值。
由于顺序表的各个元素在内存中连续存放,因此可以根据 [起始地址] 和 [数据元素大小] 立即找到第 i 个元素,这也是顺序表的 “随机存取” 的特性。

在这里插入图片描述

顺序表按位查找(动态分配)的代码为:

#include <stdio.h>
#include<stdlib.h> 
#define InitSize 10				//顺序表的初始长度

typedef struct{
	int *data;					//指示动态分配数组的指针,data指向分配空间的首地址
	int MaxSize;				//顺序表的最大容量
	int length;					//顺序表的当前长度
}SeqList;						//顺序表的类型定义【动态分配方式】

//基本操作——按位查找,获取表L中第i个位置的元素的值
int GetElem(SeqList L, int i){
	return L.data[i-1];			//返回查找位置的元素的值		
}

//基本操作——初始化一个顺序表
void InitList(SeqList &L){
	L.data = (int *)malloc(InitSize*sizeof(int));	//用malloc函数申请一片连续的内存空间
	L.length = 0;  									//顺序表初始长度为0
	L.MaxSize = InitSize;
}

int main(){
	SeqList L;           		//声明一个顺序表
	InitList(L);   				//初始化顺序表
	for(int i = 0; i<5; i++){	//设置顺序表前5个元素的值
		L.data[i] = i;  
		L.length++;
	}
	int i = 3;
	for(int i = 0; i<L.length; i++)	//打印整个顺序表
		printf("data[%d] = %d\n", i, L.data[i]);
	printf("表L的第%d个位置的元素值为%d\n", i, GetElem(L, i));
	return 0;
}

在这里,定义的顺序表初始长度为10,设置前5个元素的值分别是0、1、2、3、4,查找位序为3的元素的值,运行结果如下:
在这里插入图片描述

2. 按值查找

按值查找:获取表L中第一个元素值等于e的元素,并返回其位序。
顺序表按值查找(动态分配)的代码为:

#include <stdio.h>
#include<stdlib.h> 
#define InitSize 10				//顺序表的初始长度

typedef struct{
	int *data;					//指示动态分配数组的指针,data指向分配空间的首地址
	int MaxSize;				//顺序表的最大容量
	int length;					//顺序表的当前长度
}SeqList;						//顺序表的类型定义【动态分配方式】

//基本操作——按值查找,获取表L中第一个元素值等于e的元素,并返回其位序
int LocateElem(SeqList L, int e){
	for(int i=0; i<L.length; i++)
		if(L.data[i] == e)  
			return i+1;
	return 0;
}

//基本操作——初始化一个顺序表
void InitList(SeqList &L){
	L.data = (int *)malloc(InitSize*sizeof(int));	//用malloc函数申请一片连续的内存空间
	L.length = 0;  									//顺序表初始长度为0
	L.MaxSize = InitSize;
}

int main(){
	SeqList L;           		//声明一个顺序表
	InitList(L);   				//初始化顺序表
	for(int i = 0; i<5; i++){	//设置顺序表前5个元素的值
		L.data[i] = i;  
		L.length++;
	}
	int e = 3;
	for(int i = 0; i<L.length; i++)	//打印整个顺序表
		printf("data[%d] = %d\n", i, L.data[i]);
	printf("表L的第一个元素值为%d的元素位序为%d\n", e, LocateElem(L, e));
	return 0;
}

在这里,定义的顺序表初始长度为10,设置前5个元素的值分别是0、1、2、3、4,查找值为3的元素的位序,运行结果如下:
在这里插入图片描述


总结(需要注意)

  • 数组下标从0开始,顺序表位序从1开始
  • 往顺序表位序为 i 的位置插值时,i 之后的元素要后移
  • 在顺序表位序为 i 的位置删值时,i 之后的元素要前移
  • 插值时 i 的有效范围是[1, length+1]
  • 删值时 i 的有效范围是[1, length]
  • 插值函数bool ListInsert(SqList &L, int i, int e)是把e插到 i 这个位置,e是从main函数传入ListInsert函数的参数
  • 删值函数bool ListDelete(SqList &L, int i, int &e)是把要删除的 i 这个位置的值赋给e,再由e “带回” 给main函数,&e是引用类型
  • C语言中,结构体的比较不能直接用 “==”,需要依次对比各个分量来判断两个结构体是否相等,而基本数据类型:int、char、double、float等的比较可以直接用

线性表系列文章

【请多多支持,多多建议,一键三连(bushi),3Q~ 😃】

  • 5
    点赞
  • 43
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
以下是实现线性表顺序存储定义,并完成了顺序表的创建、插入删除查找、排序操作的代码: ```c #include <stdio.h> #include <stdlib.h> #define MAXSIZE 100 typedef struct { int data[MAXSIZE]; int length; } SqList; // 初始化顺序表 void initList(SqList *list) { list->length = 0; } // 打印顺序表 void printList(SqList list) { int i; for (i = 0; i < list.length; i++) { printf("%d ", list.data[i]); } printf("\n"); } // 在顺序表查找元素 int findElem(SqList list, int elem) { int i; for (i = 0; i < list.length; i++) { if (list.data[i] == elem) { return i; } } return -1; // 没有找到返回-1 } // 插入元素 int insertElem(SqList *list, int pos, int elem) { int i; if (list->length >= MAXSIZE) { // 判断是否超出最大长度 printf("顺序表已满,插入失败!\n"); return 0; } if (pos < 1 || pos > list->length + 1) { // 判断插入位置是否合法 printf("插入位置不合法,插入失败!\n"); return 0; } for (i = list->length - 1; i >= pos - 1; i--) { // 从后往前移动元素 list->data[i + 1] = list->data[i]; } list->data[pos - 1] = elem; // 插入元素 list->length++; // 长度加一 printf("插入成功!\n"); return 1; } // 删除元素 int deleteElem(SqList *list, int pos) { int i; if (pos < 1 || pos > list->length) { // 判断删除位置是否合法 printf("删除位置不合法,删除失败!\n"); return 0; } for (i = pos - 1; i < list->length - 1; i++) { // 从前往后移动元素 list->data[i] = list->data[i + 1]; } list->length--; // 长度减一 printf("删除成功!\n"); return 1; } // 冒泡排序 void bubbleSort(SqList *list) { int i, j; for (i = 0; i < list->length - 1; i++) { for (j = 0; j < list->length - i - 1; j++) { if (list->data[j] > list->data[j + 1]) { int temp = list->data[j]; list->data[j] = list->data[j + 1]; list->data[j + 1] = temp; } } } printf("排序成功!\n"); } int main() { SqList list; initList(&list); insertElem(&list, 1, 1); insertElem(&list, 2, 3); insertElem(&list, 3, 2); insertElem(&list, 4, 5); printf("插入后的顺序表为:"); printList(list); printf("元素2的位置为:%d\n", findElem(list, 2)); deleteElem(&list, 3); printf("删除后的顺序表为:"); printList(list); bubbleSort(&list); printf("排序后的顺序表为:"); printList(list); return 0; } ```

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值