C语言实现顺序表(增,删,改,查)

目录

一.概念:

1.静态顺序表:使用定长数组存储元素。

2.动态顺序表:使用动态开辟的数组存储。

二.顺序表的实现:

1.顺序表增加元素

1.检查顺序表

2.头插

3.尾插

2.顺序表删除元素

1.头删

2.尾删

3.指定位置删

3.顺序表查找元素

4.顺序表修改元素

1.指定位置修改:

顺序表的问题:


数据结构和算法概述-CSDN博客icon-default.png?t=N7T8https://blog.csdn.net/lh11223326/article/details/136221673

一.概念:

顺序表在数据结构中是线性表的一种。

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

顺序表可以分为:

1.静态顺序表:使用定长数组存储元素.................

#include<stdio.h> 
#define N 7
 typedef int SLDataType;
 typedef struct SeqList
 {
    SLDataType array[N];//定长数组
    size_t size;//有效数据的个数
 }SeqList;

2.动态顺序表:使用动态开辟的数组存储。

#include<stdio.h>
 typedef struct SeqList{//顺序表的动态存储
    SLDataType*array;//指向动态开辟的数组
    size_t size;//有效数据个数
    size_t capicity;//容量空间的大小
 }SeqList;

二.顺序表的实现:

一般来说我们写大型程序的时候会把声明跟引入文件放在一个头文件中如下,创建一个SeqList.h文件把下列代码放入:

#define _CRT_SECURE_NO_WARNINGS 1
#pragma once
#include<stdio.h>
#include<stdlib.h>
#include<assert.h>
//动态顺序表
typedef int SLDataType;

typedef struct SeqList {
	SLDataType* a;//去堆上动态开辟,用来指向动态开辟的数组
	int size;//存储的有效数据个数
	int capacity;//空间大小
}SL;

//对顺序表进行管理:增删查改
void SLInit(SL *ps);//顺序表初始化
void SLDestroy(SL *ps);//顺序表销毁
void SLPrint(SL* ps);
void SLCheckCapacity(SL* ps);

//头插头删,尾插尾删
void SLPushBack(SL* ps, SLDataType x);//后插
void SLPopBack(SL* ps);//后删
void SLPushFront(SL* ps, SLDataType x);//头插
void SLPopFront(SL* ps);//头删

//返回下标,没有找到返回-1
//找数据
int SLFind(SL* ps, SLDataType x);
//在指定位置插入x
void SLInsert(SL* ps,int pos,SLDataType x );
//删除指定位置的值
void SLErase(SL* ps, int pos);
//修改坐标处的元素
void SLModify(SL* ps, int pos, SLDataType x);

1.顺序表增加元素

在增加元素之前需要初始化顺序表,此时需要使用malloc创建一块空间,代码如下:

void SLInit(SL *ps) {//顺序表的初始化
	assert(ps);
	ps->a = (SLDataType*)malloc(sizeof(SLDataType)*4);
	if (ps->a==NULL) {

		perror("malloc failed");
		exit(-1);//终止程序
	}
	ps->size = 0;
	ps->capacity = 4;
}

1.检查顺序表

如果顺序表满了就需要扩容........................

void SLCheckCapacity(SL* ps) {
	assert(ps);

	//满了要扩容
	if (ps->size == ps->capacity) {
		SLDataType* tmp = (SLDataType*)realloc(ps->a, ps->capacity * 2 * (sizeof(SLDataType)));
		if (tmp == NULL) {
			perror("realloc failed");
			exit(-1);
		}
		ps->a = tmp;
		ps->capacity *= 2;
	}
}

2.头插

在头部插入数据之前需要把全部数据都往后移动一位............

void SLPushFront(SL* ps, SLDataType x) {
	assert(ps);

	SLCheckCapacity(ps);

	//挪动数据
	int end = ps->size - 1;
	while (end >= 0) {
		ps->a[end + 1] = ps->a[end];
		--end;
	}
	ps->a[0] = x;
	ps->size++;
}

3.尾插

在末尾插入数据之前检查一下,如果有数据就是满了先扩容再插入......

void SLPushBack(SL* ps, SLDataType x) {
	assert(ps);

	SLCheckCapacity(ps);
	ps->a[ps->size] = x;
	ps->size++;
}

2.顺序表删除元素

1.头删

void SLPopFront(SL* ps) {
	assert(ps);

	assert(ps->size > 0);
	
	int begin = 1;
	while (begin < ps->size) {
		ps->a[begin - 1] = ps->a[begin];
		++begin;
	}
	ps->size--;
}

