【数据结构<顺序表>】C语言

news2024/11/19 2:23:09

前言

线性表

线性表(linear list)是n个具有相同特性的数据元素的有限序列。 线性表是一种在实际中广泛使用的数据结构,常见的线性表:顺序表、链表、栈、队列、字符串…
线性表在逻辑上是线性结构,也就说是连续的一条直线。但是在物理结构上并不一定是连续的,线性表在物理上存储时,通常以数组和链式结构的形式存储
在这里插入图片描述

目录

  • 前言
    • 线性表
  • 1.顺序表
    • 动态和静态顺序表的创建
      • 静态顺序表
      • 动态顺序表
  • 2.前期的准备工作
    • 初始化顺序表
      • 销毁顺序表
        • 检查容量
          • 打印
  • 3.顺序表的增删查改等功能
    • 尾插
      • 尾删
        • 头插
          • 头删
            • 指定位置插入
            • 指定位置删除
            • 查找
  • 总代码
    • SeqList.c
    • SeqList.h
    • Test.c

1.顺序表

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

在这里插入图片描述

动态和静态顺序表的创建

静态顺序表

静态顺序表:指定顺序表的大小
缺点:空间开大了浪费,空间开小了不够用

typedef int SLDataType;
#define N 10//指定大小为10
typedef struct SeqList
{
	SLDataType a[N];
	int sz;
}SeqList;

动态顺序表

动态顺序表:使用动态开辟的数组存储
指向动态开辟的数组,空间不够用了可以扩容

#define INIT_CAPACITY 4
typedef int SLDataType;
typedef struct SeqList
{
	SLDataType* a;
	int sz;
	int capacity;
}SeqList;

2.前期的准备工作

静态顺序表只适用于确定知道需要存多少数据的场景。静态顺序表的定长数组导致N定大了,空间开多了浪费,开少了不够用。所以现实中基本都是使用动态顺序表,根据需要动态的分配空间大小,所以下面我们实现动态顺序表

初始化顺序表

