顺序表的实现

article/2025/8/22 5:18:16

目录

1.顺序表的概念

2.静态顺序表

分析:

3.动态顺序表

分析:

4.顺序表初始化

5.顺序表尾部操作

5.1尾插

 空间检查函数实现

分析:

5.2尾删

分析:

6.顺序表的头部操作

6.1头插

分析:

6.2头删

分析:

7.固定位置操作

7.1固定位置插入

分析:

 7.2固定位置删除

分析:

8.查找及打印

9.销毁顺序表

10.我的菜单及主函数 

直接上代码:


1.顺序表的概念

顺序表是用一段物理地址连续的存储单元依次存储数据元素的线性结构,一般情况下采用数组存储。在数组上完成数据的增删查改。

顺序表一般可以分为:静态顺序表和动态顺序表

2.静态顺序表

              使用定长数组存储元素

分析:

3.动态顺序表

             使用动态开辟的数组存储

分析:


 

       函数接口基于动态顺序表来实现       

4.顺序表初始化

通过分析,我们知道顺序表中有起始地址,数据个数,及空间大小,一个顺序表刚开始当然应该为空,那么数据个数和空间大小应为0,起始地址应置空

操作是对整个顺序表进行操作,函数参数应传顺序表地址,形参接收用指针。

//初始化
void SLInit(SL* p)
{assert(p);    //暴力判断,断言指针是否为空p->a = NULL;p->size = 0;p->capacity = 0;
}

5.顺序表尾部操作

5.1尾插

顾名思义,从顺序表的末尾插入数据,顺序表空间是固定的,插入的时候我们要检查空间是否足够,不够则要进行扩容,足够则插入。

void SLPushBack(SL* p, SLDataType x)
{assert(p);//检查空间,是否扩容SLcheckCapacity(p);//插入p->a[p->size] = x; //尾数的下一个位置插入数据p->size++;          //有效数据个数加一
}

 空间检查函数实现

//检查空间
void SLcheckCapacity(SL* p)
{assert(p);//检查是否需要扩容if (p->size == p->capacity){size_t newCapacity = p->capacity == 0 ? 4 : p->capacity * 2;SLDataType* tmp = realloc(p->a, sizeof(SLDataType)*newCapacity);if (tmp == NULL){printf("realloc fail\n");exit(-1);}else{p->a = tmp;p->capacity = newCapacity;}}
}

分析:

我们要知道当数据个数=空间数时,空间已满,那么就要改变空间大小,这里我们设新的空间大小newCapacity为原capacity的二倍。

接下来就是扩容空间为新空间大小,用realloc开辟空间,记着要判断是否开辟成功,详细用法: 动态内存管理分析理解_i跑跑的博客-CSDN博客

 开辟成功后,记得将令新空间指向原顺序表地址,空间大小=新空间大小。

5.2尾删

分析:

删除的时候并不是将最后一个数给置为0,或者‘\n’,这些,不对数据进行任何需要将操作而是只有效个数减一就可以。注意不可以对要删除数得空间进行释放,这是不可取得,动态开辟出的空间是一起开辟,一起释放的,在这里不可以实现。

//尾删
void SLPopBack(SL* p)
{assert(p);//size不能一直--if (p->size > 0){p->size--;}
}

 有效个数不能为负数,这里要进行判断。

6.顺序表的头部操作

6.1头插

分析:

从头部插入数据,那么就需要将原数据从最后一个数据开始向后移动一位,这里必然要进行空间检查。

//头插
void SLPushFront(SL* p, SLDataType x)
{assert(p);SLcheckCapacity(p);for (int i = p->size;i>0;i--){p->a[i] = p->a[i-1];}p->a[0] = x;p->size++;
}

记得插入后有效数据个数加一。

6.2头删

分析:

与头插相反,头插是将从最后一个数开始向后覆盖,头删是不要第一个数,从第一个数开始,第一个=第二个;第二个=第三个 ... ... 这样覆盖,覆盖原有效数据-1次。

//头删
void SLPopFront(SL* p)
{assert(p);if (p->size>0){for (int j = 0; j<p->size - 1; j++){p->a[j] = p->a[j + 1];}}p->size--;
}

7.固定位置操作

7.1固定位置插入

          固定位置为下标,从0开始

分析:

思想与头插相似,先要判断空间是否足够。再进行插入,例如从下标x的位置开始,那么从最后一个数向后挪动,挪动size-x次,在x位置插入数据。

判断位置大小是否大于size,越界。 

//在固定位置插入,pos为下标
void SLInsert(SL* p, size_t pos, SLDataType x)
{assert(p);//注意要判断pos的大小if (pos>p->size){printf("pos 越界:%d\n",pos);return;}SLcheckCapacity(p);for (int i = p->size;i>pos;i--){p->a[i] = p->a[i - 1];}p->a[pos] = x;p->size++;
}

 7.2固定位置删除

分析:

操作与头删相似,从pos位置开始;第一个=第二个;第二个=第三个 ... ... ,覆盖到pos=尾数的上一个数,顺便也防了个越界。