2.尾删

直接把有效数据个数减一就行了...........

void SLPopBack(SL* ps) {
	assert(ps);

	assert(ps->size > 0);
	ps->size--;
}

3.指定位置删

把数据删除之后把数据都移前面补全.........

void SLErase(SL* ps, int pos) {
	assert(ps);

	assert(pos >= 0 && pos < ps->size);
	int begin = pos + 1;
	while (begin < ps->size) {
		ps->a[begin - 1] = ps->a[begin];
		++begin;
	}
	ps->size--;
}

3.顺序表查找元素

把每个数据都比对一遍然后返回下标.........

int SLFind(SL* ps, SLDataType x) {
	assert(ps);

	for (int i = 0; i < ps->size; i++) {
		if (ps->a[i] == x) {
			return i;
		}
	}
	return -1;
}

4.顺序表修改元素

代码的位置是用户指定下标位置的修改:

void SLModify(SL* ps, int pos, SLDataType x) {
	assert(ps);

	assert(pos >= 0 && pos < ps->size);
	ps->a[pos] = x;
}

1.指定位置修改:

从指定位置的最后面把每个数据都后移一位,不要从前面往后面移,要从后往后,移动完数据之后就可以在指定位置添加了......

void SLInsert(SL* ps, int pos, SLDataType x) {
	assert(ps);

	assert(pos >= 0 && pos <= ps->size);
	SLCheckCapacity(ps);

	int end = ps->size - 1;
	while (end>=pos) {
		ps->a[end + 1] = ps->a[end];
		--end;
	}
	ps->a[pos] = x;
	ps->size++;
}

如下是SeqList.c中全部实现函数代码:

#include"SeqList.h"
void SLInit(SL *ps) {//顺序表的初始化
	assert(ps);
	ps->a = (SLDataType*)malloc(sizeof(SLDataType)*4);
	if (ps->a==NULL) {

		perror("malloc failed");
		exit(-1);//终止程序
	}
	ps->size = 0;
	ps->capacity = 4;
}
void SLDestroy(SL *ps)//顺序表的销毁
{
	assert(ps);

	free(ps->a);
	ps->a = NULL;
	ps->capacity = ps->size = 0;
}