//初始化
void SeqListInit(SeqList* ps)
{
	assert(ps);

	ps->a = (SLDataType*)malloc(sizeof(SLDataType) * INIT_CAPACITY);
	if (ps->a == NULL)
	{
		perror("SeqListInit");
		return;
	}
	ps->sz = 0;
	ps->capacity = INIT_CAPACITY;

销毁顺序表

//销毁
void SeqListDestroy(SeqList* ps)
{
	assert(ps);

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

检查容量

void SeqListCheakcapacity(SeqList* ps)
{
	assert(ps);

	if (ps->sz == ps->capacity)//如果数组大小和容量相同,则扩容
	{
		//扩容
		SLDataType* tmp = (SLDataType*)realloc(ps->a, sizeof(SLDataType) * ps->capacity * 2);
		if (tmp == NULL)
		{
			perror("SeqListPushback");
			return;
		}
		ps->a = tmp;
		ps->capacity = ps->capacity * 2;
	}
}
打印
//打印
void SeqListPrint(SeqList* ps)
{
	assert(ps);

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

3.顺序表的增删查改等功能

尾插

先检查容量是否满了,如果买了扩容,然后在当前sz位置直接插入就是尾部插入。

//尾插
void SeqListPushback(SeqList* ps, SLDataType x)
{
	assert(ps);
	SeqListCheakcapacity(ps);//检查容量

	ps->a[ps->sz] = x;//插入到当前sz位置
	ps->sz++;
}

尾删

sz当前的位置就是尾部,直接sz–即可

//尾删
void SeqListPopback(SeqList* ps)
{
	assert(ps);

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

头插

头插思想是把数据依次向后移动移位,然后再把数据插入到下标为0的位置

//头插
void SeqListPushFront(SeqList* ps, SLDataType x)
{
	assert(ps);
	SeqListCheakcapacity(ps);

	int end = ps->sz - 1;
	
	while (end >= 0)
	{
		ps->a[end+1] = ps->a[end];
		end--;
	}

	ps->a[0] = x;
	ps->sz++;
}
头删

数据依次向前覆盖,最后第一个数据就会消失,再–sz即可

//头删
void SeqListPopFront(SeqList* ps)
{
	assert(ps);
	assert(ps->sz > 0);
	
	int i = 0;
	for (i = 0; i < ps->sz; i++)
	{
		ps->a[i] = ps->a[i + 1];
	}

	ps->sz--;
}
指定位置插入

定义一个end指向最后一个值,然后依次把值向后挪动,while循环end>=pos
每次end- -,最后end就会走到pos的位置

//指定插入
void SeqListInsert(SeqList* ps, int pos, SLDataType x)
{
	SeqListCheakcapacity(ps);

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

	int end = ps->sz - 1;
	while (end >= pos)
	{
		ps->a[end + 1] = ps->a[end];
		end--;
	}
	ps->a[pos] = x;
	ps->sz++;
}
指定位置删除

pos后面的一个值,放到pos位置,依次类推,直到sz的位置

//指定删除
void SeqListEease(SeqList* ps, int pos)
{
	assert(ps);

	int end = pos;
	while (end < ps->sz)
	{
		ps->a[end] = ps->a[end + 1];
		end++;
	}
	ps->sz--;
}
查找

遍历整个顺序表,如果有相同的值,则返回下标,没有返回-1

//查
int SeqListFind(SeqList* ps, SLDataType x)
{
	assert(ps);

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

总代码

SeqList.c

#include "SeqList.h"

//初始化
void SeqListInit(SeqList* ps)
{
	assert(ps);

	ps->a = (SLDataType*)malloc(sizeof(SLDataType) * INIT_CAPACITY);
	if (ps->a == NULL)
	{
		perror("SeqListInit");
		return;
	}
	ps->sz = 0;
	ps->capacity = INIT_CAPACITY;
}

//销毁
void SeqListDestroy(SeqList* ps)
{
	assert(ps);

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

//打印
void SeqListPrint(SeqList* ps)
{
	assert(ps);

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

//检查容量
void SeqListCheakcapacity(SeqList* ps)
{
	assert(ps);

	if (ps->sz == ps->capacity)
	{
		//扩容
		SLDataType* tmp = (SLDataType*)realloc(ps->a, sizeof(SLDataType) * ps->capacity * 2);
		if (tmp == NULL)
		{
			perror("SeqListPushback");
			return;
		}
		ps->a = tmp;
		ps->capacity = ps->capacity * 2;

	}
}

//尾插
void SeqListPushback(SeqList* ps, SLDataType x)
{
	assert(ps);
	SeqListCheakcapacity(ps);

	ps->a[ps->sz] = x;
	ps->sz++;
}

//尾删
void SeqListPopback(SeqList* ps)
{
	assert(ps);

	assert(ps->sz > 0);
	//if (ps->sz == ps->capacity)
	//	return;

	ps->sz--;
}

//头插
void SeqListPushFront(SeqList* ps, SLDataType x)
{
	assert(ps);
	SeqListCheakcapacity(ps);

	int end = ps->sz - 1;
	
	while (end >= 0)
	{
		ps->a[end+1] = ps->a[end];
		end--;
	}

	ps->a[0] = x;
	ps->sz++;
}

//头删
void SeqListPopFront(SeqList* ps)
{
	assert(ps);
	assert(ps->sz > 0);
	
	int i = 0;
	for (i = 0; i < ps->sz; i++)
	{
		ps->a[i] = ps->a[i + 1];
	}

	ps->sz--;
}

//指定插入
void SeqListInsert(SeqList* ps, int pos, SLDataType x)
{
	SeqListCheakcapacity(ps);

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

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

//指定删除
void SeqListEease(SeqList* ps, int pos)
{
	assert(ps);

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

//查
int SeqListFind(SeqList* ps, SLDataType x)
{
	assert(ps);

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

SeqList.h

#include <stdio.h>
#include <stdlib.h>
#include <assert.h>

#define INIT_CAPACITY 4

typedef int SLDataType;

typedef struct SeqList
{
	SLDataType* a;
	int sz;
	int capacity;
}SeqList;

//初始化
void SeqListInit(SeqList* ps);

//销毁
void SeqListDestroy(SeqList* ps);

//打印
void SeqListPrint(SeqList* ps);

//检查容量
void SeqListCheakcapacity(SeqList* ps);


//增删查改

void SeqListPushback(SeqList* ps, SLDataType x);

void SeqListPopback(SeqList* ps);

void SeqListPushFront(SeqList* ps, SLDataType x);

void SeqListPopFront(SeqList* ps);

void SeqListInsert(SeqList* ps, int pos, SLDataType x);

void SeqListEease(SeqList* ps, int pos);

int SeqListFind(SeqList* ps, SLDataType x);

Test.c

void Test2()
{
	SeqList ps;
	SeqListInit(&ps);
	
	SeqListInsert(&ps, 0, 1);
	SeqListInsert(&ps, 1, 2);
	SeqListInsert(&ps, 2, 3);
	SeqListInsert(&ps, 3, 4);
	SeqListInsert(&ps, 4, 5);
	SeqListPrint(&ps);

	int ret = SeqListFind(&ps, 3);
	printf("%d\n", ret);
	SeqListPrint(&ps);

	SeqListEease(&ps, 0);
	SeqListPrint(&ps);
	
	SeqListDestroy(&ps);

}

int main()
{
	Test2();

	return 0;
}

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

linux swap交换区满了怎么办(已解决)

swap交换区满了怎么办 一、不增加交换区的方法 free -m 或free -h查看占用情况 使用如下指令来查看占用swap的前十进程 for i in $( cd /proc;ls |grep "^[0-9]"|awk $0 >100) ;do awk /Swap:/{aa$2}END{print "$i",a/1024"M"} /proc/$i…

仓库信息管理系统设计与实现

一、数据库设计 1.数据库模型设计概览 2.数据库表设计 ①depository 描述&#xff1a; 该表存储仓库的信息&#xff0c;比如仓库名称&#xff0c;仓库地址和仓库介绍 表结构&#xff1a; 序号 字段名 数据类型 主键 非空 默认值 描述 1 id INT(10) 是 是 2…

LlamaIndex 联合创始人下场揭秘:如何使用私有数据提升 LLM 的能力?

ChatGPT 的爆火证明了大型语言模型&#xff08;LLM&#xff09;在生成知识和推理方面的能力。不过&#xff0c;ChatGPT 是使用公共数据集进行预训练的模型&#xff0c;因此可能无法提供与用户业务相关的特定答案或结果。 那么&#xff0c;如何使用私有数据最大化发挥 LLM 的能力…

SpringMVC第三阶段:源码解析SpringMVC如何调用Controller目标方法

源码解析SpringMVC如何调用Controller目标方法&#xff1a; 浏览器如何访问到Controller目标方法. 1、所有请求进入时候,会先进入org.springframework.web.servlet.DispatcherServlet前端控制器的doDispatch() 方法 2 、在 1016 行 getHandler() 方法中,会通过请求的资源路径…

【51单片机】万年历功能的数字时钟+倒计时 Proteus仿真 普中板子可用

// 硬件&#xff1a;DS1302、按键、LCD1602、无源蜂鸣器 // 1、具有万年历功能的数字时钟 (本世纪100年通用)&#xff0c;能够正确的显示年、月、日、时、分、秒 // 2、按键设置时间(校时) // 3、24小时内至少可设置3个闹钟&#xff0c;并具有不同的闹钟铃声。每个闹钟可以选择…

[链表OJ题 7] 环形链表

目录 题目来源&#xff1a; 代码实现&#xff1a; 思路分析&#xff1a; 实现过程&#xff1a; 题目来源&#xff1a; 力扣 141. 环形链表 题目描述 代码实现&#xff1a; bool hasCycle(struct ListNode* head) {struct ListNode* fast head, * slow head;while (fas…

为什么更新了 DNS 记录不生效?

我们在上网时如果想要访问到另一台机器上的内容&#xff0c;通常只需要直接输入一串地址&#xff0c;例如&#xff1a;www.upyun.com&#xff0c;就能够准确访问到自己想要访问的网站。但是实际上这只是方便我们记忆的字符形式网络标识&#xff0c;真正让我们的机器和另一台机器…

C语言深度解析--函数

函数 函数的定义&#xff1a; 函数&#xff0c;又称为子程序&#xff0c;是一个大型程序中的某部分代码&#xff0c;由一个或多个语句块组成。它负责完成某项特定任务&#xff0c;而且相较于其他代码&#xff0c;具备相对独立性。 一般会有输入参数并有返回值&#xff0c;提供…

关于江苏专转本的十大真相,值得一看

【真相1】专转本考试题主要是大学相关科目的骨干老师出的。他们较长时间从事相应课程教学&#xff0c;专业领域较宽&#xff0c;学术造诣较高。具有副高及以上职称&#xff0c;年龄—般在55周岁以下。VX:hhkb5200【真相2】专转本考试题"紧扣《考试大纲》&#xff0c;大家要…

C++11 新特性

文章目录 &#x1f36a;统一列表初始化&#x1f36a;左值引用&#xff0c;右值引用&#x1f95b;概念和作用&#x1f95b;使用场景 &#x1f36a;完美转发&#x1f36a;可变参数模板 C11是C的一次大更新&#xff0c;出现了很多实用的语法和特性&#xff0c;所以我们很有必要学习…

[网络安全]DVWA之XSS(Stored)攻击姿势及解题详析合集

[网络安全]DVWA之XSS&#xff08;Stored&#xff09;攻击姿势及解题详析合集 XSS(Stored)-low level源代码姿势基于Message板块基于Name板块 XSS(Stored)-medium level源代码姿势双写绕过大小写绕过Xss标签绕过 XSS(Stored)-high level源代码姿势&#xff1a;Xss标签绕过 XSS(S…

汇编学习教程:灵活寻址(四)

引言 在上篇博文中&#xff0c;我们学习了 [bxsi] 的灵活寻址形式&#xff0c;由此讲解了汇编中的多重循环实现。那么本篇博文中&#xff0c;我们将继续学习灵活寻址其他实现形式。 本次学习从一道编程案例开始学起。 编程示例如下&#xff1a; assume cs:code,ds:datadata…

【Jmeter第二章】将Jmeter界面切换为中文显示

1、Jmeter临时切换为中文显示 注意&#xff1a;上面的配置只能保证本次运行是中文&#xff0c;如果要永久中文&#xff0c;需要修改Jmeter的配置文件 2、通过修改Jmeter配置文件设置为中文显示 1、在 Jmeter/bin目录下&#xff0c;找到&#xff1a;jmeter.properties 文件 2…

K_A39_012 基于STM32驱动W25Q32 模块读写数据 串口+OLED0.96显示

K_A39_012 基于STM32驱动W25Q32 模块读写数据 串口OLED0.96显示 所有资源导航一、资源说明二、基本参数参数引脚说明 三、驱动说明时序对应程序: 四、部分代码说明1、接线引脚定义1.2、STM32F103C8T6W25Q32 模块 五、基础知识学习与相关资料下载六、视频效果展示与程序资料获取…

LeetCode 429. N 叉树的层序遍历

429. N 叉树的层序遍历 描述 给定一个 N 叉树&#xff0c;返回其节点值的层序遍历。&#xff08;即从左到右&#xff0c;逐层遍历&#xff09;。 树的序列化输入是用层序遍历&#xff0c;每组子节点都由 null 值分隔&#xff08;参见示例&#xff09;。 示例 示例1 输入&…

货拉拉Java开发实习

目录 1.Java的重载和重写有什么区别2.什么情况下需要用到重载3.有很多个字符串和变量&#xff0c;需要把它们加起来&#xff0c;这时候用String会有什么问题4.有没有其它的替代方案5.StringBuffer和StringBuilder有什么区别6.一个自定义对象&#xff0c;分别创建了两个实例&…

5分钟梳理银行测试,文末附带实战项目

很多银行招聘都要求有相关从业经验&#xff0c;这对于想跨入这个岗位的0经验从业同学可真犯了难 “你都不让我上岗&#xff0c;我哪来的工作经验呢&#xff1f;” 为了解决这个问题&#xff0c;小柠檬整理了本篇文章&#xff0c;从3个方面介绍银行项目是如何进行测试的 银行…

springboot---IoC 和 AOP

目录 引语IoC传统开发模式的弊端控制反转和依赖注入 AOP面向对象的局限性面向切面编程 总结 引语 Inversion of Control&#xff0c;缩写为IoC&#xff1a;控制反转 Aspect-oriented programming&#xff0c;缩写为AOP&#xff1a;面向切面编程 IoC和AOP是spring框架最核心的…

VMware Workstation 与 Device/Credential Guard 不兼容.在禁用 Device/Credenti

这个时候我们需要去关掉几个功能 1、关闭Hyper-V 打开控制面板首页&#xff0c;找到“程序”&#xff0c;然后找到“启用或关闭Windows功能”&#xff0c;找到“Hyper-V”&#xff0c;有勾中的全部都取消掉&#xff0c;如果这一步操作失败&#xff0c;不要紧&#xff0c;继续…

使用马哈鱼SQLFlow分析聚合函数中的数据流列

聚合函数通常将列作为参数&#xff0c;在本文中&#xff0c;我们将讨论在用作函数参数的列和聚合函数之间创建什么样的数据流。 1. COUNT() COUNT()可以采用COUNT()&#xff0c;也可以采用任何列名&#xff0c;甚至可以采用空参数。如果参数为空或为列&#xff0c;则参数和函…