【数据结构】—— 线性表

news2024/11/15 17:29:08

目录

  • 前言
  • 一、顺序表
    • 1.1 顺序表的定义及其特点
    • 1.2 顺序表的C语言实现
      • 1.2.1 定义顺序表
      • 1.2.2 初始化
      • 1.2.3 插入
      • 1.2.4 删除
      • 1.2.5 查找
  • 二、链表
    • 2.1 链表的定义
    • 2.2 单向链表的实现
      • 2.2.1 定义单向链表
      • 2.2.2 创建链表
      • 2.2.3 插入元素
      • 2.2.4 删除元素
      • 2.2.5 查找
    • 2.3 双向循环链表


前言

  线性表是最基本、最简单、也是最常用的一种数据结构。线性表(linear list)是数据结构的一种,一个线性表是n个具有相同特性的数据元素的有限序列。线性表又称线性存储结构,是最简单的一种存储结构,线性表存储数据的实现方案有两种,分别是:顺序存储结构链式存储结构
在这里插入图片描述


一、顺序表

1.1 顺序表的定义及其特点

  顺序表即线性表的顺序存储结构,最简单的顺序表为数组。它是用一组地址连续的存储单元依次存储线性表中的数据元素,从而使得逻辑上相邻的两个元素在物理位置上也相邻。顺序表存储数据的具体实现方案是:将数据全部存储到一整块内存空间中,数据元素之间按照次序挨个存放。
请添加图片描述

  其有如下特点:

  • 随机访问:可通过首地址和元素序号在单位时间O (1)内找到指定的元素。
  • 存储密度高:存储密度高是因为每个结点存储空间指用来存储数据元素,没有别的额外开销。
  • 物理位置相邻:物理位置和逻辑位置一样,保持相邻,因此插入和删除元素需要移动大量元素,比较耗时。

1.2 顺序表的C语言实现

1.2.1 定义顺序表

  加入stdbool.h引入bool型变量

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

typedef	int	DataType	//定义存储类型
#define Maxsize 50    	//线性表最大长度

typedef struct
{
    DataType data[Maxsize];    //顺序表的元素
    int len;            //顺序表当前长度
}SqList;            //顺序表的定义类型

1.2.2 初始化

//初始化只要清零长度
void InitList(SqList *L)
{
    L->len=0;
}

1.2.3 插入

//定义插入顺序表的函数:在第i个元素之前插入x
//返回值:0-插入失败;1-插入成功
bool ListInsert(SqList *L,int i,int x)
{
	int j;
	
	//判断插入后是否溢出
	if(L->length >= MaxSize)
    {
        printf("顺序表已满,无法进行插入操作!");
        return 0;
    }
    //判断插入位置是否合法
    else if((i<=0) || (i>L->length+1))
    {
        printf("插入的位置不正确!");
        return 0;
    }

    for(j=L->len-1;j>=i-1;j--)
    {
        L->data[j+1]=L->data[j];
    }
    //在第i个元素之前插入就是把从i开始的元素往后移,然后赋值给第i个元素,在数组中就是i-1了
    L->data[i-1]=x;
    L->len++; //插入完之后数组长度+1
    
    return 1;
}

1.2.4 删除

//定义删除顺序表元素函数,删除第i个元素
//返回值:0-删除失败;1-删除成功
bool ListDelete(SqList *L,int i)
{
    int j;
    
    if((i<1) || (i>L->len))//和插入是一样的判断条件
    {
        printf("删除位置错误");
        return 0;
    }
    
    //删除第i个元素就是从第i个元素开始一个一个地从后向前覆盖
    for(j=i;j<L->len;j++)
    {
        L->data[j-1]=L->data[j];
    }
    L->len--;//数组长度-1
    
    return 1;
}

1.2.5 查找

// 在顺序表中查找第一个值等于x的元素,并返回
int findElem(SqList *L, int x)
{
	int i;
	
    for(i=0;i<L->len;i++)
    {
        if(x==L->data[i])
            return i;           //找到返回下标
    }
    return -1;    //没找到返回-1
}