//在固定位置删除,pos为下标
void SLErase(SL* p, size_t pos)
{assert(p);if (pos<p->size){for (int j = (int)pos; j<p->size-1; j++){p->a[j] = p->a[j + 1];}}p->size--;
}

8.查找及打印

依次遍历,找到则返回位置下标,

//查找
int SLFind(SL* p,SLDataType x)
{assert(p);for (int i = 0;i<p->size;i++){if (p->a[i]==x){return i;}}return -1;
}

也是遍历,打印每一个数据。 

//打印
void SLPrintf(SL* p)
{assert(p);for (int i = 0;i<p->size;i++){printf("%d ",p->a[i]);}printf("\n");
}

9.销毁顺序表

          注意要释放掉内存 

//销毁
void SLDestory(SL* p)
{assert(p);free(p->a);p->a = NULL;p->capacity = p->size = 0;
}

10.我的菜单及主函数 

直接上代码:

void menu()
{printf("******************************\n");printf("** 1.尾插数据 ** 2.头插数据 **\n");printf("** 3.尾删数据 ** 4.头删数据 **\n");printf("** 5.固定插入 ** 6.固定删除 **\n");printf("** 7.查找数据 ** 8.打印数据 **\n");printf("**         0.退出           **\n");printf("******************************\n");
}
int main()
{SL s;SLInit(&s);int input = 0;do{int val = 0;size_t pos = 0;menu();printf("请输入选项->:");scanf("%d", &input);switch (input){case 1:printf("请输入你要尾插的数据:");scanf("%d",&val);SLPushBack(&s,val);break;case 2:printf("请输入你要头插的数据:");scanf("%d", &val);SLPushFront(&s, val);break;case 3:SLPopBack(&s);break;case 4:SLPopFront(&s);break;case 5:printf("请输入你要插入的位置和数据:");scanf("%d %d",&pos ,&val);SLInsert(&s,pos,val);break;case 6:printf("请输入你要删除的位置:");scanf("%d", &pos);SLErase(&s, pos);break;case 7:printf("请输入要查找的数据:");scanf("%d",&val);int num=SLFind(&s,val);printf("%d\n",num);break;case 8:SLPrintf(&s);break;case 0:SLDestory(&s);break;default:printf("请重新输入\n");break;}} while (input);return 0;
}

 这样一个顺序表的定义,函数及功能就建立完成了。

看到这啦,点个赞呗,关注不迷路噢,欢迎大家评论指正。


http://chatgpt.dhexx.cn/article/wk459Ee7.shtml

相关文章

【C语言】顺序表的创建

一、代码实现部分&#xff1a; 1、顺序表是线性表的基础部分&#xff0c;至于顺序表&#xff0c;在本人看来无异于数组。至于线性表的概念&#xff0c;在此不再赘述。接下来尝试利用C语言对线性表中的顺序表进行代码实现&#xff08;此程序中规定用户输入的数据类型为int类型&a…

顺序表和链表

1.今天给大家介绍线性表中两个常见的结构顺序表和链表&#xff0c;其中链表又包括单链表和带头双向循环链表。 2.此部分的全部代码放在个人gitee中 &#xff0c;需要的自行拿取&#xff0c;前后文件依次对应SeqList SList DList。gitee链接点这里 一、线性表 1.线性表 线性表&…

顺序表的增删查改

数据结构 是数据存储的方式&#xff0c;对于不同的数据我们要采用不同的数据结构。就像交通运输&#xff0c;选用什么交通工具取决于你要运输的是人还是货物&#xff0c;以及它们的数量。 顺序存储结构 包括顺序表、链表、栈和队列等。 例如腾讯QQ中的好友列表&#xff0c;…

顺序表初始化

文章目录 1. 顺序表2. 顺序表的初始化 1. 顺序表 顺序表(顺序存储结构) 存储数据时&#xff0c;会提前申请一整块足够大小的物理空间&#xff0c;然后将数据依次存储到一整块连续的存储空间内&#xff0c;存储时做到数据元素之间不留一丝缝隙。 使用顺序表存储集合 {1,2,3,4,…

顺序表的创建

三个朋友今天全部上岸大厂&#xff0c;祝贺。&#xff08;太羡慕了&#xff09; 静态分配创建一个顺序表&#xff1b; 1.顺序表的定义&#xff1a; #define MaxSize 10 typedef struct {ElemType data[MaxSize];int length; }SqlList;这里我们用结构体的方式定义以一个顺序表…

顺序表的详解

线性表是n个具有相同特性的数据元素的有限序列。线性表是一种在实际中广泛使用的数据结构&#xff0c;常见的线性表&#xff1a;顺序表、链表、栈、队列、字符串.... 即顺序表为线性表的一种&#xff0c; 顺序表是一种物理地址连续的存储单元依次存储数据元素的线性结构&#…

什么是顺序表

顺序表 在程序中&#xff0c;经常需要将一组&#xff08;通常是同为某个类型的&#xff09;数据元素作为整体管理和使用&#xff0c;需要创建这种元素组&#xff0c;用变量记录它们&#xff0c;传进传出函数等。一组数据中包含的元素个数可能发生变化&#xff08;可以增加或删…

数据结构——顺序表

