当前位置: 首页 > news >正文

数据结构---线性表

1,顺序表实现---动态分配

#include<stdlib.h>
#define InitSize 10
typedef struct {int *data;//静态分配int length;int MaxSize;
}SqList;
void InitList(SqList& L)
{L.data = (int*)malloc(InitSize * sizeof(int));//分配空间L.length = 0;L.MaxSize = InitSize;//初始空间为10}
void ListInsert(SqList& L, int x, int a)
{L.data[x] = a;
}
void Increaselength(SqList& L, int len)
{int *p = L.data;L.data = (int*)malloc((InitSize + len) * sizeof(int));//重新开辟空间for (int i = 0; i < L.MaxSize;i++){L.data[i] = p[i];}L.MaxSize = InitSize + len;free(p);}
int main()
{SqList q;InitList(q);ListInsert(q, 2, 4);Increaselength(q, 5);ListInsert(q, 12, 2);printf("data[2]=%d,data[12]=%d", q.data[2],  q.data[12]);system("pause");return 0;
}

 第i个元素中的i表示的是位序

2, 静态分配的插入与删除操作:

2.1插入操作:

typedef struct {int data[MaxSize];int length;}SqList;
void InitList(SqList& L)
{L.length = 0;for (int i = 0; i <MaxSize-1; i++){L.data[i] = i;//赋予原始数据,注意不要插满L.length++;}}
bool ListInsert(SqList &L,int i,int e)//在第i个位置插入e
{if (i<1 || i>L.length + 1)return false;if (L.length >= MaxSize)//存储空间已满{return false;}for(int j=L.length;j>=i;j--){L.data[j] = L.data[j - 1];}L.data[i - 1] = e;L.length++;return true;}
int main()
{SqList L;InitList(L);if (ListInsert(L, 8, 1)){printf("data[7]=%d ", L.data[7]);//验证插入}system("pause");return 0;}

2.2,删除操作:

typedef struct {int data[MaxSize];int length;}SqList;
void InitList(SqList& L)
{L.length = 0;for (int i = 0; i < MaxSize - 1; i++){L.data[i] = i;//赋予原始数据,注意不要插满L.length++;}}
bool ListDelete(SqList &L,int i,int &e)//在第i个位置插入e
{if (i<1 || i>L.length)return false;e=L.data[i - 1];//赋值for(int j=i;j<L.length;j++){L.data[j-1] = L.data[j];}L.length--;return true;}int main()
{SqList L;InitList(L);int e = -1;if (ListDelete(L, 8, e))//位置8的元素是7{printf("删除的元素是%d data[7]=%d", e,L.data[7]);//验证删除,删除后data[7]=8}system("pause");return 0;}

3,顺序表的查找:

3.1按位查找

动态分配和普通数组访问方式相同,时间复杂度为O(1)

GetElem(SqList L,int i)
{
return L.data[i-1];
}

3.2按值查找

动态分配方式:

int LocatElem(SqList L, int e)
{
for(int i=0;i<L.length;i++)
{
if(L.data[i]==e)
return i+1;
}
return 0;}

4,链表初始化

4.1不带头结点的单链表的初始化:

与顺序表不同,单链表是用指针来定义

typedef struct LNode {int data;struct LNode* next;//每个元素包括数据和指向下一个节点的指针}LNode,*LinkList;//LNode*等价于LinkList
bool InitList(LinkList &L)//声明是一个单链表
{L = NULL;return true;}
bool IsEmpty(LinkList &L)//声明是一个单链表
{return (L == NULL);}
int main()
{LinkList L;//声明一个指向单链表的指针InitList(L);if(IsEmpty(L))printf("初始化成功");system("pause");return 0;}

4.2,带头结点的单链表的初始化: 

typedef struct LNode {int data;struct LNode* next;//每个元素包括数据和指向下一个节点的指针}LNode,*LinkList;//LNode*等价于LinkList
bool InitList(LinkList &L)//声明是一个单链表
{L = (LNode*)malloc(sizeof(LNode));//头指针指向下一个节点:即为头节点if (L == NULL)return false;//没有内存,分配失败L->next = NULL;//头节点暂时没有节点return true;}
bool IsEmpty(LinkList &L)//声明是一个单链表
{return (L == NULL);}
int main()
{LinkList L;InitList(L);if(IsEmpty(L)==false)printf("初始化成功");system("pause");return 0;}

5,链表插入操作:

5.1,带头结点,按位序插入:

typedef struct LNode {int data;struct LNode* next;//每个元素包括数据和指向下一个节点的指针}LNode,*LinkList;//LNode*等价于LinkList
//带头结点按位序插入
bool ListInsert(LinkList& L,int i,int e)//在第i个位置插入e
{if (i < 1)return false;int j = 0;LNode *p;p= L;//是从第0个节点开始遍历,所以p应该与头节点相同while (p != NULL && j < i - 1)//找到第i-1的节点{p = p->next;j++;}if (p == NULL)//超出链表长度{return false;}LNode *s = (LNode*)malloc(sizeof(LNode));s->data = e;s->next = p->next;p->next = s;return true;}
bool InitList(LinkList &L)//声明是一个单链表
{L = (LNode*)malloc(sizeof(LNode));//头指针指向下一个节点:即为头节点if (L == NULL)return false;//没有内存,分配失败L->next = NULL;//头节点暂时没有节点return true;}
bool IsEmpty(LinkList &L)//声明是一个单链表
{return (L == NULL);}
int main()
{LinkList L;InitList(L);if(IsEmpty(L)==false)printf("初始化成功");if(ListInsert(L, 1, 1))printf("插入成功");system("pause");return 0;}

 5.2,不带头节点按位序插入:

bool ListInsert(LinkList& L,int i,int e)//在第i个位置插入e
{if (i < 1)return false;if (i == 1)//此处插入第一个节点和其他节点不同,直接与L交互{LNode* s = (LNode*)malloc(sizeof(LNode));s->data = e;s->next = L;//指向L指向的节点L = s;//需要更改头结点的指向,比较麻烦return true;}int j = 1;//没有第0个节点LNode *p;p= L;//是从第0个节点开始遍历,所以p应该与头节点相同while (p != NULL && j < i - 1)//找到第i-1的节点{p = p->next;j++;}if (p == NULL)//超出链表长度{return false;}LNode* s = (LNode*)malloc(sizeof(LNode));s->data = e;s->next = p->next;p->next = s;return true;}

5.3,指定节点的后插操作:

//在指定节点后插入一个元素
bool InsertNextLNode(LNode *p,int e)//传入节点即可,不需要传入表
{if (p == NULL)return false;//节点选择错误LNode* s = (LNode*)malloc(sizeof(LNode));if (s == NULL)//内存分配不够return false;s->data = e;s->next = p->next;p->next = s;return true;
}

 

5.4前插操作:

在p节点之前插入s节点

思路:无法找到前驱节点,因此可以插在p节点之后,然后将两个节点中的数据调换

bool InsertPriorNode(LNode* p, LNode* s)
{if (p == NULL || s == NULL)return false;s->next = p->next;p->next = s;int temp = s->data;s->data = p->data;p->data = temp;return true;
}

 6,链表删除操作:

6.1,带头结点按位序删除第i个节点:

思路:先找到第i-1节点,然后将前一个结点的next指针指向后一个结点的next指针

bool ListDelete(LinkList L, int i, int& e)
{if (i < 1)return false;LNode* p = L;//当前指向结点int j = 0;while (p != NULL&&j<i-1) {//找到i-1结点p = p->next;j++;}if (p == NULL)return false;if (p->next== NULL)//需要删除的结点也为空return false;LNode* q = p->next;//应当被删除的结点e = q->data;p->next = q->next;free(q);return true;
}

6.2,指定节点的删除p:

将p的后一个结点复制到p,然后将p的后一个结点释放掉

bool DeleteNode(LNode* p)
{if (p == NULL)return false;LNode* q = p->next;p->data = p->next->data;p->next = q->next;free(q);return true;
}

注意:如果p是最后一个结点,只能从表头依次寻找p的前驱

7,单链表的查找(带头结点)

7.1按位查找

LNode *GetElem2(LinkList L, int i)
{if (i < 0)//第位序0返回的是头节点return NULL;LNode* p;p = L;int j = 0;//带头结点下标从0开始while (p != NULL && j < i){p = p->next;j++;}return p;
}

回顾:

 

7.2按值查找

LNode* GetElem3(LinkList L, int e)
{LNode* p=L->next;while (p != NULL && p->data!=e)//因为头节点中没有数据,所以应该从头节点的下一个结点开始查找{p = p->next;}return p;
}

求表长:

int GetLength(LinkList L)
{LNode* p = L; int len = 0;while (p->next != NULL){p = p->next;len++;}return len;
}

 8,单链表的建立:

8.1尾插法建立单链表

LinkList List_TailInsert(LinkList& L)
{int a = 0;L = (LinkList)malloc(sizeof(LNode));//建立头结点scanf("%d", &a);LNode* r,*s = L;//r是尾结点while (a != 9999)//结束标志{s = (LNode*)malloc(sizeof(LNode));//放入新节点s->data = a;r->next = s;//建立链表连接r = s;//新的尾结点scanf("%d", &a);//循环输入数字}r->next = NULL;return L;}

8.2头插法建立单链表

LinkList List_HeadInsert(LinkList& L)
{int a = 0;LNode* s;L = (LinkList)malloc(sizeof(LNode));//建立头结点L->next = NULL;//初始化单链表,以防有脏数据scanf("%d", &a);while (a != 9999)//结束标志{s = (LNode*)malloc(sizeof(LNode));//放入新节点s->data = a;s->next= L->next;//建立链表连接L->next = s;//新的尾结点scanf("%d", &a);//循环输入数字}return L;}

 尾插法元素排列为顺序,头插法元素排列为逆序,头插法可以用于链表的逆置

9,双链表(带头结点):

9.1定义:

typedef struct DNode {int data;struct DNode *prior,* next;
}DNode,*DLinkList;
bool InitDLinkList(DLinkList &L)
{L = (DNode*)malloc(sizeof(DNode));//分配头结点if (L == NULL)return false;L->prior = NULL;//头结点的前驱节点都为NULL;L->next = NULL;return true;
}
int main()
{DLinkList L;InitDLinkList(L);}

9.2插入操作(在p结点后插入s结点)

bool InsertNextDNode(DNode* p, DNode* s)
{if (p == NULL && s == NULL)return false;s->next = p->next;if (p->next != NULL)//p有后继节点p->next->prior = s;//则后继节点的前继指针指向ss->prior = p;p->next = s;return true;
}

9.3删除操作(删除p结点的后继节点):

bool DeleteNextDNode(DNode* p)
{if (p == NULL)return false;DNode* q = p->next;if (q == NULL)return false;//没有后继节点p->next = q->next;if (q->next != NULL)//后继结点不为最后一个结点q->next->prior = p;//则后继节点的前继指针为sfree(q);return true;
}

9.4销毁双链表:

void DestoryList(DLinkList &L)//L代表的是链表的头指针
{while (L->next != NULL){DeleteNextDNode(L);//从表头开始删除}free(L);//释放头结点L = NULL;//头指针指向NULL
}

9.5遍历:

向后遍历:

while(p!=NULL)
{
p=p->next;
}

向前遍历(跳过头结点):

while(p->prior!=NULL)
{
p=p->prior;}

 

10,循环链表:

10.1循环单链表

定义:

typedef struct LNode {int data;struct LNode* next;
}LNode,*LinkList;//初始化相同
bool InitList(LinkList& L)
{L = (LNode*)malloc(sizeof(LNode));//定义头结点if (L == NULL)//空间分配失败return false;L->next = L;//头指针只向自己return true;
}
bool IsEmpty(LinkList L)
{if (L->next == L)return true;elsereturn false;
}
bool IsTail(LinkList L,LNode *p)//判断p结点是否为尾结点
{if (p->next == L)return true;elsereturn false;
}

从一个结点出发,不同于单链表只能找到后续的各个节点,循环单链表可以找到其他任何一个结点 

10.2循环双链表:

初始化:

判断是否为空是否是表尾结点与循环单链表相同,初始化与双链表不同的是:

L->prior=L;
L->next=L;

插入后继结点:

bool InsertNextDNode(DNode* p, DNode* s)
{s->next = p->next;p->next->prior = s;//双链表需要判断是否是最后一个结点,循环双链表不需要s->prior = p;p->next = s;return true;
}

删除后继结点:

void DeleteNextDNode(DNode* p)
{p->next = q->next;q->next->prior = p;//双链表需要判断是否是最后一个结点,循环双链表不需要free(q);}

11,静态链表:用数组的方式实现链表

初始化:

#define MaxSize 10
typedef struct{
int data;
int next;
}SLinkList[MaxSize];
int main(){
SLinkList a;}

12,顺序表与链表的比较 

相关文章:

数据结构---线性表

1&#xff0c;顺序表实现---动态分配 #include<stdlib.h> #define InitSize 10 typedef struct {int *data;//静态分配int length;int MaxSize; }SqList; void InitList(SqList& L) {L.data (int*)malloc(InitSize * sizeof(int));//分配空间L.length 0;L.MaxSize…...

MySQL 8.0 字符集问题导致报错

报错&#xff1a; ### Error querying database. Cause: java.sql.SQLException: Illegal mix of collations (utf8_general_ci,IMPLICIT) and (utf8mb4_0900_ai_ci,COERCIBLE) MySQL 8.0引入了一些新的字符集和排序规则&#xff0c;并对现有的进行了改进。在MySQL 8.0中&#…...

单路高清HDMI编码器JR-3211HD

产品简介&#xff1a; JR-3211HD单路高清HDMI编码器是专业的高清音视频编码产品&#xff0c;该产品具有支持1路高清HDMI音视频采集功能&#xff0c; 1路3.5MM独立外接音频输入&#xff0c;编码输出双码流H.264格式&#xff0c;音频MP3/AAC格式。编码码率可调&#xff0c;画面质…...

分库,分表,分区,分片

MySQL&#xff1a; 是一个开源的关系型数据库管理系统&#xff0c;主要用于存储和管理数据。它提供了命令行接口&#xff0c; SQLyog&#xff1a; 是一个图形化的客户端软件&#xff0c;专门用于管理和操作MySQL数据库。 它提供了一个直观的用户界面&#xff0c;简化了MySQL数据…...

【详解算法流程+程序】DBSCAN基于密度的聚类算法+源码-用K-means和DBSCAN算法对银行数据进行聚类并完成用户画像数据分析课设源码资料包

DBSCAN(Density-Based Spatial Clustering of Applications with Noise)是一个比较有代表性的基于密度的聚类算法。 与划分和层次聚类方法不同&#xff0c;它将簇定义为密度相连的点的最大集合&#xff0c;能够把具有足够高密度的区域划分为簇&#xff0c; 并可在噪声的空间数据…...

java es相关操作

一.es 后期修改分片数量 在Elasticsearch中一旦索引创建后&#xff0c;分片的数量就不能直接更改。如果需要更改分片的数量&#xff0c;你需要按照以下步骤操作&#xff1a; 创建一个新的索引&#xff0c;并指定所需的分片数量。 将旧索引的数据复制到新索引中。 关闭旧索引…...

腾讯EdgeOne产品测评体验——开启安全防护,保障数据无忧

当今时代数字化经济蓬勃发展人们的生活逐渐便利&#xff0c;类似线上购物、线上娱乐、线上会议等数字化的服务如雨后春笋般在全国遍地生长&#xff0c;在人们享受这些服务的同时也面临着各式各样的挑战&#xff0c;如网络数据会不稳定、个人隐私容易暴露、资产信息会被攻击等。…...

机器视觉图形处理软件介绍

机器视觉图形处理软件介绍 一.VisionPro 康耐视公司推出的 系统&#xff0c;具有快速而强大的应用系统开发能力。可快速建立原型和易于集成 。具有高可靠性、硬件灵活性。VisionPro 提供了易于应用的原型、发展和应用。VisionProQuickStart 原型环境加速了强大机器视觉系统的…...

C# WinForm简介

Winform是什么? .Net开发平台中对Windows Form的简称&#xff0c;基于.Net Framework平台 的客户端开发技术&#xff0c;一般使用C#编程。Windows 风格的控件&#xff0c;以及事件&#xff0c;直接使用&#xff0c;开发快速。Windows Form&#xff1a;Windows窗体Windows应用程…...

概念:CPU、内存、磁盘、Android内存分配

cpu CPU的全称是Central Processing Unit&#xff0c;中文名称为中央处理单元。它是计算机硬件的核心部件&#xff0c;负责解释计算机程序指令并处理计算机软件中的数据。简言之&#xff0c;CPU执行计算机程序中的操作指令&#xff0c;包括基本算术、逻辑、控制和输入/输出&am…...

Vue 图片加载失败显示默认图片

方法一&#xff1a;通过onerror属性加载默认图片 <img :src"img" :onerror"defaultImg" /><script> export default {data() {return {img: , // 访问图片的ip地址defaultImg: this.src ${require(/assets/images/right/default-person.png)…...

【Sentinel的限流使用】⭐️SpringBoot整合Sentinel实现Api的限流

目录 前言 一、Sentinel下载 二、SpringBoot 整合 Sentinel 三、流控规则 章末 前言 小伙伴们大家好&#xff0c;上次使用OpenFeign时用到了 Hystrix实现熔断和限流的功能&#xff0c;但是发现该工具已经停止维护了&#xff0c;于是想到了Spring Cloud Alibaba开发的Sentin…...

【示例】MySQL-SQL语句优化

前言 本文主要讲述不同SQL语句的优化策略。 SQL | DML语句 insert语句 插入数据的时候&#xff0c;改为批量插入 插入数据的时候&#xff0c;按照主键顺序插入 大批量插入数据的时候&#xff08;百万&#xff09;&#xff0c;用load指令&#xff0c;从本地文件载入&#x…...

QT 线程的使用

1.头文件&#xff1a; #include<QThread> 2.在.h文件中定义全局&#xff1a; QThread* threadTraj; void threadTrajProcess();//回调函数 3.在.cpp文件中&#xff1a; threadTraj new QThread();//初始化 //连接槽函数 QObject::connect(threadTraj, &QThre…...

Python基于flask的豆瓣电影分析可视化系统

博主介绍&#xff1a;✌程序员徐师兄、7年大厂程序员经历。全网粉丝12w、csdn博客专家、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ &#x1f345;文末获取源码联系&#x1f345; &#x1f447;&#x1f3fb; 精彩专栏推荐订阅&#x1f447;…...

【迅为iTOP-4412-linux 系统制作(4)】ADB 或者 TF 卡烧写测试

准备工作 编译生成的内核镜像uImage 和设备树 dtb 文件“exynos4412-itop-elite.dtb”已经可以使用了。 把编译生成的uimage和dtb文件。拷贝fastboot工具。官方的u-boot-iTOP-4412.bin 也拷贝到 platform-tools 文件夹目录内。system.img 也拷贝到 platform-tools 文件夹目录…...

阿里云对象存储OSS批量上传,单个上传,批量删除,单个删除!

请自行替换秘钥&#xff1a; #阿里云 OSS src/main/resources/application.properties #不同的服务器&#xff0c;地址不同 aliyun.oss.file.endpointhttps://oss-cn-hangzhou.aliyuncs.com aliyun.oss.file.accessKeyIdLTAI5t9wUqCoD42qPGRy8S aliyun.oss.file.accessKeySecre…...

Python的国际化和本地化【第162篇—国际化和本地化】

&#x1f47d;发现宝藏 前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。【点击进入巨牛的人工智能学习网站】。 随着全球化的发展&#xff0c;多语言支持在软件开发中变得越来越重要。Python作为一种流行的…...

播放Samba协议下的音视频文件

Samba&#xff08;也被称为SMB/CIFS&#xff09;是一个用于在局域网内共享文件和打印服务的协议&#xff0c;广泛应用于Windows和Linux系统之间的文件共享。 一、展示Samba服务器下的文件 使用如jcifs这样的Java库来在安卓应用中集成SMB/CIFS客户端功能。这个库提供了与SMB/CI…...

Excel全套213集教程

Excel全套213集教程 包含技术入门93集 图表17集 数据透视35集 公式函数68 基础入门 93节 https://www.alipan.com/s/cMxuPstkS1x 提取码: 77dd 点击链接保存&#xff0c;或者复制本段内容&#xff0c;打开「阿里云盘」APP &#xff0c;无需下载极速在线查看&#xff0c;视…...

【七 (1)指标体系建设-构建高效的故障管理指标体系】

目录 文章导航一、故障概述1、故障&#xff1a;2、故障管理&#xff1a; 二、指标体系概述1、指标2、指标体系 三、指标体系构建难点1、管理视角2、业务视角3、技术视角 四、指标体系构建原则1、与战略目标对齐2、综合和平衡3、数据可获得性4、可操作性5、具体和可衡量6、参与和…...

Go gin框架(详细版)

目录 0. 为什么会有Go 1. 环境搭建 2. 单-请求&&返回-样例 3. RESTful API 3.1 首先什么是RESTful API 3.2 Gin框架支持RESTful API的开发 4. 返回前端代码 go.main index.html 5. 添加静态文件 main.go 改动的地方 index.html 改动的地方 style.css 改动…...

Git分布式版本控制系统——Git常用命令(二)

五、Git常用命令————分支操作 同一个仓库可以有多个分支&#xff0c;各个分支相互独立&#xff0c;互不干扰 分支的相关命令&#xff0c;具体如下&#xff1a; git branch 查看分支 git branch [name] 创建分支&#x…...

LeetCode 59.螺旋矩阵II

LeetCode 59.螺旋矩阵II 1、题目 力扣题目链接&#xff1a;59. 螺旋矩阵 II - 力扣&#xff08;LeetCode&#xff09; 给你一个正整数 n &#xff0c;生成一个包含 1 到 n2 所有元素&#xff0c;且元素按顺时针顺序螺旋排列的 n x n 正方形矩阵 matrix 。 示例 1&#xff1…...

03-JAVA设计模式-适配器模式

适配器模式 设么是适配器模式 它属于结构型模式&#xff0c;主要用于将一个类的接口转换成客户端所期望的另一种接口&#xff0c;从而使得原本由于接口不兼容而无法协同工作的类能够一起工作。 适配器模式主要解决的是不兼容接口的问题。在软件开发中&#xff0c;经常会有这…...

MVVM架构模式

目录 MVVM 数据绑定方式 实现方式 Model View ViewModel 数据绑定方式 vue&#xff1a;&#xff1a; 数据劫持和发布-订阅模式&#xff1a; Object.defineProperty() 方法来劫持&#xff08;监控&#xff09;各属性的 getter 、setter &#xff0c;并在数据&#xff08;对…...

leetcode2924--找到冠军II

1. 题意 给定一个有向无环图&#xff0c;方向表示胜负关系&#xff1b;求最后胜出的人。 2. 题解 将所有人标记为胜者&#xff0c;统计出度去掉对应胜者标记&#xff1b; 最后统计胜者数目&#xff0c;是否大于1&#xff0c;若大于1&#xff0c;则没有胜者&#xff0c;否则…...

嵌入式|蓝桥杯STM32G431(HAL库开发)——CT117E学习笔记13:RTC实时时钟

系列文章目录 嵌入式|蓝桥杯STM32G431&#xff08;HAL库开发&#xff09;——CT117E学习笔记01&#xff1a;赛事介绍与硬件平台 嵌入式|蓝桥杯STM32G431&#xff08;HAL库开发&#xff09;——CT117E学习笔记02&#xff1a;开发环境安装 嵌入式|蓝桥杯STM32G431&#xff08;…...

统一用安卓Studio修改项目包名

可以逃跑&#xff0c;可以哭泣&#xff0c;但不可以放弃 --《鬼灭之刃》 修改项目包名 1&#xff09;选中项目中药修改的包名&#xff1a; 2)目结构显示方式&#xff0c;取消 Compact Middle Packages 选项&#xff1b; 3)右键要修改的包名&#xff0c;选择 Refactor —— Re…...

Spring Cloud Gateway详细介绍以及实现动态路由

一. 简介 Spring Cloud Gateway This project provides a libraries for building an API Gateway on top of Spring WebFlux or Spring WebMVC. Spring Cloud Gateway aims to provide a simple, yet effective way to route to APIs and provide cross cutting concerns to …...