二、链表

2.1 链表的定义

  链表是一个在物理存储单元中非连续、非顺序的的存储结构,数据元素的逻辑顺序是通过链表的指针地址实现,有一系列结点(地址)组成,结点可动态的生成。链表分为三类:单向链表双向链表循环链表
请添加图片描述

  节点包括两个部分:

  • 一部分存储数据元素的数据域(存储对象)
  • 另一部分是存储下一个节点地址的指针域(引用下一个节点)。

  其有以下特点

  • 优点:和线性表顺序结构相比,链表结构插入,删除操作不需要移动所有节点,不需要初始化容量。
  • 缺点:搜索时必须遍历节点,含有大量引用,占空间大。

2.2 单向链表的实现

2.2.1 定义单向链表

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

typedef int DataType;

typedef struct ListNode{
    DataType data; 		//代表数据域
    struct ListNode * next; //代表指针域,指向直接后继元素
}SList;

2.2.2 创建链表

//输入:arr[]-数组;n-数组长度
//返回值:链表
SLink* CreateList(int arr[], int n)
{
	int i;

	SList* head = NULL;    // 头节点指针
    SList* tail = NULL;    // 头节点指针

	for (i = 0; i < n; i++)
	{
        // 创建新节点并为其分配内存
        SList* newNode = (SList*)malloc(sizeof(SList));

        if (newNode == NULL) {
            printf("内存分配失败.");
            return NULL;
        }

		// 设置新节点的数据
		newNode->data = arr[i];
		newNode->next = NULL;

        if (head == NULL)
        {
            head = tail = newNode;
        }
        else
        {
            tail->next = newNode;
            tail = tail->next;
        }
	}

	return head;
}

2.2.3 插入元素

void Insert(SList** headRef, int position, int value) 
{
    int count = 1;
    SList* p = *headRef;//创建临时结点

    SList* newNode = (SList*)malloc(sizeof(SList));// 创建新节点并为其分配内存

    if (newNode == NULL) {
        printf("内存分配失败。\n");
        return;
    }
    newNode->data = value;

    // 如果要插入的位置是链表的头部或链表为空
    if(*headRef == NULL || position == 0) {
        newNode->next = *headRef;
        *headRef = newNode;
        return;
    }

    // 找到要插入位置的前一个节点
    while (p->next != NULL && count < position) {
        p = p->next;
        count++;
    }

    // 在指定位置插入节点
    newNode->next = p->next;
    p->next = newNode;
}

2.2.4 删除元素

void Delete(SList** headRef, int value) {
    SList* p = *headRef;
    SList* prev = NULL;

    // 处理头节点为目标节点的情况
    if (p != NULL && p->data == value) {
        *headRef = p->next;
        free(p);
        return;
    }

    // 遍历链表找到要删除的节点
    while (p != NULL && p->data != value) {
        prev = p;
        p = p->next;
    }

    // 如果找到了目标节点,则删除它
    if (p != NULL) {
        prev->next = p->next;
        free(p);
    }
}

2.2.5 查找

SList* Search(SList* head, int value) {
    SLink* p = head;

    while (p != NULL) {
        if (p->data == value) {
            return p;  // 返回匹配的节点地址
        }
        p = p->next;
    }

    return NULL;  // 若没有找到匹配节点,则返回NULL
}

2.3 双向循环链表

  双向链表就是除了next后结点还有pre前结点,然后再将尾结点与头节点相连形成循环,就成了双向循环链表,其示意图与定义如下:
请添加图片描述

typedef int DataType;
typedef struct ListNode
{
	struct ListNode *next;
	struct ListNode *pre;
	DataType data;
}LTNode;

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

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

相关文章

选刊风向标!985大学近十年发文热门IEEE期刊盘点