目录 一. 什么是顺序表&#xff1f; 1&#xff0c;静态顺序表 2&#xff0c;动态顺序表 ①动态顺序表的实现及其初始化 ②空间的创建 ③顺序表的打印和销毁 ④顺序表的尾部插入和删除 ⑤顺序表的头部插入和删除 ⑥顺序表pos位置的插入和删除 ⑦顺序表指定元素的删除 二&am…

【数据结构】——顺序表介绍(独家介绍,小白必看!!)

重点和易错点都用彩笔标记出来了&#xff0c;放心食用&#xff01;&#xff01; 数据结构分为线性表和非线性表&#xff0c;今天我们要学习的顺序表就是线性表中的一个小类。那么&#xff0c;何为线性表&#xff0c;线性表是指n个具有相同性质的数据元素的有限序列&#xff0c…

顺序表详解

目录 一、线性表的概念 二、顺序表 1、顺序表的概念 1&#xff09;. 静态顺序表&#xff1a;使用定长数组存储元素。 2&#xff09;. 动态顺序表&#xff1a;使用动态开辟的数组存储。 三、接口实现 1、创建 2、初始化 3、扩容 4、尾插 5、打印 6、销毁 7、尾删 越界&…

php的strstr是什么意思,php strstr函数怎么用

strstr()函数是PHP中的一个内置函数&#xff0c;语法为strstr(string,search,before_search) &#xff0c;用于搜索字符串在另一字符串中是否存在&#xff0c;如果是&#xff0c;返回该字符串及剩余部分&#xff0c;否则返回 FALSE。此函数区分大小写。 php strstr()函数怎么用…

【数据结构】--- kmp算法和strstr函数

kmp算法和strstr函数 引言一、概念分析分析原理分析 KMP算法原理基本操作图解KMP原理 三、复杂度分析四、KMP算法代码 引言 现实生活中&#xff0c;字符串匹配在很多的应用场景里都有着极其重要的作用&#xff0c;包括生物信息学、信息检索、拼写检查、语言翻译、数据压缩、网…

实现strstr函数

strstr函数的作用是寻找子字符串在目标字符串中第一次出现的位置。 #include <stdio.h> #include<stdlib.h> #include<assert.h> const char * Strstr(const char * str1, const char * str2) {assert(str1 ! NULL);assert(str2 ! NULL);char* cur str1;ch…

字符串函数剖析(3)---strstr函数

1.strstr函数的巧妙 – 查找子字符串 1.1模拟实现strstr函数 strstr函数&#xff1a;在一个字符串中查找子串 学习新函数时&#xff0c;先去c库查找该函数的相关资料&#xff0c;更加助于你的学习 const char * strstr ( const char * str1, const char * str2 );先看函数…

C语言strstr()函数用法-字符串查找

1.函数定义 strstr()函数是一个参数为两个字符指针类型&#xff0c;返回值是char*类型的函数。 用于找到子串&#xff08;str2&#xff09;在一个字符串&#xff08;str1&#xff09;中第一次出现的位置&#xff08;不包括str2的串结束符&#xff09;&#xff0c;并返回该位置…

ConcurrentHashMap 实现原理

一. ConcurrentHashMap 是什么 在并发编程中&#xff0c;ConcurrentHashMap 是一个经常被使用的数据结构&#xff0c;相比于 Hashtable 以及Collections.synchronizedMap() 来说&#xff0c;ConcurrentHashMap 在线程安全的基础上提供了更好的写并发能力&#xff0c;同时还降低…

ConcurrentHashMap 详解

前言 ConcurrentHashMap。 以下的技术点都基于JDK1.8~ 基础回顾 我们都知道&#xff0c;从JDK1.8起&#xff0c;ConcurrentHashMap底层的数据结构就已经从原来的Segment分段锁变为了数组 链表 红黑树的形态。 它是一款并发容器&#xff0c;一款装数据的容器在并发环境下铁…

ConcurrentHashMap介绍

引言 学习ConcurrentHashMap&#xff0c;合理的问题顺序应该如下&#xff1a; ConcurrentHashMap是什么&#xff08;WHAT&#xff09;为什么要有ConcurrentHashMap&#xff08;WHY&#xff09;ConcurrentHashMap的实现原理&#xff08;HOW&#xff09;ConcurrentHashMap如何使…

一文彻底弄懂ConcurrentHashMap

一文彻底弄懂ConcurrentHashMap 导读前言锁synchronizedvolatile&#xff08;非锁&#xff09;自旋锁分段锁ReentrantLockCAS ConcurrentHashMap 实现原理JDK1.7 中的 ConcurrentHashMapSegmentConcurrentHashMap 并发读写的几种情况get 方法put 方法 JDK1.8 中的 ConcurrentHa…

ConcurrentHashMap杂谈

为什么使用ConcurrentHashMap 在并发编程中使用HashMap可能导致程序死循环&#xff0c;而使用线程安全的HashTable效率又非常低下 线程不安全的HashMap 在多线程环境下&#xff0c;使用HashMap进行put操作会引起死循环&#xff0c;导致CPU利用率接近100% 死循环案例&#xf…