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

甘州区建设局网站青岛百度网站排名

甘州区建设局网站,青岛百度网站排名,中国设计联盟网服务内容,平顶山做网站的公司嵌入式软件数据结构(一)链表知识点专栏 附源码 附原理 前言: 首先我们要知道什么是链表? 什么是链表,链表是一种通过指针串联在一起的线性结构,每一个节点由两部分组成,一个是数据域一个是指…

嵌入式软件数据结构(一)链表知识点专栏 附源码 附原理  前言:

首先我们要知道什么是链表?

什么是链表,链表是一种通过指针串联在一起的线性结构,每一个节点由两部分组成,一个是数据域一个是指针域(存放指向下一个节点的指针),最后一个节点的指针域指向null(空指针的意思)链表的入口节点称为链表的头结点也就是head。

链表就像是一个由一串小纸条组成的链条,每个纸条上有两部分内容:一部分是写的数字或者信息(就是数据),另一部分是指向下一个纸条的箭头。最后一个纸条上没有箭头,说明它是链条的终点。你可以从第一个纸条(头结点)开始,按照箭头一个一个地找到下去。

每次想在链表中加入新纸条时,你只需要把新纸条和前一个纸条用箭头连接起来;如果要拿掉一个纸条,只需要把前面那个纸条的箭头指向后面那个纸条就行,不需要移动其他纸条。

链表的好处是插入和删除纸条很方便,但如果你想要快速找到某个纸条,就得从头开始一条条地找。

这样说,链表是不是更直观了一些?

如图所示:

链表的类型

接下来说一下链表的几种类型:

单链表

双链表

单链表中的指针域只能指向节点的下一个节点。

双链表:每一个节点有两个指针域,一个指向下一个节点,一个指向上一个节点。

双链表 既可以向前查询也可以向后查询。

如图所示:

 

循环链表

循环链表,顾名思义,就是链表首尾相连。

循环链表可以用来解决约瑟夫环问题。

链表的存储方式

了解完链表的类型,再来说一说链表在内存中的存储方式。

数组是在内存中是连续分布的,但是链表在内存中可不是连续分布的。

链表是通过指针域的指针链接在内存中各个节点。

所以链表中的节点在内存中不是连续分布的 ,而是散乱分布在内存中的某地址上,分配机制取决于操作系统的内存管理。

如图所示:

这个链表起始节点为2, 终止节点为7, 各个节点分布在内存的不同地址空间上,通过指针串联在一起。

链表的操作

删除D节点,如图所示:

 

只要将C节点的next指针 指向E节点就可以了。

那有同学说了,D节点不是依然存留在内存里么?只不过是没有在这个链表里而已。

是这样的,所以在C++里最好是再手动释放这个D节点,释放这块内存。

其他语言例如Java、Python,就有自己的内存回收机制,就不用自己手动释放了。

添加节点

可以看出链表的增添和删除都是O(1)操作,也不会影响到其他节点。

但是要注意,要是删除第五个节点,需要从头节点查找到第四个节点通过next指针进行删除操作,查找的时间复杂度是O(n)。

再把链表的特性和数组的特性进行一个对比,如图所示:

数组在定义的时候,长度就是固定的,如果想改动数组的长度,就需要重新定义一个新的数组。

链表的长度可以是不固定的,并且可以动态增删, 适合数据量不固定,频繁增删,较少查询的场景。

删除单链表的重复节点

面试题 02.01. 移除重复节点 - 力扣(LeetCode)

编写代码,移除未排序链表中的重复节点。保留最开始出现的节点。

/*** Definition for singly-linked list.* struct ListNode {*     int val;*     struct ListNode *next;* };*/
struct ListNode* removeDuplicateNodes(struct ListNode* head) {if (head == NULL) return NULL;bool hash[20001] = {false}; // 假设节点值的范围在0到20000之间struct ListNode dummy = {0, head};struct ListNode *prev = &dummy;struct ListNode *current = head;while (current != NULL) {if (hash[current->val]) {// 删除当前节点prev->next = current->next;free(current);current = prev->next;} else {hash[current->val] = true;prev = current;current = current->next;}}return head;
}

 

如何找出链表的倒数第K个元素?

LCR 140. 训练计划 II - 力扣(LeetCode)

给定一个头节点为 head 的链表用于记录一系列核心肌群训练项目编号,请查找并返回倒数第 cnt 个训练项目编号。