本期盘点同济大学近十年有关IEEE旗下发文较多的期刊&#xff0c;一起来看看哪些是双一流大学热门发文期刊&#xff1a; 1、IEEE Transactions on Cybernetics • 影响因子&#xff1a;9.4 • JCR1区&#xff0c;中科院1区-Top • 检索数据库&#xff1a;SCIE • 期刊分区&a…

stable diffusion的安装

stable diffusion的安装 一、前言二、安装python环境1、已经安装python环境&#xff0c;但非3.10.6版本&#xff08;可以不看&#xff09; 三、安装stable diffusion四、运行五、启动报错1、Torch is not able to use GPU2、Installing open_clip 卡住3、报错提示 "git&qu…

systemverilog中的DPI-C用例介绍

文章目录 前言一、dpi_longint二、dpi_packed_array三、dpi_structure四、相关参考总结 前言 本文主要基于VCS内置的三个关于DPI-C的使用用例&#xff0c;记录一下DPI-C的使用方法。测试用例的路径为$VCS_HOME/doc/examples/testbench/sv/。测试用例包括&#xff1a;dpi_longi…

自然语言处理:第四十三章 视觉RAG:变革传统深度学习模型开发流程,开创下一代多模态视觉模型的新时代

文章链接:微信公众平台 (qq.com) 写在前面: 笔者更新不易&#xff0c;希望走过路过点个关注和赞&#xff0c;笔芯!!! 写在前面: 笔者更新不易&#xff0c;希望走过路过点个关注和赞&#xff0c;笔芯!!! 写在前面: 笔者更新不易&#xff0c;希望走过路过点个关注和赞&#xff…

Chaper 09 深入理解Promise

文章目录 前言一、异步编程二、Promise 前言 在JavaScript中&#xff0c;异步编程是一个重要的概念。随着应用程序的复杂性增加&#xff0c;处理异步操作的方式也变得更加复杂。Promise是一种用于处理异步操作的对象&#xff0c;它提供了一种更清晰和更强大的方式来管理异步代…

智能的JavaScript开发工具WebStorm v2024.2全新发布

WebStorm 是jetbrains公司旗下一款JavaScript 开发工具&#xff0c;被广大中国JS开发者誉为"Web前端开发神器""强大的HTML5编辑器""智能的JavaSscript IDE"等。与IntelliJ IDEA同源&#xff0c;继承了IntelliJ IDEA强大的JS部分的功能。 立即获…

学生防近视台灯什么品牌好?学生护眼台灯怎么选?收下这份攻略

根据中国报告大厅的数据&#xff0c;近年来&#xff0c;随着科技的不断进步&#xff0c;台灯行业亦得到了快速发展。早期的台灯主要采用白炽灯作为光源&#xff0c;但随着LED技术的日益成熟&#xff0c;LED台灯已成为市场主流。目前&#xff0c;台灯行业正处于高速发展阶段&…

【吊打面试官系列-Redis面试题】Redis 过期键的删除策略?

大家好&#xff0c;我是锋哥。今天分享关于 【Redis 过期键的删除策略】面试题&#xff0c;希望对大家有帮助&#xff1b; Redis 过期键的删除策略&#xff1f; 1000道 互联网大厂Java工程师 精选面试题-Java资源分享网 1、定时删除:在设置键的过期时间的同时&#xff0c;创建…

19 - 路径搜索的综合

---- 整理自狄泰软件唐佐林老师课程 文章目录 1. 需求2. 一些工具3. 编译规则的依赖4. 实验 1. 需求 工程项目中不希望源码文件夹在编译时被改动&#xff08;只读文件夹&#xff09;在编译时自动创建文件夹&#xff08;build&#xff09;用于存放编译结果编译过程中能够自动搜…

java基本程序设计结构与数据类型

1.一个简单程序的编写、编译与运行 编写如下的Main.java public class Main{public static void main(String[] args){System.out.println("Hello World");} }上面的程序有几个要注意的点&#xff1a; ①public 是访问修饰符&#xff0c;用来表示其他程序对Main类的…

【C++】vector(下)--下篇

