数据结构(顺序表和链表)

作者:泡泡鱼(敲代码中)日期:2025/10/21

数据结构(题)

一、顺序表

1、移除元素

1int removeElement(int* nums, int numsSize, int val) {
2    int dst = 0;
3    int src = 0;
4    while(src<numsSize)
5    {
6        if(nums[src]!=val)
7        {
8            nums[dst]=nums[src];
9            dst++;
10        }
11        src++;
12    }
13    return dst;
14}

2、删除有序数组中的重复项

3、合并两个有序数组

1void merge(int* nums1, int nums1Size, int m, int* nums2, int nums2Size, int n) {
2    int i=m-1;
3    int j=n-1;
4    int index=m+n-1;
5    while(i>=0&&j>=0)
6    {
7        if(nums2[j]>nums1[i])
8        {
9            nums1[index]=nums2[j];
10            j--;
11            index--;
12        }
13        else{
14            nums1[index]=nums1[i];
15            i--;index--;
16        }
17    }
18    while(j>=0)
19    {
20        nums1[index--]=nums2[j--];
21    }
22}
23

二、链表

1、移除链表元素

思路1:遍历、查找、删除

思路2:再创建一个新的链表,把节点不为val的节点放入新链表

2、反转链表

思路1:新建一个链表,将原链表中的节点插入新的链表中

思路2:

1/**
2 * Definition for singly-linked list.
3 * struct ListNode {
4 *     int val;
5 *     struct ListNode *next;
6 * };
7 */
8typedef struct ListNode ListNode;
9struct ListNode* reverseList(struct ListNode* head) {
10    if(head==NULL)
11    {
12        return head;
13    }
14    ListNode* n1,*n2,*n3;
15    n1=NULL;
16    n2=head;
17    n3=n2->next;
18    while(n2)
19    {
20        n2->next=n1;
21        n1=n2;
22        n2=n3;
23        if(n3)
24            n3=n3->next;
25    }
26    return n1;
27}
28

3、链表的中间结点

1/**
2 * Definition for singly-linked list.
3 * struct ListNode {
4 *     int val;
5 *     struct ListNode *next;
6 * };
7 */
8 typedef struct ListNode ListNode;
9struct ListNode* middleNode(struct ListNode* head) {
10    ListNode* slow=head;
11    ListNode* fast=head;
12    while(fast&&fast->next)
13    {
14        slow=slow->next;
15        fast=fast->next->next;
16    }
17    return slow;
18}

4、合并两个有序链表

思路1:比较两个链表,哪个小把哪个放入新的链表中

需要注意的两点是:① l1和l2是否为空②新链表是否为空

思路2:

申请一个哨兵位(占位子)

可以优化代码(一直要判断链表是否为空)

1/**
2 * Definition for singly-linked list.
3 * struct ListNode {
4 *     int val;
5 *     struct ListNode *next;
6 * };
7 */
8typedef struct ListNode ListNode;
9struct ListNode* mergeTwoLists(struct ListNode* list1, struct ListNode* list2) {
10    ListNode* newHead,*newTail;
11    newHead=newTail=(ListNode*)malloc(sizeof(ListNode));
12    ListNode* l1=list1;
13    ListNode* l2=list2;
14    if(l1==NULL)
15    {
16        return list2;
17    }
18    if(l2==NULL)
19    {
20        return list1;
21    }
22    while(l1&&l2)
23    {
24        if(l1->val<l2->val)
25        {
26            newTail->next=l1;
27            newTail=newTail->next;
28            l1=l1->next;
29        }
30        else{
31            newTail->next=l2;
32            newTail=newTail->next;
33            l2=l2->next;
34        }
35    }
36    //l1走到空和l2走到空
37    if(l1)
38    {
39        newTail->next=l1;
40    }
41    if(l2)
42    {
43        newTail->next=l2;
44    }
45    ListNode* pcur=newHead->next;
46    free(newHead);
47    newHead=NULL;
48    return pcur;
49}
50

5、链表分割

1/*
2struct ListNode {
3    int val;
4    struct ListNode *next;
5    ListNode(int x) : val(x), next(NULL) {}
6};*/
7class Partition {
8public:
9    ListNode* partition(ListNode* pHead, int x) {
10        ListNode* lessHed,*lessTail;
11        lessHed=lessTail=(ListNode*)malloc(sizeof(ListNode));
12        ListNode* GreateHead,*GreatTail;
13        GreateHead=GreatTail=(ListNode*)malloc(sizeof(ListNode));
14        ListNode* pcur = pHead;
15        while(pcur)
16        {
17            if(pcur->val<x)
18            {
19                lessTail->next=pcur;
20                lessTail=lessTail->next;
21            }
22            else{
23                GreatTail->next=pcur;
24                GreatTail=GreatTail->next;
25            }
26            pcur=pcur->next;
27        }
28        GreatTail->next=NULL;
29        //将大小链表首尾相连
30        lessTail->next=GreateHead->next;
31        ListNode* retHead=lessHed->next;
32        free(lessHed);
33        free(GreateHead);
34        lessHed=GreateHead=NULL;
35
36        return retHead;
37    }
38};