/*** Definition for singly-linked list.* struct ListNode {*     int val;*     struct ListNode *next;* };*/
struct ListNode* trainingPlan(struct ListNode* head, int cnt) {if (head == NULL || cnt <= 0) {return NULL;}struct ListNode *fast = head, *slow = head;// Move fast pointer cnt steps aheadfor (int i = 0; i < cnt; i++) {if (fast == NULL) return NULL;  // If cnt is greater than the length of the listfast = fast->next;}// Move both fast and slow pointers until fast reaches the endwhile (fast != NULL) {fast = fast->next;slow = slow->next;}// Now slow points to the cnt-th node from the endreturn slow;
}

如何找出链表的中间节点

876. 链表的中间结点 - 力扣(LeetCode)

给你单链表的头结点 head ,请你找出并返回链表的中间结点。

如果有两个中间结点,则返回第二个中间结点。

/*** Definition for singly-linked list.* struct ListNode {*     int val;*     struct ListNode *next;* };*/
struct ListNode* middleNode(struct ListNode* head) {struct ListNode *fast = head, *slow = head;// 快慢指针,fast 每次移动 2 步,slow 每次移动 1 步while (fast != NULL && fast->next != NULL) {fast = fast->next->next;  // fast 移动两步slow = slow->next;        // slow 移动一步}// 当 fast 指针到达链表末尾时,slow 指针就指向中间节点return slow;
}

反转链表

LCR 141. 训练计划 III - 力扣(LeetCode)

给定一个头节点为 head 的单链表用于记录一系列核心肌群训练编号,请将该系列训练编号 倒序 记录于链表并返回。

/*** Definition for singly-linked list.* struct ListNode {*     int val;*     struct ListNode *next;* };*/
struct ListNode* trainningPlan(struct ListNode* head) {struct ListNode *prev = NULL, *curr = head, *next = NULL;// 遍历链表并反转指针while (curr != NULL) {next = curr->next;    // 保存当前节点的下一个节点curr->next = prev;    // 将当前节点的指针反向prev = curr;          // prev 前移,指向当前节点curr = next;          // curr 前移,指向下一个节点}// 返回新的头节点return prev;
}

环形链表

141. 环形链表 - 力扣(LeetCode)

给你一个链表的头节点 head ,判断链表中是否有环。

如果链表中有某个节点,可以通过连续跟踪 next 指针再次到达,则链表中存在环。 为了表示给定链表中的环,评测系统内部使用整数 pos 来表示链表尾连接到链表中的位置(索引从 0 开始)。注意:pos 不作为参数进行传递 。仅仅是为了标识链表的实际情况。

如果链表中存在环 ,则返回 true 。 否则,返回 false 。

