链表

LinkedList 源码解析

穿精又带淫゛_ 提交于 2020-02-08 20:24:00
LinkedList 适用于集合元素先入先出和先入后出的场景,在队列源码中被频繁使用,面试也经常问到,本小节让我们通过源码来加深对 LinkedList 的了解。 1 整体架构 LinkedList 底层数据结构是一个双向链表,整体结构如下图所示: 上图代表了一个双向链表结构,链表中的每个节点都可以向前或者向后追溯,我们有几个概念如下 : 链表每个节点我们叫做 Node,Node 有 prev 属性,代表前一个节点的位置,next 属性,代表后一个节点的位置; first 是双向链表的头节点,它的前一个节点是 null。 last 是双向链表的尾节点,它的后一个节点是 null; 当链表中没有数据时,first 和 last 是同一个节点,前后指向都是 null; 因为是个双向链表,只要机器内存足够强大,是没有大小限制的。 链表中的元素叫做 Node,我们看下 Node 的组成部分: private static class Node < E > { E item ; // 节点值 Node < E > next ; // 指向的下一个节点 Node < E > prev ; // 指向的前一个节点 // 初始化参数顺序分别是:前一个节点、本身节点值、后一个节点 Node ( Node < E > prev , E element , Node < E > next ) {

相交链表

可紊 提交于 2020-02-08 18:25:48
题目 思路 自己的思路——暴力解法 分别遍历两个链表,记录下他们的长度s1,s2 长链表先走|s1-s2|,然后短链表再以相同的速度出发 当两个链表相等时,便是相交节点 相关代码如下: class Solution { public: ListNode *getIntersectionNode(ListNode *headA, ListNode *headB) { if (!headA || !headB) return NULL; ListNode* A = headA; ListNode* B = headB; int ch1=0, ch2=0; while (A->next) { A = A->next; ch1++; } while (B->next) { B = B->next; ch2++; } if (B != A) return NULL; A = headA; B = headB; if (ch1 > ch2) { ch1 = ch1 - ch2; while (ch1) { A = A->next; ch1--; } } else { ch2 = ch2 - ch1; while (ch2) { B = B->next; ch2--; } } while (B != A) { A = A->next; B = B->next; } return A; } };

[剑指offer][leetcode.141]环形链表

北慕城南 提交于 2020-02-08 17:05:00
题目 给定一个链表,判断链表中是否有环。 为了表示给定链表中的环,我们使用整数 pos 来表示链表尾连接到链表中的位置(索引从 0 开始)。 如果 pos 是 -1,则在该链表中没有环。 示例 1: 输入:head = [3,2,0,-4], pos = 1 输出:true 解释:链表中有一个环,其尾部连接到第二个节点。 示例 2: 输入:head = [1,2], pos = 0 输出:true 解释:链表中有一个环,其尾部连接到第一个节点。 示例 3: 输入:head = [1], pos = -1 输出:false 解释:链表中没有环。 进阶: 你能用 O(1)(即,常量)内存解决此问题吗? 分析 判断是否存在环。使用快慢指针,如果快慢指针会相遇,那么表示存在环。 bool hasCycle ( ListNode * head ) { ListNode * fast = head ; ListNode * slow = head ; while ( fast != NULL && fast - > next != NULL ) { fast = fast - > next - > next ; slow = slow - > next ; if ( fast == slow ) return true ; } return false ; } 来源: CSDN 作者: 磕葵子

LeetCode 160 相交链表

我怕爱的太早我们不能终老 提交于 2020-02-08 15:28:27
题目: 编写一个程序,找到两个单链表相交的起始节点。 如下面的两个链表: 在节点 c1 开始相交。 示例 1: 输入:intersectVal = 8, listA = [4,1,8,4,5], listB = [5,0,1,8,4,5], skipA = 2, skipB = 3 输出:Reference of the node with value = 8 输入解释:相交节点的值为 8 (注意,如果两个列表相交则不能为 0)。从各自的表头开始算起,链表 A 为 [4,1,8,4,5],链表 B 为 [5,0,1,8,4,5]。在 A 中,相交节点前有 2 个节点;在 B 中,相交节点前有 3 个节点。 示例 2: 输入:intersectVal = 2, listA = [0,9,1,2,4], listB = [3,2,4], skipA = 3, skipB = 1 输出:Reference of the node with value = 2 输入解释:相交节点的值为 2 (注意,如果两个列表相交则不能为 0)。从各自的表头开始算起,链表 A 为 [0,9,1,2,4],链表 B 为 [3,2,4]。在 A 中,相交节点前有 3 个节点;在 B 中,相交节点前有 1 个节点。 示例 3: 输入:intersectVal = 0, listA = [2,6,4],

算法总结—链表

偶尔善良 提交于 2020-02-08 15:27:50
链表题目对算法的要求度不高,但实际写的过程中需要注意语言细节,考虑精细度的地方很多。 1.链表结构与基本操作 1.1 添加节点 一般情况: cur ->next = prev ->next; prev ->next = cur; 表头插入: cur ->next = head; head = cur; 1.2删除节点 一般情况:(已知待删除节点的前驱节点) ListNode* temp = prev->next; prev->next = prev->next->next; delete temp; 表头元素删除: ListNode* temp = head->next; delete head; head = temp; 变形题目:(已知待删除节点,且不知道头指针位置,leetcode237 https://leetcode.com/problems/delete-node-in-a-linked-list/) 思路:将待删除节点后继节点内容拷贝至当前节点,然后删除后继节点,相当于以后继代替当前节点被删除 class Solution { public: void deleteNode(ListNode* node) { node->val = node->next->val; ListNode* temp = node->next; node->next = node-

leetcode 链表题总结

前提是你 提交于 2020-02-08 15:26:59
按照frequency来排序,总共27题 1、2. Add Two Numbers   https://leetcode.com/problems/add-two-numbers/#/description 两个链表相加,注意就是进位问题。 /** * Definition for singly-linked list. * public class ListNode { * int val; * ListNode next; * ListNode(int x) { val = x; } * } */ public class Solution { public ListNode addTwoNumbers(ListNode l1, ListNode l2) { int flag = 0; ListNode result = new ListNode(0); ListNode node = result; while (l1 != null || l2 != null){ int val = flag; if (l1 != null){ val += l1.val; l1 = l1.next; } if (l2 != null){ val += l2.val; l2 = l2.next; } if (val > 9){ val -= 10; flag = 1; } else {

链表简单实现

我的梦境 提交于 2020-02-08 13:49:50
链表简单实现 ```java class Node<T>{ T name; public Node(T name, Node next, Node previdous) { this.name = name; this.next = next; this.previdous = previdous; } Node<T> next; Node<T> previdous; @Override public String toString() { return "Node{" + "name='" + name + '\'' + '}'; } } *节点的实现 public class MyLinkedList < T > implements Iterable < T > { private int theSize ; private int modCount ; private Node < T > beginMarker ; private Node < T > endMarker ; public MyLinkedList ( ) { clear ( ) ; } public void clear ( ) { beginMarker = new Node < T > ( null , null , null ) ; endMarker = new Node < T > (

leetcode148.排序链表

你说的曾经没有我的故事 提交于 2020-02-08 13:48:01
在 O(n log n) 时间复杂度和常数级空间复杂度下,对链表进行排序。 示例 1: 输入 : 4 - > 2 - > 1 - > 3 输出 : 1 - > 2 - > 3 - > 4 示例 2: 输入 : - 1 - > 5 - > 3 - > 4 - > 0 输出 : - 1 - > 0 - > 3 - > 4 - > 5 来源:力扣(LeetCode) 链接:https://leetcode-cn.com/problems/sort-list 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。 完整代码 看到时间复杂度为O(nlogn)的要求,就考虑用快排来实现,但是传统的快排(以第一个元素为基准)无法实现链表的移动,这里是单向链表。采用了如下的移动方法(以第一个元素为基准) 快排 # include <bits/stdc++.h> using namespace std ; void swap ( int & a , int & b ) { //交换两个元素 int temp = a ; a = b ; b = temp ; } void quickSort ( vector < int > & nums , int s , int e ) { if ( s >= e ) //递归终止条件 return ; int flag = nums [ e ] ;

单链表排序

天涯浪子 提交于 2020-02-08 11:16:15
leetcode148链表排序 归并排序 快排链表 原题链接:https://leetcode-cn.com/problems/sort-list/ 归并排序 /** * Definition for singly-linked list. * public class ListNode { * int val; * ListNode next; * ListNode(int x) { val = x; } * } */ class Solution { public ListNode sortList ( ListNode head ) { return head == null ? null : digui ( head ) ; } private ListNode digui ( ListNode head ) //找到中间节点进行分治 { if ( head . next == null ) return head ; ListNode mid = null , low = head , high = head ; while ( high != null && high . next != null ) { mid = low ; low = low . next ; high = high . next . next ; } //找到中间节点,进行后续归并 mid .