6、链表的回文结构

思路1:创建新的链表,将原链表反转的结果保存在新链表中,遍历新旧链表比较

思路2:创建新数组,保存链表中所有节点的值,判断数组是否为回文结构

1/*
2struct ListNode {
3    int val;
4    struct ListNode *next;
5    ListNode(int x) : val(x), next(NULL) {}
6};*/
7class PalindromeList {
8public:
9    bool chkPalindrome(ListNode* A) {
10        int arr[900]={0};
11        int i=0;
12        ListNode* pcur=A;
13        while(pcur)
14        {
15            arr[i++]=pcur->val;
16            pcur=pcur->next;
17        }
18        int left =0;
19        int right=i-1;
20        while(left<right)
21        {
22             if(arr[left]!=arr[right])
23            {
24                return false;;
25            }
26            left++;
27            right--;
28        }
29        return true;
30    }
31};

上述解法只能适用于给定长度的链表题中!!!

思路3:

1/*
2struct ListNode {
3    int val;
4    struct ListNode *next;
5    ListNode(int x) : val(x), next(NULL) {}
6};*/
7class PalindromeList {
8  public:
9    struct ListNode* middleNode(struct ListNode* head) {
10        ListNode* slow = head;
11        ListNode* fast = head;
12        while (fast && fast->next) {
13            slow = slow->next;
14            fast = fast->next->next;
15        }
16        return slow;
17    }
18    struct ListNode* reverseList(struct ListNode* head) {
19        if (head == NULL) {
20            return head;
21        }
22        ListNode* n1, *n2, *n3;
23        n1 = NULL;
24        n2 = head;
25        n3 = n2->next;
26        while (n2) {
27            n2->next = n1;
28            n1 = n2;
29            n2 = n3;
30            if (n3)
31                n3 = n3->next;
32        }
33        return n1;
34    }
35    bool chkPalindrome(ListNode* A) {
36        ListNode* mid=middleNode(A);
37        ListNode* right=reverseList(mid);
38        ListNode* left =A;
39        while(right)
40        {
41            if(left->val!=right->val)
42            {
43                return false;
44            }
45            left=left->next;
46            right=right->next;
47        }
48        return true;
49    }
50};
51

7、相交链表

1/**
2 * Definition for singly-linked list.
3 * struct ListNode {
4 *     int val;
5 *     struct ListNode *next;
6 * };
7 */
8 typedef struct ListNode ListNode;
9struct ListNode *getIntersectionNode(struct ListNode *headA, struct ListNode *headB) {
10    ListNode* pa=headA;
11    ListNode* pb=headB;
12    int SizeA=0;
13    int SizeB=0;
14    //统计两个链表的大小
15    while(pa)
16    {
17        SizeA++;
18        pa=pa->next;
19    }
20    while(pb)
21    {
22        SizeB++;
23        pb=pb->next;
24    }
25    int gap=abs(SizeA-SizeB);//绝对值,差值
26    //让长链表先走gap步
27    ListNode* longSize=headB;
28    ListNode* shortSize=headA;
29    if(SizeA>SizeB)
30    {
31        longSize =headA;
32        shortSize=headB;
33    }
34    while(gap--)
35    {
36        longSize=longSize->next;
37    }
38    //找相等的节点
39    while(shortSize)
40    {
41        if(longSize==shortSize)//相等的话这个节点已经是相交的节点了
42        {
43            return shortSize;
44        }
45        shortSize=shortSize->next;
46        longSize=longSize->next;
47    }
48    return NULL;
49}
50

8、环形链表

快慢指针,如果slow和fast最开始都指向head,slow走一步,fast走两步,如果slow和fast有相交则有环。

1/**
2 * Definition for singly-linked list.
3 * struct ListNode {
4 *     int val;
5 *     struct ListNode *next;
6 * };
7 */
8typedef struct ListNode ListNode;
9bool hasCycle(struct ListNode *head) {
10    ListNode* slow=head;
11    ListNode* fast=head;
12    while(fast&&fast->next)
13    {
14        slow=slow->next;
15        fast=fast->next->next;
16        if(fast==slow)
17            return true;
18    }
19    return false;
20}