/*** Definition for singly-linked list.* struct ListNode {*     int val;*     struct ListNode *next;* };*/
bool hasCycle(struct ListNode *head) {if (head == NULL) return false;struct ListNode *slow = head, *fast = head;while (fast != NULL && fast->next != NULL) {slow = slow->next;           // 慢指针每次走一步fast = fast->next->next;     // 快指针每次走两步// 如果快慢指针相遇,说明有环if (slow == fast) {return true;}}// 如果 fast 指针到达链表的末尾,说明没有环return false;
}

单链表相交,如何求交点?

面试题 02.07. 链表相交 - 力扣(LeetCode)

给你两个单链表的头节点 headA 和 headB ,请你找出并返回两个单链表相交的起始节点。如果两个链表没有交点,返回 null 。

图示两个链表在节点 c1 开始相交

题目数据 保证 整个链式结构中不存在环。

注意,函数返回结果后,链表必须 保持其原始结构 。

/*** Definition for singly-linked list.* struct ListNode {*     int val;*     struct ListNode *next;* };*/
struct ListNode *getIntersectionNode(struct ListNode *headA, struct ListNode *headB) {if (headA == NULL || headB == NULL) {return NULL;}struct ListNode *pA = headA;struct ListNode *pB = headB;// 遍历两个链表,指针 pA 和 pB 将同时遍历相同的长度while (pA != pB) {// 如果 pA 到达链表末尾,则跳转到链表 B 的头pA = (pA == NULL) ? headB : pA->next;// 如果 pB 到达链表末尾,则跳转到链表 A 的头pB = (pB == NULL) ? headA : pB->next;}// 当 pA 和 pB 相遇时,返回交点(可能是 NULL,表示没有交点)return pA;
}

回文链表

234. 回文链表 - 力扣(LeetCode)

给你一个单链表的头节点 head ,请你判断该链表是否为回文链表。如果是,返回 true ;否则,返回 false 。

/*** Definition for singly-linked list.* struct ListNode {*     int val;*     struct ListNode *next;* };*/
// 反转链表
struct ListNode* reverseList(struct ListNode* head) {struct ListNode *prev = NULL, *curr = head, *next = NULL;while (curr != NULL) {next = curr->next;curr->next = prev;prev = curr;curr = next;}return prev;
}// 判断链表是否为回文
bool isPalindrome(struct ListNode* head) {if (head == NULL || head->next == NULL) {return true;  // 空链表或只有一个节点的链表是回文的}// 快慢指针找到链表中间节点struct ListNode *slow = head, *fast = head;while (fast != NULL && fast->next != NULL) {slow = slow->next;fast = fast->next->next;}// 反转后半部分链表struct ListNode* secondHalf = reverseList(slow);struct ListNode* firstHalf = head;// 比较前半部分和反转后的后半部分while (secondHalf != NULL) {if (firstHalf->val != secondHalf->val) {return false;  // 如果不相等,说明不是回文链表}firstHalf = firstHalf->next;secondHalf = secondHalf->next;}return true;  // 如果所有节点相等,则是回文链表
}

移除重复节点

面试题 02.01. 移除重复节点 - 力扣(LeetCode)

编写代码,移除未排序链表中的重复节点。保留最开始出现的节点。

/*** Definition for singly-linked list.* struct ListNode {*     int val;*     struct ListNode *next;* };*/
struct ListNode* removeDuplicateNodes(struct ListNode* head) {if (head == NULL) return NULL;bool hash[20001] = {false}; // 假设节点值的范围在0到20000之间struct ListNode dummy = {0, head};struct ListNode *prev = &dummy;struct ListNode *current = head;while (current != NULL) {if (hash[current->val]) {// 删除当前节点prev->next = current->next;free(current);current = prev->next;} else {hash[current->val] = true;prev = current;current = current->next;}}return head;
}

用普通算法实现两个有序链表合并

21. 合并两个有序链表 - 力扣(LeetCode)

将两个升序链表合并为一个新的 升序 链表并返回。新链表是通过拼接给定的两个链表的所有节点组成的。 

/*** Definition for singly-linked list.* struct ListNode {*     int val;*     struct ListNode *next;* };*/
struct ListNode* mergeTwoLists(struct ListNode* l1, struct ListNode* l2) {// 如果 l1 为 NULL,直接返回 l2if (l1 == NULL) return l2;// 如果 l2 为 NULL,直接返回 l1if (l2 == NULL) return l1;// 比较 l1 和 l2 当前节点的值,选择较小的节点if (l1->val < l2->val) {// 如果 l1 的值较小,递归合并 l1 的下一个节点和 l2l1->next = mergeTwoLists(l1->next, l2);return l1;} else {// 如果 l2 的值较小,递归合并 l1 和 l2 的下一个节点l2->next = mergeTwoLists(l1, l2->next);return l2;}
}

http://www.dtcms.com/wzjs/426949.html

相关文章:

  • asp.net网站安装教程网络营销和网络推广
  • 网站公司做的网站点击率怎么查南京谷歌seo
  • 多人运动免费正能量网站链接杭州网站优化方案
  • 怎样自己免费搭建网站推广策划
  • 市场部做网站工作职责seo算法是什么
  • 商城类网站开发注册网站免费注册
  • 白沟做网站做网站怎么优化
  • 手机网站建设模板百度seoo优化软件
  • 阳信做网站关键词优化的作用
  • 美国一个人做的网站苏州网站建设方案
  • 长沙市师德师风建设网站百度搜索引擎技巧
  • 网站开发前端后端书籍seo推广任务小结
  • 网站定制公司报价挖掘关键词的工具
  • b2c商务网站建设全网整合营销
  • 库存网站建设哪家好seo外链自动群发工具
  • 白城学习做网站的学校网站数据统计
  • 攀枝花网站建设公司求个没封的网站2022
  • 成都疫情最新规定公告广西百度seo
  • 宣讲家网站 家风建设seo的中文是什么
  • asp做学生信息网站新媒体运营
  • 有没有专门做尾料回收的网站三一crm手机客户端下载
  • 网站做301排名会掉谷歌关键词排名优化
  • 郑州管城建设网站推广软文发稿
  • 个人网站建设与企业网站网络营销师培训费用是多少
  • 深圳网站建设注册google安卓手机下载
  • 网站导航是做链接赚钱么百度关键词指数查询
  • 珠海市网站建设开发公司百度首页推荐关不掉吗
  • 兼职做网站开网店哪个平台靠谱
  • 平台推广是做什么的seo基础培训机构
  • 大连哪个公司做网站好优化大师apk