首页 > 其他分享 >链表(数据结构)

链表(数据结构)

时间:2024-10-31 20:50:00浏览次数:3  
标签:结点 next 链表 pcur SL 数据结构 我们

一. 单链表

1.1 概念与结构

再上一篇中我们讲到顺序表,但是顺序表也是有很多的问题,像申请的空间过多过少或者增容该才能不浪费空间,今天我们就来认识一个新的知识,叫做链表,链表也是线性表的一种,链表是一种物理存储结构上非连续、非顺序的存储结构,数据结构的逻辑顺序是通过链表中的指针链接次序实现的。

1.2 结点

链表到底是一个怎样的存在?又是怎样通过一个个的结点将其连接在一起,说一个简单的例子,我们坐的火车是一个个车厢连接起来的,前一个车厢连接着后一个车厢,也就是说我们能从前一个车厢的位置找到后一个车厢的位置,其实链表也是如此,来一张简单的图:我们来看上面的一张图,简单点说上面的1,2,3,4就是一个个的结点,我们可以发现的是其实结点的地址不一定是连续的,但是我们可以发现每一个结点的结构总是包含着下一个结点的地址,链表中每个结点都是独立申请的(即需要插入数据时才去申请一块结点的空间),我们需要通过指针变量来保存下一个结点位置才能从当前结点找到下一个结点。所以在链表中没有增容的概念,如上图所示,所以结点是一个结构体,那这个结构体又有什么组成的呢?是数据+指向下一个结点的指针

struct ListNode
{
   int data;
   struct ListNode* next;
}

1.3 链表的性质

1、链式机构在逻辑上是连续的,在物理结构上不一定连续 2、结点一般是从堆上申请的 3、从堆上申请来的空间,是按照一定策略分配出来的,每次申请的空间可能连续,可能不连续

 所以假设当我们想要保存一个整型数据的时候,实际上是从操作系统申请一个内存空间,而这个内存空间不仅要保存当前的整型数据,还要保存下一个结点的地址,当我们想要从第⼀个结点⾛到最后⼀个结点时,只需要在当前结点拿上下⼀个结点的地址就可以了。而且对于链表来说没有增容的概念,是我们需要的时候再去申请一块空间,这就很好的处理了在顺序表中些许浪费的情况。

1.4 链表的打印

清楚了链表的结构,了解了结点的结构,现在我们可以简单的来打印一个链表,同样的方法我们创建三个文件:在我们以后的代码中,我们也尽量养成三个文件的写法,这样会使代码更清晰可见,我们的思路 也会更清晰明了。首先我们在头文件中创建我们所需要的函数声明:

在创建完头文件之后,我们就开始写测试文件和实现文件的函数:

我们先用结点创建一个链表,在打印之前我们对它进行调试,通过调试发现在每一个结点中存放在我们事先输入的数据,并且通过前一个结点可以找到后一个结点,之后我们开始写打印的代码:

 可能有同学就会对这个打印的代码产生疑惑,对此我来解释一下,在前面我们将链表的第一个结点node1传入SLprintf中,所以SL* phead就是头结点,当我们把头结点先赋值给一个新的SL*类型的变量pcur,如下图所示:

 while循环的条件是pcur不为空指针,所以我们先让pcur->data就是第一个数据1,打印完之后将pcur赋值给pcur->next,然而next的地址又是下一个结点的地址,所以我们就会打印出下一个数据,打印出来的结果就是:

完整代码:

//SList.h
//声明函数
#pragma once
#include <stdlib.h>//申请空间
#include <stdio.h>
//定义一个结点
typedef int SLDatatype;
typedef struct SLNode
{
	SLDatatype data;
	struct SLNode* next;
}SL;
//打印函数
void SLprintf(SL* phead);


//SList.c
//实现函数
#include "SList.h"
void SLprintf(SL* phead)
{
	SL* pcur = phead;
	while (pcur)
	{
		printf("%d->", pcur->data);
		pcur = pcur->next;
	}
	printf("NULL\n");
}


//test.c
//测试文件
#include "SList.h"
void CreatSList()
{
	SL* node1 = (SL*)malloc(sizeof(SL));
	node1->data = 1;
	SL* node2 = (SL*)malloc(sizeof(SL));
	node2->data = 2;
	SL* node3 = (SL*)malloc(sizeof(SL));
	node3->data = 3;
	SL* node4 = (SL*)malloc(sizeof(SL));
	node4->data = 4;

	node1->next = node2;
	node2->next = node3;
	node3->next = node4;
	node4->next = NULL;
	SLprintf(node1);
}
int main()
{
	CreatSList();
	return 0;
}




1.5 链表的分类

链表的结构非常多样,以下情况组合起来就有8种(2 x 2 x 2)链表结构:

链表说明: 