个人主页~ vector&#xff08;上&#xff09;~ vector&#xff08;下&#xff09;–上篇~ vector 二、模拟实现3、test.cpptest1test2test3test4test5test6 三、一个难题 二、模拟实现 3、test.cpp test1 这个没啥好说的&#xff0c;就是尾插和迭代器都能正常使用 //测尾…

中国各、省、市、县、乡镇基尼系数数据(2000-2023年)

基尼系数是一个国际上广泛用来综合考察居民内部收入分配差异状况的重要指标。它表示在全部居民收入中&#xff0c;用于进行不平均分配的那部分收入占总收入的百分比。基尼系数的值介于0和1之间&#xff0c;其中0代表收入分配绝对平均&#xff0c;即每个人的收入都相等&#xff…

Qt21基础图形的绘制

基础图形的绘制 paintareapaintarea.hpaintarea.cpp paintexpaintex.hpaintex.cpp main.cpp运行图 paintarea paintarea.h #ifndef PAINTAREA_H #define PAINTAREA_H#include <QWidget> #include <QBrush> #include <QPen> #include <QPainter> #inc…

DZ主题模板 Discuz迪恩淘宝客购物风格商业版模板

Discuz淘宝客网站模板&#xff0c;迪恩淘宝客购物风格商业版模板。 版本支持&#xff1a;discuzx3.0版本,discuzx3.1版本,discuzx3.2版本。 包括网站首页&#xff0c;论坛首页&#xff0c;论坛列表页&#xff0c;论坛内容页&#xff0c;论坛瀑布流,频道列表页&#xff0c;频道…

开学季好物合集有哪些?全方位必备好物推荐

随着秋风轻拂&#xff0c;书页翻新的声音在耳边悄然响起&#xff0c;我们迎来了又一个开学季。在这个特别的时刻&#xff0c;每位学子都怀揣着对未来的无限憧憬&#xff0c;踏入了校园的大门。为了帮助大家更好地适应新学期的学习节奏&#xff0c;享受更加充实而愉快的校园生活…

解决Linux安装epel源提示没有可用安装包

目录 前言 常规方法总结 1、命令直接安装 2、通过网址下载安装 手动安装 1、EPEL的资源地址 2、选择版本 3、找到rpm文件存放位置 4、下载并移动至虚拟机中 5、安装 6、成功后会生成相应的repo文件 7、更新源 前言 EPEL&#xff0c; 即Extra Packages for Enterpri…

STM32开发资料

文章目录 前言一、正点原子&#xff1f;1. 资料链接2.论坛3.参考资料盘 二、野火1. 论坛2. 资料链接 总结 前言 提示&#xff1a;这里可以添加本文要记录的大概内容&#xff1a; 学习需要&#xff1a;找一个开发板的资料作为基础 提示&#xff1a;以下是本篇文章正文内容&…

Redis 键值对操作全攻略

文章目录 一 . get 和 set二 . keys *三 . exists四 . del五 . expire六 . ttl七 . Redis 的 key 的过期策略八 . 定时器的实现8.1 基于优先级队列8.2 基于时间轮实现的定时器 九 . type十 . 数据库管理相关命令 Hello , 大家好 , 这个专栏给大家带来的是 Redis 系列 ! 本篇文章…

聊聊客户端/服务器与订阅/发布两大模型

正文 大家好&#xff0c;我是bug菌&#xff5e; 在项目开发中根据不同的应用场景通常会去尝试各种各样的通信方式&#xff0c;可能试来试去可能又回到了原地&#xff0c;而对于一个相对比较大的网络系统&#xff0c;不同的场景得考量不同的通信架构模型&#xff0c;那么今天就跟…

面向对象23种设计模式通俗理解

终点即是起点,自强不息! 设计模式的理解 设计模式是为了可重用代码、让代码更容易被他人理解、保证代码可靠性。 模式&#xff1a;在某些场景下&#xff0c;针对某类问题的某种通用的解决方案。 场景&#xff1a;项目所在的环境 问题&#xff1a;约束条件&#xff0c;项目目标…