数据结构(二)—— 链表(2)

news/2025/1/12 15:47:42/

文章目录

  • 1 143 重排链表
    • 1.1 找到原链表的中点(「876. 链表的中间结点」)。
    • 2.2 将原链表的右半端反转(「206. 反转链表」)
    • 3.3 交叉合并两个链表(与「21. 合并两个有序链表」思路不同)
    • 3.4 补充 21 合并两个有序链表
  • 2 328 奇偶链表
  • 3 单向链表
  • 4 双向链表
  • 5 双向循环链表


1 143 重排链表

笨方案一:利用线性表存储该链表,而后直接按顺序访问指定元素,重建该链表即可。
在这里插入图片描述

void reorderList(ListNode* head) {if(head == nullptr) return;vector<ListNode*> vec;while(head != nullptr){vec.push_back(head);head = head->next;}int i = 0;int j = vec.size() - 1;while(i < j){vec[i]->next = vec[j];++i;if (i == j) {break;}vec[j]->next = vec[i];--j;}vec[i]->next = nullptr;
}

方案二:寻找链表中点 + 链表逆序 + 合并链表
注意到目标链表即为将原链表的左半端和反转后的右半端合并后的结果。

这样任务可划分为三步:

1.1 找到原链表的中点(「876. 链表的中间结点」)。

使用快慢指针找到链表的中间节点。
在这里插入图片描述

2.2 将原链表的右半端反转(「206. 反转链表」)

使用迭代法实现链表的反转。

3.3 交叉合并两个链表(与「21. 合并两个有序链表」思路不同)

保证l2的长度小于l1,这里的写法与21不同。
在这里插入图片描述

