顺序表的C语言实现与解析

embedded/2025/3/19 15:36:14/

目录

引言 

作者主页:共享家9527-CSDN博客

​编辑代码结构概览 

头文件( ST.h )要点 

源文件要点 

1. 顺序表初始化( SeqListInit ): 

2. 顺序表销毁( SeqListDestroy ): 

3. 顺序表打印( SeqListPrint ): 

4. 检查并增容( cheakfull ): 

 5. 尾插法( SeqListPushBack ): 

6. 头插法( SeqListPushFront ): 

7. 头删法( SeqListPopFront ): 

8. 尾删法( SeqListPopBack ): 

9. 顺序表查找( SeqListFind ): 

10. 在指定位置插入元素( SeqListInsert ): 

​编辑注意事项 


引言
 


顺序表是一种线性数据结构,它使用一组连续的内存单元来存储数据元素。在C语言中,我们可以通过数组和一些辅助变量来实现顺序表。本文将详细解析上述提供的C语言代码,涵盖顺序表的初始化、销毁、插入、删除、查找等基本操作。
 

作者主页:共享家9527-CSDN博客


代码结构概览
 


整个代码分为两部分:头文件( .h )和源文件( .c )。头文件定义了顺序表的数据结构以及函数声明,源文件则包含了函数的具体实现。
 


头文件( ST.h )要点
 

c#pragma once
#include <stdio.h>
#include <assert.h>
#include <stdlib.h>typedef int SLDateType;
typedef struct SeqList
{SLDateType* a;int size;int capacity;
}SeqList;// 对数据的管理:增删查改 
void SeqListInit(SeqList* ps);
void SeqListDestroy(SeqList* ps);void SeqListPrint(SeqList* ps);
void SeqListPushBack(SeqList* ps, SLDateType x);
void SeqListPushFront(SeqList* ps, SLDateType x);
void SeqListPopFront(SeqList* ps);
void SeqListPopBack(SeqList* ps);// 顺序表查找
int SeqListFind(SeqList* ps, SLDateType x);
// 顺序表在pos位置插入x
void SeqListInsert(SeqList* ps, int pos, SLDateType x);
// 顺序表删除pos位置的值
void SeqListErase(SeqList* ps, int pos);


 
 
1. 数据类型定义: SLDateType  被定义为  int ,这是顺序表中元素的数据类型。如果需要存储其他类型的数据,只需修改这一处定义。
 
2. 顺序表结构体: SeqList  结构体包含三个成员:
 
-  a  是一个指向  SLDateType  类型的指针,用于动态分配内存来存储顺序表的元素。
 
-  size  表示当前顺序表中已存储的元素个数。
 
-  capacity  表示顺序表当前分配的内存容量,即最多能存储的元素个数。

 
3. 函数声明:声明了一系列对顺序表进行操作的函数,包括初始化、销毁、打印、插入、删除、查找等。这些函数的实现将在源文件中给出。
 


源文件要点
 


c#define _CRT_SECURE_NO_WARNINGS
#include"ST.h"void SeqListInit(SeqList* ps)
{assert(ps);ps->a = (SLDateType*)malloc(sizeof(SLDateType));if (ps->a == NULL){perror("malloc false");return;}ps->size = 0;ps->capacity = 4;
}


 


1. 顺序表初始化( SeqListInit ):
 


- 使用  assert(ps)  来确保传入的顺序表指针不为空。这是一种防御性编程,有助于在开发阶段发现潜在的空指针引用错误。
 
- 使用  malloc  函数为顺序表分配初始内存,大小为一个  SLDateType  类型的空间。如果  malloc  失败(返回  NULL ),使用  perror  打印错误信息并返回。
 
- 将  size  初始化为0,表示顺序表中还没有元素, capacity  初始化为4,表示初始分配的内存可以容纳4个元素。

 
cvoid SeqListDestroy(SeqList* ps)
{assert(ps);free(ps->a);ps->a = NULL;ps->size = 0;ps->capacity = 0;ps = NULL;
}


 


2. 顺序表销毁( SeqListDestroy ):
 


- 同样使用  assert(ps)  确保指针有效。
 
- 使用  free  释放顺序表分配的内存,防止内存泄漏。
 