void SLPrint(SL* ps) {
	assert(ps);

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

void SLCheckCapacity(SL* ps) {
	assert(ps);

	//满了要扩容
	if (ps->size == ps->capacity) {
		SLDataType* tmp = (SLDataType*)realloc(ps->a, ps->capacity * 2 * (sizeof(SLDataType)));
		if (tmp == NULL) {
			perror("realloc failed");
			exit(-1);
		}
		ps->a = tmp;
		ps->capacity *= 2;
	}
}


void SLPushBack(SL* ps, SLDataType x) {
	assert(ps);

	/*SLCheckCapacity(ps);
	ps->a[ps->size] = x;
	ps->size++;*/
	SLInsert(ps, ps->size, x);
}

void SLPopBack(SL* ps) {//
	assert(ps);

	//直接报错 暴力检查
	assert(ps->size > 0);
	ps->size--;

	//就是无效删除退出 检查
	/*if (ps->size == 0) {
		return;
	}*/
}
void SLPushFront(SL* ps, SLDataType x) {
	assert(ps);

	SLInsert(ps, 0, x);
}
void SLPopFront(SL* ps) {
	assert(ps);

	SLErase(ps, ps->size-1);
}

int SLFind(SL* ps, SLDataType x) {
	assert(ps);

	for (int i = 0; i < ps->size; i++) {
		if (ps->a[i] == x) {
			return i;
		}
	}
	return -1;
}


//在指定位置插入x
void SLInsert(SL* ps, int pos, SLDataType x) {
	assert(ps);

	assert(pos >= 0 && pos <= ps->size);
	SLCheckCapacity(ps);

	int end = ps->size - 1;
	while (end>=pos) {
		ps->a[end + 1] = ps->a[end];
		--end;
	}
	ps->a[pos] = x;
	ps->size++;
}
//删除指定位置的值
void SLErase(SL* ps, int pos) {
	assert(ps);

	assert(pos >= 0 && pos < ps->size);
	int begin = pos + 1;
	while (begin < ps->size) {
		ps->a[begin - 1] = ps->a[begin];
		++begin;
	}
	ps->size--;
}

void SLModify(SL* ps, int pos, SLDataType x) {
	assert(ps);

	assert(pos >= 0 && pos < ps->size);
	ps->a[pos] = x;
}

最后可以自行设计一个界面:

顺序表的问题:

  1. 中间/头部的插入删除,时间复杂度为O(N).
  2. 增容需要申请新空间,拷贝数据,释放旧空间,会有不小的消耗。
  3. 增容一般是呈2倍的增长,势必会有一定的空间浪费,如容量为100,满了以后增容到200,再继续插入了5个数据,后面没有数据插入了,那么就浪费了95个数据空间。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/495512.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

NSString有哪些创建对象的方法?创建的对象分别存储在什么区域?

NSString有哪些创建对象的方法&#xff1f;创建的对象分别存储在什么区域&#xff1f; 一般通过NSString创建对象的方法有&#xff1a; NSString *string1 "123";NSString *string2 [[NSString alloc] initWithString:"123"];NSString *string3 [NSSt…

Java设计模式—备忘录模式(快照模式)

定义 备忘录模式提供了一种状态恢复的实现机制&#xff0c;使得用户可以方便地回到一个特定的历史步骤&#xff0c;当新的状态无效或者存在问题时&#xff0c;可以使用暂时存储起来的备忘录将状态复原&#xff0c;很多软件都提供了撤销&#xff08;Undo&#xff09;操作&#…

白酒:浓香型白酒的典型代表与特点

云仓酒庄的豪迈白酒作为白酒的品牌&#xff0c;具有一系列与众不同的特点和优势。下面云仓酒庄的豪迈白酒将从典型性、品质、口感和包装等方面深入分析白酒的特点&#xff0c;以及它如何体现浓香型白酒的魅力。 浓香型白酒是中国白酒的重要分支&#xff0c;以浓郁的香味和与众不…

设计模式之原型模式讲解

原型模式本身就是一种很简单的模式&#xff0c;在Java当中&#xff0c;由于内置了Cloneable 接口&#xff0c;就使得原型模式在Java中的实现变得非常简单。UML图如下&#xff1a; 我们来举一个生成新员工的例子来帮助大家理解。 import java.util.Date; public class Employee…

SI案例分享--冷却液对PCIe链路性能的影响

目录 0 引言 1 PCIe线缆组件在不同冷却方式中的性能对比 1.1 配置Paddle card互连的电缆组件测试结果&#xff08;cable-1&#xff09; 1.2 直接焊接互连的电缆组件测试结果&#xff08;cable-2&#xff09; 1.3 一侧配置Paddle card、一侧直接焊接互连的电缆组件测试结果…

阿里云账号怎么注册?看这一篇就够了

阿里云账号怎么注册&#xff1f;阿里云账号支持手机号注册、阿里云APP注册、淘宝、支付宝和钉钉多种注册方式&#xff0c;账号注册后需要通过实名认证才可以购买或使用云产品&#xff0c;使用淘宝、支付宝或钉钉注册方式可以免去实名认证步骤&#xff0c;阿里云百科aliyunbaike…

深入解析MD5哈希算法:原理、应用与安全性

码到三十五 &#xff1a; 个人主页 心中有诗画&#xff0c;指尖舞代码&#xff0c;目光览世界&#xff0c;步履越千山&#xff0c;人间尽值得 ! 本文将深入探讨MD5哈希算法的工作原理、应用场景以及安全性问题。我们将了解MD5如何生成固定长度的哈希值&#xff0c;以及它在数…

Leo赠书活动-21期 《一篇讲明白 Hadoop 生态的三大部件》

✅作者简介&#xff1a;大家好&#xff0c;我是Leo&#xff0c;热爱Java后端开发者&#xff0c;一个想要与大家共同进步的男人&#x1f609;&#x1f609; &#x1f34e;个人主页&#xff1a;Leo的博客 &#x1f49e;当前专栏&#xff1a; 赠书活动专栏 ✨特色专栏&#xff1a;…

【OpenAI援引马斯克评价中国】小米汽车 SU7 顶配版或超 30 万/OpenAI 加持机器人亮相/荣耀已投入 100 亿研发 AI

雷军&#xff1a;共建一个更良性包容的汽车市场舆论环境 Figure 与 OpenAI 联手推出新机器人 亚马逊和 Google 悄悄降低对生成式 AI 的预期 小米生态链模式大改革&#xff0c;将进行分级管理 掌阅科技&#xff1a;致力打造国内首款真正 AI 阅读应用 荣耀称已投入 100 亿用于 AI…

Ipython与Jupyter之间的关系

IPython 和 Jupyter 之间的关系可以从它们的历史和目标中得到很好的解释。IPython&#xff08;Interactive Python&#xff09;最初是由 Fernando Prez 于 2001 年创建的&#xff0c;旨在提升 Python 的交互式计算体验。它提供了一个强大的交互式 Python shell 和一个面向高效计…

C语言例4-27:计算1+2+...+100之和(利用while语句实现)。

代码如下&#xff1a; //计算12...100之和&#xff08;利用while语句实现&#xff09;。 #include<stdio.h> int main(void) {int n1, sum0;while(n<100){ //复合语句作为当型循环结构的循环体sumsumn;n;}printf("sum %d\n",sum);retu…

Phoenix伪分布安装

引言 Phoenix是构建在HBase上的一个SQL层&#xff0c;能让我们用标准的JDBC APIs而不是HBase客户端APIs来创建表&#xff0c;插入数据和对HBase数据进行查询。Phoenix完全使用Java编写&#xff0c;作为HBase内嵌的JDBC驱动。Phoenix查询引擎会将SQL查询转换为一个或多个HBase扫…

国赛大纲解读

1. 第一部分,是针对5G基础知识的掌握,第二部分是人工智能基本算法的掌握,就是人工智能的应用,用5G+人工智能(AI算法)进行网络优化的问题,要有网络优化的基础知识,比如说:某个区域的覆盖问题,覆盖特别差,但有数据,覆盖电频,srp值这些数据给你,根据数据来判断是…

Rabbitmq消息顺序的问题以及解决方案

1.1消息顺序的场景 场景1&#xff1a;一个queue&#xff0c;多个consumer 一个queue&#xff0c;有多个consumer去消费&#xff0c;这样就会造成顺序的错误&#xff0c;consumer从MQ里面读取数据是有序的&#xff0c;但是每个consumer的执行时间是不固定的&#xff0c;无法保…

1-28 核心类库(四)

一 BigDecimal类(会用) 1.作用:用来进行金融类项目中的数据的精确计算 2. import java.math.BigDecimal; import java.math.RoundingMode;public class BigDecimalTest {public static void main(String[] args) {//一定要字符串 int类型的答案不一定准BigDecimal bd1new B…

专题二_滑动窗口(1)

目录 209. 长度最小的子数组 解析 题解 3. 无重复字符的最长子串 解析 题解 1004. 最大连续1的个数 III 解析 题解 209. 长度最小的子数组 209. 长度最小的子数组 - 力扣&#xff08;LeetCode&#xff09; 解析 题解 class Solution { public:int minSubArrayLen(int…

JAVA WEB 能够实现整个文件夹的上传下载吗?

导入项目&#xff1a; 导入到Eclipse&#xff1a;导入项目 导入到IDEA&#xff1a;导入项目 springboot统一配置&#xff1a;springboot-配置 下载示例&#xff1a; https://gitee.com/xproer/up6-jsp-eclipse/tree/6.5.40/ 工程 NOSQL NOSQL示例不需要任何配置&#xff0c;可…

【Java程序员福音】国外Java 程序员开发常用的工具(全)

Java是一门开源语言&#xff0c;所以可以选择的开发环境很多&#xff0c;你适合哪一个呢&#xff1f;整理了一些Java程序员开发常用的工具&#xff0c;需要的同学可以收藏。 1、免费开源Eclipse Eclipse最初是由IBM公司开发的替代商业软件Visual Age for Java的下一代IDE开发环…

深入浅出:探索Hadoop生态系统的核心组件与技术架构

目录 前言 HDFS Yarn Hive HBase Spark及Spark Streaming 书本与课程推荐 关于作者&#xff1a; 推荐理由&#xff1a; 作者直播推荐&#xff1a; 前言 进入大数据阶段就意味着 进入NoSQL阶段&#xff0c;更多的是面向OLAP场景&#xff0c;即数据仓库、BI应用等。 …

【Ubuntu】Ubuntu LTS 稳定版更新策略

1、确保下载环境 sudo apt update && sudo apt upgrade -y sudo apt autoremove 2、安装更新管理器 sudo apt install update-manager-core -y 3、设置只更新稳定版 sudo vim /etc/update-manager/release-upgrades 4、开始更新&#xff0c;耐心等待 sudo do-re…