9、环形链表(2)

目标:找出入环的第一个节点

快慢指针:相遇点到入环起始节点的距离==链表头节点到入环起点的距离。

①循环找到slow和fast的相遇点

②再创建一个节点,从head开始,pcur和slow指针一起遍历,如果相同,则找到入环第一个节点。

1/**
2 * Definition for singly-linked list.
3 * struct ListNode {
4 *     int val;
5 *     struct ListNode *next;
6 * };
7 */
8typedef struct ListNode ListNode;
9struct ListNode* detectCycle(struct ListNode* head) {
10    ListNode* fast = head;
11    ListNode* slow = head;
12    while (fast && fast->next) {
13        slow = slow->next;
14        fast = fast->next->next;
15        if (slow == fast) {
16            ListNode* pcur = head;
17            while (pcur != slow) {
18                slow = slow->next;
19                pcur = pcur->next;
20            }
21            return pcur;
22        }
23    }
24    return NULL;
25}

10、随即表的复制

目标:复制原链表的指针,但都不指向原链表,如下例子,要得到的链表:

思路:

①拷贝节点

②重置random指针

copy->random=pcur->random->next

③断开新旧链表

1/**
2 * Definition for a Node.
3 * struct Node {
4 *     int val;
5 *     struct Node *next;
6 *     struct Node *random;
7 * };
8 */
9typedef struct Node Node;
10Node* buyNode(int x) {
11    Node* node = (Node*)malloc(sizeof(Node));
12    node->val = x;
13    node->next = node->random = NULL;
14    return node;
15}
16void AddNode(Node* head) {
17    Node* pcur = head;
18    while (pcur) {
19        Node* next = pcur->next;
20        Node* newnode = buyNode(pcur->val);
21        newnode->next = next;
22        pcur->next = newnode;
23        pcur = next;
24    }
25}
26void setRandom(Node* head) {
27    Node* pcur = head;
28    while (pcur) {
29        Node* copy = pcur->next;
30        if (pcur->random)
31            copy->random = pcur->random->next;
32        pcur = copy->next;
33    }
34}
35struct Node* copyRandomList(struct Node* head) {
36    if (head == NULL) {
37        return head;
38    }
39    AddNode(head);
40    setRandom(head);
41    Node* pcur = head;
42    Node *newHead, *newTail;
43    newHead = newTail = pcur->next;
44    while (newTail->next) {
45        pcur = newTail->next;
46        newTail->next = pcur->next;
47        newTail = newTail->next;
48    }
49    return newHead;
50}

数据结构(顺序表和链表)》 是转载文章,点击查看原文


相关推荐


运放的 Input Offset Drift(输入失调漂移)
Heismk2025/10/19

Input Offset Drift(输入失调漂移)是衡量运算放大器(或其他精密放大器件)性能的关键指标,用于描述温度变化时输入失调电压的变化率,直接反映器件在温度波动环境下的稳定性。 核心定义 输入失调漂移指的是:当环境温度每变化 1℃ 时,运放的**输入失调电压(Input Offset Voltage)**所发生的变化量,单位通常为 μV/℃(微伏每摄氏度)或 nV/℃(纳伏每摄氏度)。 输入失调电压(Vos):理想运放输入短路时输出应为 0,但实际器件因内部工艺差异,需在输入端施加一个微


Compose 自定义布局和图形
Best_Jerry2025/10/18

Advanced layout concepts - MAD Skills Compose 提供各种开箱即用型解决方案,可帮助您快速轻松地从头开始构建界面。但是,如果您需要更进一步,以实现完全自定义的界面,该怎么办?详细了解高级布局概念,以便自行构建自定义布局,让您的设计实现更上一层楼。 1. Advanced Layout Concepts Layout 这一术语在 Compose 中有多种含义: 以下是每种含义的相关解释: 2. Layout phase and constraint


告别加班!这些数组操作技巧让前端开发效率翻倍
良山有风来2025/10/17

你是不是经常遇到这样的场景:产品经理扔过来一堆数据,要你快速处理展示;后端返回的数组结构复杂,需要层层筛选过滤;明明很简单的数据操作,却要写一大堆循环和判断... 别担心!今天这篇干货,就是来拯救你的。我将带你系统掌握JavaScript数组和对象的核心操作,学完立刻就能用在实际项目中。相信我,掌握这些技巧后,你的开发效率至少提升一倍! 数组基础:从创建到遍历 让我们从最基础的数组操作开始。数组就像是一个数据容器,能帮我们有序地存放各种信息。 创建数组有两种常用方式。第一种是用方括号,这是最简洁