- 将  ps->a  置为  NULL ,避免悬空指针。同时将  size  和  capacity  置为0,并尝试将  ps  指针也置为  NULL (不过这在函数外部不会生效,因为函数参数是值传递)。

 
cvoid SeqListPrint(SeqList* ps)
{assert(ps);for (int i = 0;i < ps->size;i++){printf("%d ", ps->a[i]);}printf("\n");
}


 


3. 顺序表打印( SeqListPrint ):
 


- 通过遍历顺序表,从索引0到  size - 1 ,打印每个元素的值,最后换行。

 
cvoid cheakfull(SeqList* ps)
{assert(ps);if (ps->capacity == ps->size){SLDateType* tmp = (SeqList*)realloc(ps->a, ps->capacity * 2);if (tmp == NULL){perror("realloc false");return;}ps->a = tmp;ps->capacity *= 2;printf("增容成功\n");}
}


 


4. 检查并增容( cheakfull ):
 


- 检查顺序表当前元素个数  size  是否等于容量  capacity ,如果相等则表示顺序表已满,需要增容。
 
- 使用  realloc  函数将顺序表的内存容量扩大为原来的2倍。如果  realloc  失败,打印错误信息并返回。
 
- 更新  ps->a  指向新分配的内存,并将  capacity  更新为原来的2倍。
 

 
cvoid SeqListPushBack(SeqList* ps, SLDateType x)
{cheakfull(ps);assert(ps);ps->a[ps->size] = x;ps->size++;
}


 
5. 尾插法( SeqListPushBack ):
 


- 首先调用  cheakfull  函数检查顺序表是否已满并进行增容。
 
- 将元素  x  插入到顺序表的末尾(索引为  size  的位置),然后  size  加1。
 

 
cvoid SeqListPushFront(SeqList* ps, SLDateType x) 
{assert(ps);cheakfull(ps);for (int i = ps->size;i > 0;i--){ps->a[i] = ps->a[i - 1];}ps->a[0] = x;ps->size++;
}


6. 头插法( SeqListPushFront ):
 


- 检查顺序表是否需要增容。
 
- 通过循环将顺序表中已有的元素从后往前依次向后移动一位,然后将新元素  x  插入到索引0的位置,最后  size  加1。注意这里循环条件是  i > 0 ,而不是  i >= 0 ,否则会导致数组越界。
 

 
cvoid SeqListPopFront(SeqList* ps) {assert(ps);for (int i = 0;i < ps->size - 1;i++){ps->a[i] = ps->a[i + 1];}ps->size--;
}


7. 头删法( SeqListPopFront ):
 


- 通过循环将顺序表中从索引1开始的元素依次向前移动一位,覆盖掉原来索引0的元素,然后  size  减1。注意这里循环条件是  i < ps->size - 1 ,防止数组越界。

 
cvoid SeqListPopBack(SeqList* ps) {assert(ps);assert(ps->size>0);ps->size--;
}


 


8. 尾删法( SeqListPopBack ):
 


- 首先检查顺序表中是否有元素( size > 0 ),然后直接将  size  减1,相当于逻辑上删除了最后一个元素,而不需要实际修改数组中的元素值。

 
c// 顺序表查找
int SeqListFind(SeqList* ps, SLDateType x) {assert(ps);assert(ps->size > 0);for (int i = 0;i < ps->size;i++){if (ps->a[i] == x){return i;}}return -1;
}


 


9. 顺序表查找( SeqListFind ):
 


- 遍历顺序表,从索引0到  size - 1 ,检查每个元素是否等于要查找的元素  x 。如果找到,返回该元素的索引;如果遍历完整个顺序表都没有找到,则返回 -1。
 

 
c// 顺序表在pos位置插入x
void SeqListInsert(SeqList* ps, int pos, SLDateType x) {assert(ps);assert(ps->size >= pos);cheakfull(ps);for (int i = ps->size;i > pos;i--){ps->a[i] = ps->a[i - 1];}ps->a[pos] = x;ps->size++;
}


10. 在指定位置插入元素( SeqListInsert ):
 


- 检查传入的位置  pos  是否合法( pos  小于等于当前  size )。
 
- 检查顺序表是否需要增容。
 
- 通过循环将从索引  size  到  pos + 1  的元素依次向后移动一位,然后将新元素  x  插入到索引  pos  的位置,最后  size  加1。
 


注意事项
 