class Solution {
public:void reorderList(ListNode* head) {if(head == nullptr) return;ListNode* mid = middleNode(head);ListNode* reverse = reverseList(mid->next);mid->next = nullptr;   // 将链表切断mergeList(head, reverse);}ListNode* middleNode(ListNode* head) {ListNode* slow = head;ListNode* fast = head;while(fast->next != nullptr && fast->next->next != nullptr){fast = fast->next->next;slow = slow->next;}return slow;}ListNode* reverseList(ListNode* head) {ListNode* cur = head;ListNode* pre = nullptr;while(cur != nullptr){ListNode* temp = cur->next;cur->next = pre;pre = cur;cur = temp;}return pre;}void mergeList(ListNode* l1, ListNode* l2) {while(l2 != nullptr){ListNode* templ1 = l1->next;l1->next = l2;l1 = templ1;ListNode* templ2 = l2->next;l2->next = l1;l2 = templ2;}}};

与21相同的思路代码如下,注意返回值为ListNode*了

ListNode* mergeList(ListNode* l1, ListNode* l2) {ListNode* dummyhead = new ListNode(999);ListNode* cur = dummyhead;while(l1 != nullptr && l2 != nullptr){cur->next = l1;l1 = l1->next;cur = cur->next;cur->next = l2;l2 = l2->next;cur = cur->next;}if(l1 != nullptr) cur->next = l1;if(l2 != nullptr) cur->next = l2;return dummyhead->next;
}

3.4 补充 21 合并两个有序链表

在这里插入图片描述

ListNode* mergeTwoLists(ListNode* list1, ListNode* list2) {if(list1 == nullptr) return list2;if(list2 == nullptr) return list1;ListNode* dummyhead = new ListNode(0);ListNode* cur = dummyhead;while(list1 != nullptr && list2 != nullptr) {if(list1->val < list2->val){cur->next = list1;cur = cur->next;list1 = list1->next;}else{cur->next = list2;cur = cur->next;list2 = list2->next;}}if(list1 != nullptr) cur->next = list1;if(list2 != nullptr) cur->next = list2;return dummyhead->next;
}

2 328 奇偶链表

在这里插入图片描述

while的退出条件是画图得出的

ListNode* oddEvenList(ListNode* head) {if(head == nullptr) return head;ListNode* odd = head;ListNode* even = head->next;ListNode* evenhead = even;while(even != nullptr && even->next != nullptr) {odd->next = even->next;    // 1even->next = odd->next->next;   // 2odd = odd->next;even = even->next;}odd->next = evenhead;return head;
}

3 单向链表

#include<iostream>using namespace std;class MyLinkedList {
public:struct ListNode {int val;ListNode* next;ListNode(int val) : val(val), next(nullptr) {}};MyLinkedList() {node_ = new ListNode(0);size_ = 0;}int get(int index) {if (index >= size_ || index < 0) return -1;ListNode* cur = node_;while (index--) {cur = cur->next;}cur = cur->next;return cur->val;}void addAtHead(int val) {ListNode* newNode = new ListNode(val);newNode->next = node_->next;node_->next = newNode;size_++;}void addAtTail(int val) {ListNode* newNode = new ListNode(val);ListNode* cur = node_;while (cur->next != nullptr) {cur = cur->next;}cur->next = newNode;size_++;}void addAtIndex(int index, int val) {if (index > size_ || index < 0) return; // index可以为size_ListNode* newNode = new ListNode(val);ListNode* cur = node_;while (index--) {cur = cur->next;}newNode->next = cur->next;cur->next = newNode;size_++;}void deleteAtIndex(int index) {if (index >= size_ || index < 0) return;ListNode* cur = node_;while (index--) {cur = cur->next;}ListNode* temp = cur->next;cur->next = cur->next->next;delete temp;size_--;}void show() {ListNode* cur = node_->next;while (cur != nullptr) {cout << cur->val << " ";cur = cur->next;}cout << endl;}private:int size_;ListNode* node_;
};int main() {MyLinkedList link;link.addAtHead(7);link.addAtHead(2);link.addAtHead(1);link.addAtTail(8);link.show();link.deleteAtIndex(2);link.show();return 0;
}

4 双向链表

#include<iostream>using namespace std;struct Node {int data_;Node* pre_;Node* next_;Node(int data): data_(data), pre_(nullptr), next_(nullptr) {}Node(){pre_ = nullptr;next_ = nullptr;}    
};class DoubleLink {
public:DoubleLink() {head_ = new Node();}~DoubleLink() {Node* p = head_;while (p != nullptr) {head_ = head_->next_;delete p;p = head_;}}public:void insert_head(int val) {Node* node = new Node(val);node->next_ = head_->next_;node->pre_ = head_;if (head_->next_ != nullptr) head_->next_->pre_ = node;  //原来链表里有第一个节点  确认head后面一个不为空head_->next_ = node;}// 尾插法void InsertTail(int val) {Node* p = head_;while (p->next_ != nullptr) {p = p->next_;}Node* node = new Node(val);node->pre_ = p;p->next_ = node;}void Remove(int val) {Node* p = head_->next_;while (p != nullptr) {if (p->data_ == val) {p->pre_->next_ = p->next_;if (p->next_ != nullptr) p->next_->pre_ = p->pre_;delete p;return;} else {p = p->next_;}}}bool Find(int val) {Node* p = head_->next_;while (p != nullptr) {if (p->data_ == val) {return true;} else {p = p->next_;}}}void show() {Node* p = head_->next_;while (p != nullptr) {cout << p->data_ << " ";p = p->next_;}cout << endl;}
private:Node* head_;
};int main() {DoubleLink dlink;dlink.InsertTail(20);dlink.InsertTail(23);dlink.InsertTail(89);dlink.InsertTail(15);dlink.InsertTail(36);dlink.InsertTail(78);dlink.InsertTail(56);dlink.InsertTail(41);dlink.InsertTail(32);dlink.show();dlink.insert_head(200);dlink.show();dlink.Remove(200);dlink.show();dlink.Remove(78);dlink.show();return 0;
}

5 双向循环链表

#include<iostream>using namespace std;struct Node {int data_;Node* pre_;Node* next_;Node(int data): data_(data), pre_(nullptr), next_(nullptr) {}Node(){pre_ = nullptr;next_ = nullptr;}    
};class DoubleCircleLink {
public:DoubleCircleLink() {head_ = new Node();head_->next_ = head_;head_->pre_ = head_;}~DoubleCircleLink() {Node* p = head_->next_;while (p != head_) {head_->next_ = p->next_;p->next_->pre_ = head_;delete p;p = head_->next_;}delete head_;head_ = nullptr;}public:void insert_head(int val) {Node* node = new Node(val);node->next_ = head_->next_;node->pre_ = head_;if (head_->next_ != nullptr) head_->next_->pre_ = node;  //原来链表里有第一个节点  确认head后面一个不为空head_->next_ = node;}// 尾插法void InsertTail(int val) {Node* p = head_->pre_;Node* node = new Node(val);node->pre_ = p;p->next_ = node;node->next_ = head_;head_->pre_ = node;}void Remove(int val) {Node* p = head_->next_;while (p != head_) {if (p->data_ == val) {p->pre_->next_ = p->next_;p->next_->pre_ = p->pre_;delete p;return;} else {p = p->next_;}}}bool Find(int val) {Node* p = head_->next_;while (p != head_) {if (p->data_ == val) {return true;} else {p = p->next_;}}}void show() {Node* p = head_->next_;while (p != head_) {cout << p->data_ << " ";p = p->next_;}cout << endl;}
private:Node* head_;
};int main() {DoubleCircleLink dlink;dlink.InsertTail(20);dlink.InsertTail(23);dlink.InsertTail(89);dlink.InsertTail(15);dlink.InsertTail(36);dlink.InsertTail(78);dlink.InsertTail(56);dlink.InsertTail(41);dlink.InsertTail(32);dlink.show();dlink.insert_head(200);dlink.show();dlink.Remove(200);dlink.show();dlink.Remove(78);dlink.show();return 0;
}

感谢博主 @-特立独行的猪-
实在是太强了555


http://www.ppmy.cn/news/107695.html

相关文章

Dockerd 进程CPU high 100% 原因排查

Dockerd 进程CPU high 100% 原因排查 现象说明 线上主机不知道操作了什么&#xff0c;收到了监控cpu load 告警。排查dockerd进程在作怪. 排查过程 排查容器的内存、cpu均正常.收到故障&#xff0c;运维思想&#xff0c;先恢复生产。优雅的重启dockerd进程&#xff0c;不影…

Feign入门使用 OpenFeign 日志增强 超时控制

一、概述 Feign是一个声明式的web服务的客户端&#xff0c;Feign就是参考Ribbon添加了注解接口的绑定器。 我们封装一些客户端类来包装对其他服务的依赖调用。Feign让我们只需要创建一个接口注解就能够实现操作。Feign集成了Ribbon 关于使用就是在接口添加特定注解就可以了。…

【课代表笔记】直播回顾:Top药企的数字化实践集锦

【K讲了】系列直播之医药行业第一期&#xff1a;Top药企的数字化实践集锦前不久已在视频号和大家如期见面&#xff0c;以下是课代表为大家抄好的笔记~~ 斯歌K2的医药行业经验 K2在医药领域拥有丰富的客户积累及实施经验&#xff0c;全球TOP 10药企中有7家选择K2。斯歌K2已在医药…

Softing“物联网连接和OPC UA通信”系列研讨会

— 免费线上研讨会概览 — 您是否正在为车间应用寻找机器连接&#xff1f;您是否需要为创新的物联网解决方案制定架构决策&#xff1f;或者您是否已经选择了物联网平台&#xff0c;需要连接组件来访问自动化网络中的数据&#xff1f;在Softing线上研讨会中&#xff0c;我们将讨…

让ChatGPT谈谈科技发展

ChatGPT谈科技发展 讲讲科技发展的那些事儿谈谈ChatGPT对科技发展的影响谈谈你对ChatGPT的看法ChatGPT对科技发展的负面影响ChatGPT的存在是利是弊&#xff1f;关于全国科技者工作日 讲讲科技发展的那些事儿 谈谈ChatGPT对科技发展的影响 谈谈你对ChatGPT的看法 ChatGPT对科技发…

应用案例 | 升级OPC Classic到OPC UA,实现安全高效的数据通信

一 背景 OPC&#xff08;OLE for Process Control&#xff0c;用于过程控制的OLE&#xff09;是工业自动化领域中常见的通信协议。它提供了一种标准化的方式&#xff0c;使得不同厂商的设备和软件可互相通信和交换数据。OPC Classic是旧版OPC规范&#xff0c;通过使用COM&…

如何使用 Python 进行机器学习?

全套学习路线图、课程&#xff0c;机器学习工作流程如下。 Python人工智能 入门&#xff1a; Python基础→Python数据挖掘中级&#xff1a; 机器学习进阶&#xff1a; NLP自然语言高级&#xff1a; OpenCV基础→深度学习 人工智能学习路线图2023版-黑马程序员人工智能技术路…

IC卡水表大多都用在什么项目上?有什么功能特点吗?

IC卡水表是一种先进的计量仪表&#xff0c;广泛应用于许多项目&#xff0c;其功能特点使其在许多领域得到广泛应用。 首先&#xff0c;IC卡水表可以应用于自来水的计量&#xff0c;它可以高精度地测量水的流量&#xff0c;提供给用户准确的用水量信息&#xff0c;从而有助于用户…