阿里云负载均衡SLB的使用参考:创建阿里云ECS实例操作
熙客2025/10/15

目录 一、背景知识 1.1 概念 1.2 负载均衡类型选择 1.3 核心功能与工作原理 1.4 配置负载均衡的注意事项 二、传统型负载均衡CLB的使用示例 2.1 创建3个ECS实例 2.2 安装nginx 2.3 创建负载均衡CLB 2.4 负载均衡配置 2.5 负载均衡检验 一、背景知识 1.1 概念 阿里云负载均衡能将访问流量分发到后端多台云服务器上,提升应用系统的服务能力和高可用性。它主要包含以下三种产品: 特性维度CLB(传统型负载均衡)ALB(应


NineData云原生智能数据管理平台新功能发布|2025年9月版
NineData2025/10/14

本月共发布 17 项更新,其中重点发布 6 项、功能优化 11 项。 重点发布 数据库 DevOps - SQL 任务事务执行 SQL 任务支持以事务方式执行。在 DML 语句执行失败后自动回滚整个任务,确保执行原子性与一致性。 数据库 DevOps - 数据脱敏与敏感扫描 敏感数据保护模块新增支持 PostgreSQL、SQL Server、Oracle 数据源的自动扫描与脱敏,帮助企业更全面地识别并防护敏感信息。 数据库 DevOps - ER 图增强 ER 图现


Flutter - Melos Pub workspaces 实践
LinXunFeng2025/10/13

欢迎关注微信公众号:FSA全栈行动 👋 一、前言 为解决 App 代码臃肿、编译耗时的问题,我们进行了分包重构,核心思路如下: 业务分包:将不同业务线的代码拆分成独立的包,开发者只需聚焦于各自包内的 example 工程进行开发,从而提升编译和运行效率。 功能沉淀:把跨业务复用的功能(包括基础业务和非业务功能)也抽离成独立的包,逐步让主 App 轻量化为一个“空壳”,负责集成所有模块。 依赖管理:业务包之间使用 git 依赖,指向 master 分支;而非业务的功能包则发布到自建的 unp


业务流程建模标准(BPMN)
deepdata_cn2025/10/11

在数字化转型浪潮中,企业对业务流程的可视化、标准化与自动化需求日益迫切。BPMN(Business Process Model and Notation,业务流程建模符号) 作为全球通用的业务流程建模标准,通过统一的图形语言打破了“业务人员说不清楚、IT人员看不懂”的沟通壁垒,成为连接业务需求与技术实现的核心桥梁。 一、BPMN的起源与发展 在BPMN出现前,企业建模缺乏统一规范:有的用流程图(Flowchart),有的用UML活动图,甚至有的用手绘草图——不同角色对同一流程的理解差异巨大,导致


JDK8 新特性 - Stream 流详解
chirrupy_hamal2025/10/9

文章目录 一、认识 Stream二、Stream 的常用方法1、如何获取 Stream 流2、Stream 流常见的中间方法2.3、Stream 流常见的终结方法 一、认识 Stream 二、Stream 的常用方法 1、如何获取 Stream 流 2、Stream 流常见的中间方法 代码简化 s -> s.getName() Studet::getName 代码简化 2.3、Stream 流常见的终结方法 报错


一个基于 ASP.NET Core 的开源、模块化、多租户应用框架和内容管理系统
追逐时光者2025/10/8

前言 今天大姚给大家分享一个基于 ASP.NET Core 的开源、模块化、多租户应用框架和内容管理系统:OrchardCore。 项目介绍 OrchardCore 是一个开源的(BSD-3-Clause license)、模块化的、支持多租户的应用程序框架,使用 ASP.NET Core 构建。同时,它也是一个基于该框架的内容管理系统(CMS)。 DotNetGuide编程学院 DotNetGuide编程学院是一个专注于C#/.NET/.NET Core学习、工作、面试干货和实战教程分享的知识


Python 的 UDP 编程
hubenchang05152025/10/6

#Python 的 UDP 编程 用户数据报协议(User Datagram Protocol) 是一个 无连接、非可靠 的传输层协议,和 TCP 并列,是互联网中最常见的协议之一。 UDP 程序不存在连接,只需要绑定自身地址并收发数据即可。下面是一个示例,它创建了两个 socket,从一个向另一个发送数据。 import socket # 创建 UDP socket sock1 = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) sock2

首页编辑器站点地图

本站内容在 CC BY-SA 4.0 协议下发布

Copyright © 2025 聚合阅读