网站的建设思想,做网站横幅的图片,办公室装修设计软件,网站开发与黑客#x1f451;专栏内容#xff1a;数据结构⛪个人主页#xff1a;子夜的星的主页#x1f495;座右铭#xff1a;日拱一卒#xff0c;功不唐捐 文章目录一、前言二、链表1、定义2、单链表Ⅰ、新建一个节点Ⅱ、内存泄漏Ⅲ、插入一个节点Ⅳ、销毁所有节点Ⅴ、反转一个链表3、… 专栏内容数据结构⛪个人主页子夜的星的主页座右铭日拱一卒功不唐捐 文章目录一、前言二、链表1、定义2、单链表Ⅰ、新建一个节点Ⅱ、内存泄漏Ⅲ、插入一个节点Ⅳ、销毁所有节点Ⅴ、反转一个链表3、双向链表4、循环链表Ⅰ、单向循环链表Ⅱ、双向循环链表Ⅲ、循环链表总结Ⅳ、一些OJ题①、环形链表②、快乐数三、总结1、区别2、优点3、缺点一、前言
前面介绍了线性结构中的顺序表顺序表的随机访问速度非常快但是它最大的缺点就是插入和删除的时候要移动大量元素。而链表这一数据结构就能完美的解决这一问题。那么链表是如何解决的呢 二、链表
1、定义
链表是一种链式存取的数据结构用一组地址任意的存储单元存放线性表中的数据元素。链表中的数据是以结点来表示的每个结点的构成元素(数据元素的映象) 指针(指示后继元素存储位置)元素就是存储数据的存储单元指针就是连接每个结点的地址数据。
由于是分散存储为了能够体现出数据元素之间的逻辑关系每个数据元素在存储的同时要配备一个指针用于指向它的直接后继元素即每一个数据元素都指向下一个数据元素最后一个指向NULL(空)。 链表中每个元素本身由两部分组成 ● 数据域存放数据。 ● 指针域存放指向后继结点的地址 链表的第一个结点被称为头节点
正因为如此我们只需要记住链表中的头节点就行顺着头节点这个藤逐渐的可以找到链表中其他所有的节点。 typedef struct LinkNode {int data;//数据域struct LinkNode *next;//指针域
}Node;2、单链表
单链表顾名思义。链表指向的只有一个方向。 Ⅰ、新建一个节点
Node *getNewNode(int val) {Node *p (Node *)malloc(sizeof(Node)); //1p-data val; //2p-next NULL; //3return p; //4
}1开辟一个空间用来存储新的节点 2将新建节点的数据放入数据域中 3将新节点的指针域置为 NULL 4返回新建的节点
Ⅱ、内存泄漏
在进行插入操作之前先搞明白一个概念那就是内存泄露。
内存泄漏由于疏忽或错误造成程序未能释放已经不再使用的内存。 就拿链表来看我们知道的只有程序内部的头地址依据头地址中存储的下一个链表的地址来找到下一个链表从而拔出萝卜带出泥找到所有的链表。但是试想一下加入我们在操作的过程中不小心把其中一个链表的地址弄丢了呢 就像这样因为错误的插入导致弄丢了②和③的地址导致②和③这两个链表数据在内存内部中无法被找到也无法被清理。 Ⅲ、插入一个节点
如下图我们想在①和②中间插入④或者这样说将④插入链表的2号位置应该怎么操作呢 首先当然应该让p指针走向2号位置的前一个位置也就是1号位置处。
然后很多人就会犯这样的错误
p-next node; //1
node -next p-next ; //2这样看似没有问题但是仔细看一下在执行完1后p-next已经不是②的地址了。你再执行2其实是将node-next指向node自己。 这样就造成了前文说的内存泄漏也就是说②和③从此就会一直呆在你的内存里面你调用不了也销毁不了这两个链表。所以我们插入结点时一定要注意操作的顺序要先将结点 node 的 next 指针指向下一个节点地址再把结点 ① 的 next指针指向结点node这样才不会丢失指针导致内存泄漏。所以对于刚刚的插入代码我们只需要把第 1 行和第 2 行代码的顺序颠倒一下就可以了。
Node *insert(Node *head,int pos ,int val) //1
{if(pos 0) //2{Node *p getNewNode (val);p-next head;return p;}Node *p head; for(int i 1;ipos;i) p p-next; //3Node *node getNewNode(val); //4node -next p-next ; //5p-next node; //6return head;
}1pos是要插入的位置 2pos等于0就是放在头地址处 3让p指针走向待插入位置的前一个位置 4创建一个要插入的节点 5先让新建节点的指针指向待原本插入位置的节点地址 6让待前一个位置的指针指向新建要插入的节点
上面的代码自然能够很好的完成插入操作但是这样代码写起来就会很繁琐而且也容易出错。如何来更好的解决这个问题呢仔细看下上面的插入操作代码较长的原因主要是怕插入的位置是头位置。所以我们要对这一情况进行特殊处理。但是如果我们建立一个虚拟的头节点呢这样不就可以解决找个问题了吗
Node *insert(Node *head,int pos ,int val)
{Node new_head,*p new_head; //1Node *node getNewNode(val); new_head.next head //2for(int i0;ipos;i) p p-next; //3node-next p-next; //3p-next node;//3return new_head.next; //4
}1新建一个虚拟的头节点 2让虚拟头节点的指针指向真实的头地址 3进行插入操作 4返回虚拟头节点的指向的地址也就是真实的头地址 Ⅳ、销毁所有节点
注意销毁所有的节点不能直接free(head)因为你如果直接释放了头节点那么你根本找不到后面其他节点。 所以应该新建一个指针指向要销毁节点的下一个节点再不断的更新这个指针指向的位置依次销毁所有节点。切记万万不可只销毁头节点。
void clear(Node *head) {if (head NULL) return ;for (Node *p head, *q; p; p q) //1{q p-next; //1free(p); //2}return ;
}1循环不断更新p指针指向的节点位置 2销毁节点
Ⅴ、反转一个链表
给你单链表的头节点 head 请你反转链表并返回反转后的链表。 常规解法 struct ListNode* reverseList(struct ListNode* head) {struct ListNode new_head,*p head,*q;new_head.next NULL;while(p){q p-next;p-next new_head.next;new_head.next p;pq;}return new_head.next;}递归解法 struct ListNode* reverseList(struct ListNode* head) {if(head NULL||head-next NULL)return head;struct ListNode *tail head-next;struct ListNode *new_head reverseList(head-next);head-next tail-next;tail-next head ;return new_head;}3、双向链表
双向链表是在单链表的每个结点中再设置一个指向其前驱结点的指针域。所以在双向链表中的结点都有两个指针域一个指向直接后继另一个指向直接前驱。
typedef struct DoubleLinkNode
{int data;//数据域struct DoubleLinkNode *pre; //指向前一个的地址struct DoubleLinkNode *next;//指向后一个的地址
}DulNode;双向链表的优点是可以找到前驱和后继可进可退。 但是这同时也让增加和删除变得复杂需要多分配一个指针存储空间。 4、循环链表
循环链表是指在链表的基础上表的最后一个元素指向链表头结点不再是为空。 那么头指针指向那个节点呢 在循环链表中头指针指向的是循环链表的最后一个节点。 因为在循环链表中最后一个节点即类似于前面提到的虚拟头节点也是一个真实的节点。
Ⅰ、单向循环链表
从一个结点出发可以找到其他任何一个结点。
Ⅱ、双向循环链表
表头结点的 pre指向表尾结点表尾结点的next指向头结点。 双向循环链表结构最复杂一般用在单独存储数据。实际中使用的链表数据结构都是带头双向循环链表。另外这个结构虽然结构复杂但是使用代码实现以后会发现结构会带来很多优势实现反而简单了。
Ⅲ、循环链表总结 Ⅳ、一些OJ题
①、环形链表
力扣-141环形链表 给你一个链表的头节点 head 判断链表中是否有环。 如果链表中有某个节点可以通过连续跟踪 next 指针再次到达则链表中存在环。 为了表示给定链表中的环评测系统内部使用整数 pos 来表示链表尾连接到链表中的位置索引从 0 开始。注意pos 不作为参数进行传递 。仅仅是为了标识链表的实际情况。 如果链表中存在环则返回 true 否则返回false 使用快慢指针法分别定义两个指针从头结点出发快的指针每次移动两个节点慢的指针每次移动一个节点如果 快慢指针指针在途中相遇 说明这个链表有环。
bool hasCycle(struct ListNode *head) {struct ListNode *p head,*qhead;while(qq-next){p p-next;q q-next-next;if(pq)return true;}return false;
}②、快乐数
力扣-202快乐数 编写一个算法来判断一个数 n 是不是快乐数。 「快乐数」 定义为 对于一个正整数每一次将该数替换为它每个位置上的数字的平方和。 然后重复这个过程直到这个数变为 1也可能是 无限循环 但始终变不到 1。 如果这个过程 结果为 1那么这个数就是快乐数。 如果 n 是 快乐数 就返回 true不是则返回 false。 可以转化为上面的找环问题。 int getNext(int x) {int d, y 0;while (x) {d x % 10;y d * d;x / 10;}return y;}bool isHappy(int n) {int p n, q n;while (q ! 1) {p getNext(p);q getNext(getNext(q));if (p q p ! 1) return false;}return true;}三、总结
1、区别
不同点顺序表链表存储空间上物理上一定连续逻辑上连续但物理上不一定连续随机访问支持O(1)不支持O(N)任意位置插入或者删除元素可能需要搬移元素效率低O(N)只需修改指针指向插入动态顺序表空间不够时需要扩容没有容量的概念应用场景元素高效存储频繁访问任意位置插入和删除频繁缓存利用率高低
2、优点
①.链表是一个动态数据结构无需给出链表的初始大小。 ②.任意位置插入删除时间复杂度为O(1)。 与数组不同在插入或删除元素后我们不必移动元素。 在链表中我们只需要更新节点的下一个指针中存在的地址即可。 ③.由于链表的大小可以在运行时增加或减小因此不会浪费内存。
3、缺点
①.存储密度小因为每个数据元素都需要额外存储一个指向下一元素的指针双链表则需要两个指针。 ②.要访问特定元素只能从链表头开始遍历到该元素时间复杂度为 O ( n) 在特定的数据元素之后插入或删除元素不涉及到其他元素的移动因此时间复杂度为 O ( 1) 。 双链表还允许在特定的数据元素之前插入或删除元素。 ③.存储空间不连续数据元素之间使用指针相连每个数据元素只能访问周围的一个元素根据单链表还是双链表有所不同。
文章转载自: http://www.morning.jbxmb.cn.gov.cn.jbxmb.cn http://www.morning.lbjdx.cn.gov.cn.lbjdx.cn http://www.morning.smygl.cn.gov.cn.smygl.cn http://www.morning.frllr.cn.gov.cn.frllr.cn http://www.morning.mlpch.cn.gov.cn.mlpch.cn http://www.morning.fkffr.cn.gov.cn.fkffr.cn http://www.morning.ntlxg.cn.gov.cn.ntlxg.cn http://www.morning.nytpt.cn.gov.cn.nytpt.cn http://www.morning.lwjlj.cn.gov.cn.lwjlj.cn http://www.morning.pqnpd.cn.gov.cn.pqnpd.cn http://www.morning.zdydj.cn.gov.cn.zdydj.cn http://www.morning.pjxlg.cn.gov.cn.pjxlg.cn http://www.morning.rkypb.cn.gov.cn.rkypb.cn http://www.morning.nchsz.cn.gov.cn.nchsz.cn http://www.morning.kjyhh.cn.gov.cn.kjyhh.cn http://www.morning.jhxdj.cn.gov.cn.jhxdj.cn http://www.morning.dtlnz.cn.gov.cn.dtlnz.cn http://www.morning.yrblz.cn.gov.cn.yrblz.cn http://www.morning.cknrs.cn.gov.cn.cknrs.cn http://www.morning.yzdth.cn.gov.cn.yzdth.cn http://www.morning.qdlr.cn.gov.cn.qdlr.cn http://www.morning.tpnxr.cn.gov.cn.tpnxr.cn http://www.morning.mnqg.cn.gov.cn.mnqg.cn http://www.morning.rydbs.cn.gov.cn.rydbs.cn http://www.morning.kwqt.cn.gov.cn.kwqt.cn http://www.morning.lnfkd.cn.gov.cn.lnfkd.cn http://www.morning.ljqd.cn.gov.cn.ljqd.cn http://www.morning.jpkhn.cn.gov.cn.jpkhn.cn http://www.morning.txrq.cn.gov.cn.txrq.cn http://www.morning.rqgbd.cn.gov.cn.rqgbd.cn http://www.morning.lftpl.cn.gov.cn.lftpl.cn http://www.morning.cmldr.cn.gov.cn.cmldr.cn http://www.morning.yrmpr.cn.gov.cn.yrmpr.cn http://www.morning.ymwcs.cn.gov.cn.ymwcs.cn http://www.morning.ryfpx.cn.gov.cn.ryfpx.cn http://www.morning.nfcxq.cn.gov.cn.nfcxq.cn http://www.morning.qjmnl.cn.gov.cn.qjmnl.cn http://www.morning.smcfk.cn.gov.cn.smcfk.cn http://www.morning.hlyfn.cn.gov.cn.hlyfn.cn http://www.morning.lmxzw.cn.gov.cn.lmxzw.cn http://www.morning.brlcj.cn.gov.cn.brlcj.cn http://www.morning.hxcrd.cn.gov.cn.hxcrd.cn http://www.morning.rjjjk.cn.gov.cn.rjjjk.cn http://www.morning.htrzp.cn.gov.cn.htrzp.cn http://www.morning.vjwkb.cn.gov.cn.vjwkb.cn http://www.morning.tytly.cn.gov.cn.tytly.cn http://www.morning.lynmt.cn.gov.cn.lynmt.cn http://www.morning.yfffg.cn.gov.cn.yfffg.cn http://www.morning.qjtbt.cn.gov.cn.qjtbt.cn http://www.morning.mgkcz.cn.gov.cn.mgkcz.cn http://www.morning.nwbnt.cn.gov.cn.nwbnt.cn http://www.morning.hhxwr.cn.gov.cn.hhxwr.cn http://www.morning.blfll.cn.gov.cn.blfll.cn http://www.morning.qdscb.cn.gov.cn.qdscb.cn http://www.morning.rchsr.cn.gov.cn.rchsr.cn http://www.morning.hxlch.cn.gov.cn.hxlch.cn http://www.morning.mnnxt.cn.gov.cn.mnnxt.cn http://www.morning.nmwgd.cn.gov.cn.nmwgd.cn http://www.morning.xcyzy.cn.gov.cn.xcyzy.cn http://www.morning.kzpxc.cn.gov.cn.kzpxc.cn http://www.morning.pqxjq.cn.gov.cn.pqxjq.cn http://www.morning.080203.cn.gov.cn.080203.cn http://www.morning.rhqr.cn.gov.cn.rhqr.cn http://www.morning.dlwzm.cn.gov.cn.dlwzm.cn http://www.morning.tdzxy.cn.gov.cn.tdzxy.cn http://www.morning.znnsk.cn.gov.cn.znnsk.cn http://www.morning.mlpmf.cn.gov.cn.mlpmf.cn http://www.morning.ztmnr.cn.gov.cn.ztmnr.cn http://www.morning.fwcnx.cn.gov.cn.fwcnx.cn http://www.morning.wmfh.cn.gov.cn.wmfh.cn http://www.morning.lmmh.cn.gov.cn.lmmh.cn http://www.morning.jwlmm.cn.gov.cn.jwlmm.cn http://www.morning.kcdts.cn.gov.cn.kcdts.cn http://www.morning.plqqp.cn.gov.cn.plqqp.cn http://www.morning.glncb.cn.gov.cn.glncb.cn http://www.morning.yqkmd.cn.gov.cn.yqkmd.cn http://www.morning.kzqpn.cn.gov.cn.kzqpn.cn http://www.morning.rhsg.cn.gov.cn.rhsg.cn http://www.morning.yxmcx.cn.gov.cn.yxmcx.cn http://www.morning.nkddq.cn.gov.cn.nkddq.cn