1. 内存管理:在使用  malloc  和  realloc  分配内存时,一定要检查返回值是否为  NULL ,以防止内存操作错误。使用完内存后,要及时调用  free  释放内存,避免内存泄漏。
 
2. 边界检查:在进行插入、删除、查找等操作时,要仔细检查数组索引是否越界。使用  assert  进行参数合法性检查是一个很好的习惯,可以帮助在开发阶段发现潜在的错误。
 
3. 函数参数传递:注意C语言函数参数是值传递,如果需要修改传入的指针本身(如在  SeqListDestroy  中尝试将  ps  置为  NULL ),需要使用指针的指针或者返回修改后的指针。
 
通过上述对顺序表实现代码的详细解析,希望读者能够更好地理解顺序表这种数据结构在C语言中的实现方式以及相关操作的要点和注意事项。


http://www.ppmy.cn/embedded/173894.html

相关文章

蓝桥杯练习day1:拆分数位-四位数字的最小和

前言 给你一个四位 正 整数 num 。请你使用 num 中的 数位 &#xff0c;将 num 拆成两个新的整数 new1 和 new2 。new1 和 new2 中可以有 前导 0 &#xff0c;且 num 中 所有 数位都必须使用。 比方说&#xff0c;给你 num 2932 &#xff0c;你拥有的数位包括&#xff1a;两…

【数据结构】顺序表和链表

一、线性表 线性表是n个具有相同特性的数据元素的有限序列。线性表是一种在实际中广泛使用的数据结构&#xff0c;常见的线性表有&#xff1a;顺序表&#xff0c;链表&#xff0c;栈&#xff0c;队列&#xff0c;字符串 线性表在逻辑上是线性结构&#xff0c;也就是说是连续的…

【CSS】一、基础选择器

文章目录 1、CSS2、CSS的引入方式3、选择器3.1 标签选择器3.2 类选择器3.3 id选择器3.4 通配符选择器 4、练习&#xff1a;画盒子 1、CSS CSS&#xff0c;Cascading Style Sheets&#xff0c;层叠样式表&#xff0c;是一种样式表语言&#xff0c;用于表述HTML的呈现&#xff0…

组合Composition(has-a)

在 Python 中&#xff0c;**组合&#xff08;Composition&#xff09;** 是一种设计模式&#xff0c;用于将一个类的实例作为另一个类的属性。这种模式允许你将多个类的功能组合在一起&#xff0c;而不是通过继承来实现。组合强调的是“有一个”&#xff08;has-a&#xff09;关…

桌子(table、desk)以及其他常见物体的urdf模型,用于搭建机器人环境如pybullet、Gazebo

一、背景 我们在搭建仿自己的仿真环境时&#xff0c;需要添加一些物品&#xff0c;如桌子&#xff0c;托盘等&#xff0c;使得我们的场景更丰富并贴合我们的任务。但手写这些常见物品的urdf是不现实的&#xff0c;所以下面给出了github上开源的模型&#xff0c;感谢开源。 我…

如何让焦虑为城市供能 | 杂谈

凌晨两点&#xff0c;我盯着满桌冷掉的碳烤磷虾烩面——这顿价值500星币的宵夜。当冒充食客的就餐员像幽灵般消失后&#xff0c;躁动的神经末梢突然刺破迷雾&#xff1a;那些令人窒息的负能量&#xff0c;是否能在量子层面转化为清洁动能&#xff1f; 这个疯狂假设打开了四维能…

Machine Learning: 十大基本机器学习算法

机器学习算法分类&#xff1a;监督学习、无监督学习、强化学习 基本的机器学习算法&#xff1a; 线性回归、支持向量机(SVM)、最近邻居(KNN)、逻辑回归、决策树、k平均、随机森林、朴素贝叶斯、降维、梯度增强。 机器学习算法大致可以分为三类&#xff1a; 监督学习算法 (Sup…

Qt Widgets、Qt Quick

一、核心概念 ‌Qt Widgets‌ Qt框架中的传统桌面UI开发组件库&#xff0c;基于C实现&#xff0c;提供按钮、文本框等控件‌。适用于需要深度集成操作系统底层功能或复杂业务逻辑的桌面应用‌。 ‌Qt Quick‌ QML的标准库和工具包&#xff0c;提供预置的视觉组件&#xff08;如…