线性表的基本操作(ListInsert&ListDelete)
1、ListInsert(&L,i,e)
功能:1、插入操作实现,在表L中的第i个位置上插入指定元素e。2、静态分配方式插入操作
定义插入操作关键步骤
1. 检查表是否已满(静态分配的核心限制)
2. 检查插入位置有效性(i的合法范围:1 ≤ i ≤ length+1)
3. 从最后一个元素开始后移,为新元素腾出位置(i-1是数组下标)
4. 插入新元素到目标位置
5. 表长度加1
#define _CRT_SECURE_NO_WARNINGS
// 插入操作实现,在表L中的第i个位置上插入指定元素e。
// 静态分配线性表插入操作
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#define MAXSIZE 100 //define 后不能加分号
// 定义线性表结构体,静态分配方式
typedef struct {
int data[MAXSIZE]; // 存储数据元素的数组
int length; // 当前线性表的长度,即元素个数
}SqList;
bool ListInsert(SqList* L, int i, int e)
{
// 1、检查线性表是否已满
if (L->length >= MAXSIZE)
{
printf("插入失败:表已经满,最大容量%d\n", MAXSIZE);
return false;
}
// 2、检查插入位置有效值(1<=i<=length+1)
if (i < 1 || i > L->length + 1)
{
printf("插入失败:位置i=%d不合法(有效范围1~%d)\n", i, L->length + 1);
return false;
}
// 3、从最后一个元素开始后移动,为新元素腾出位置(i - 1是数组下标)
for (int j = L->length; j >= i;j--)
{
L->data[j] = L->data[j - 1];
}
//4、插入新元素到目标位置
L->data[i - 1] = e;
// 5.表长度加1
L->length++;
return true;
}
int main()
{
SqList L = { {1,2,3},3 }; // 初始化线性表,已有元素[1,2,3],长度3
// 打印原始长度
printf("原始表内容:");
for (int i = 0; i < L.length; i++)
{
printf("%d ", L.data[i]);
}
printf("\n当前长度:%d\n\n", L.length);
// 测试插入操作
bool ret = ListInsert(&L, 2, 5);
if (ret)
{
printf("插入成功后表的内容:");
for (int i = 0;i < L.length;i++)
{
printf("%d ", L.data[i]);
}
printf("\n当前长度:%d\n", L.length);
}
// 测试边界情况(插入到表尾之后)
ListInsert(&L, L.length + 1, 99); // 应该成功
// 测试表满情况(假设MAXSIZE=5,这里手动填满测试)
L.length = MAXSIZE; // 模拟表已满状态
ListInsert(&L, 1, 100); // 应该提示表满
return 0;
}
运行结果:
注意点:
- define 后不用加;
define 后不用加;
- 注意线性表位序和数组之间的关系,位序为1时,数组下标为0;
- 时间复杂度情况分析
- 最好情况:新元素插入表尾T=O(1)
- 最坏情况:新元素插入表头T=O(n)
- 平均情况:假设新元素插到任何一个位置的概率相同,即i = 1,2,3,…, length+1的概率都是p = 1/1+n;i = 1,循环n次,i = 2,循环n-1,i = n+1; 循环0次;
- 平均循环次数 = np+(n-1)p+….+1*p = n/2, 即T = O(n)
2、ListDelete(&L,i,*e);
功能:1、插入操作实现,在表L中的删除第i个位置的元素,并且返回e。2、静态分配方式删除操作
核心逻辑:
边界检查:先判断线性表是否为空,再判断删除位置是否在有效范围内(1 到当前长度)
元素保存:通过指针
e
返回被删除的元素值(注意数组下标从 0 开始,所以取i-1
位置)元素前移:将删除位置之后的所有元素向前移动一位(从
i
位置开始到表尾)长度更新:最后将线性表长度减 1
关键代码
for (int j = i; j < L->length; j++) { L->data[j - 1] = L->data[j]; }
#include <stdio.h>
#define MAXSIZE 100 // 定义线性表最大容量
// 静态分配线性表结构体定义
typedef struct {
int data[MAXSIZE]; // 存储数据元素的数组
int length; // 当前线性表长度(有效元素个数)
} SqList;
/**
* 线性表删除操作:删除指定位置的元素
* @param L 指向线性表的指针
* @param i 删除位置(从1开始计数)
* @param e 用于存储被删除元素值的指针
* @return 成功返回1,失败返回0
*/
int ListDelete(SqList* L, int i, int* e) {
// 边界检查1:线性表是否为空
if (L->length == 0) {
printf("错误:线性表为空,无法删除\n");
return 0;
}
// 边界检查2:删除位置是否合法(1 ≤ i ≤ length)
if (i < 1 || i > L->length) {
printf("错误:删除位置i=%d不合法(有效范围1~%d)\n", i, L->length);
return 0;
}
*e = L->data[i - 1]; // 保存被删除元素(数组下标从0开始)
// 元素前移:从第i个位置(数组下标i-1)开始后续元素左移
for (int j = i; j < L->length; j++) {
L->data[j - 1] = L->data[j];
}
L->length--; // 线性表长度减1
return 1;
}
// 测试主函数
int main() {
SqList list = { {10, 20, 30, 40, 50}, 5 }; // 初始化含5个元素的线性表
int deleted_e;
// 测试正常删除(删除第3个元素)
if (ListDelete(&list, 3, &deleted_e)) {
printf("删除成功!被删除元素:%d\n", deleted_e);
printf("当前线性表元素:");
for (int i = 0; i < list.length; i++) {
printf("%d ", list.data[i]);
}
printf("\n当前长度:%d\n\n", list.length);
}
// 测试边界情况(删除第1个元素)
if (ListDelete(&list, 1, &deleted_e)) {
printf("删除成功!被删除元素:%d\n", deleted_e);
printf("当前线性表元素:");
for (int i = 0; i < list.length; i++) {
printf("%d ", list.data[i]);
}
printf("\n当前长度:%d\n\n", list.length);
}
// 测试非法位置(删除第5个元素,当前长度为3)
if (ListDelete(&list, 5, &deleted_e)) {
printf("删除成功!被删除元素:%d\n", deleted_e);
}
return 0;
}
运行结果
注意点:
- 返回的值需要带回来,需要用引用符号
本网站原创文章版权归何大锤的狂飙日记所有。发布者:何大锤,转转请注明出处:何大锤的博客