虽然有这么多的链表的结构,但是我们实际中最常用还是两种结构: 单链表和双向带头循环链表 1. 无头单向非循环链表:结构简单,一般不会单独用来存数据。实际中更多是作为其他数据结构的子结构,如哈希桶、图的邻接表等等。另外这种结构在笔试面试中出现很多。 2. 带头双向循环链表:结构最复杂,⼀般用在单独存储数据。实际中使用的链表数据结构,都是带头双向循环链表。另外这个结构虽然结构复杂,但是使用代码实现以后会发现结构会带来很多优势,实现反而简单了,后面我们代码实现了就知道了。

 在这一篇简单的讲解了单链表的简单结构组织,知道了怎样去写一个简单的单链表,在下一篇中我们会增加难度,用单链表实现数据的删减、增加、插入等,并且练习解释一些单链表的算法题,使知识更加的牢固。

标签:结点,next,链表,pcur,SL,数据结构,我们
From: https://blog.csdn.net/OKkankan/article/details/143329265

相关文章

  • Leetcode21:合并两个有效链表
    原题地址:.-力扣(LeetCode)题目描述将两个升序链表合并为一个新的 升序 链表并返回。新链表是通过拼接给定的两个链表的所有节点组成的。 示例1:输入:l1=[1,2,4],l2=[1,3,4]输出:[1,1,2,3,4,4]示例2:输入:l1=[],l2=[]输出:[]示例3:输入:l1=[],l2=......
  • Python常用数据结构
    1.列表(List)列表是Python中最灵活的数据结构之一,像个能装万物的大箱子。你可以把任何类型的对象放进来,甚至可以把列表放进列表里,真是个魔法箱!功能特性:可变:你可以随时增加、删除、修改列表中的元素。有序:元素按插入顺序排列创建和基本操作:#创建一个空列表my_list=[]......
  • 相交链表
    两个链表的第一个公共结点(相交链表)题目链接:牛客||LeetCode160描述输入两个无环的单向链表,找出它们的第一个公共结点,如果没有公共节点则返回空。(注意因为传入数据是链表,所以错误测试数据的提示是用其他方式显示的,保证传入数据是正确的)例如,输入{1,2,3},{4,5},{6,7}时,两个无......
  • 代码随想录之链表刷题总结
    目录1.链表理论基础2.移除链表元素3.设计链表4.翻转链表5.两两交换链表中的节点6.删除链表中的第N个节点7.链表相交8.环形链表1.链表理论基础链表是一种通过指针串联在一起的线性结构,每一个节点由两部分组成,一个是数据域一个是指针域(存放指向下一个节点的指针),最后......
  • 《链表篇》---两两交换链表中的节点(中等)
    题目传送门1.定义一个虚拟节点链接链表2.定义一个当前节点指向虚拟节点3.在当前节点的下一个节点和下下一个节点都不为null的情况下。定义node1和node2。保存当前节点后面两个节点的地址。cur.next=node2;node1.next=node2.next;node2.next=node1;cur=node1;4.......
  • 《链表篇》---删除链表的倒数第N个节点(中等)
    题目传送门 方法一:计算链表长度(迭代)1.计算链表长度,并且定义哑节点链接链表。2.从哑节点开始前进length-n次。即为被删除节点的前置节点。3.进行删除操作。4.返回哑节点的后置节点classSolution{publicListNoderemoveNthFromEnd(ListNodehead,intn){......
  • 数据结构 - 散列表,三探之代码实现
    相信通过前面两章对散列表的学习,大家应该已经掌握了散列表的基础知识,今天我们就选用简单的取模方式构建散列函数,分别实现链式法和开放寻址法中的线性探测法来解决碰撞问题,而再散列法则以方法的形式分别在两种实现方法中实现。01、链式法实现1、元素定义通过前面链式......
  • LUOGU_进阶数据结构
    LUOGU_进阶数据结构二叉堆P10977CuttheSequence:因为DP的值是单调递增的,所以可能的决策点只有最远的合法位置与那些后缀最大值段的左端点,用单调队列+可删除堆(懒标记)做。如果\(\exista<0\),怎么做?CDQ优化DP,可以做!!并查集P10350ModernizacjaBajtocji:把二选一的居民放进一......
  • 【数据结构多彩画卷】不要只会普通的二叉树了 , 你听说过用二叉树来排序吗? 【二叉搜索
    本篇会加入个人的所谓鱼式疯言❤️❤️❤️鱼式疯言:❤️❤️❤️此疯言非彼疯言而是理解过并总结出来通俗易懂的大白话,小编会尽可能的在每个概念后插入鱼式疯言,帮助大家理解的.......
  • 数据结构之你就背吧!(更新中)
    数据的逻辑结构在存储器中的映象有哪几种方法?顺序映象非顺序映象算法的性质及解释?有穷性:步骤或规则是有限的,在有穷步后结束。确定性:每条规则或指令无二义性;算法执行路径唯一(相同输入只能得到相同输出)。可行性:每个计算步骤能在有限时间内完成。输入:有一个或多个外部输......