链表

C++ 排序链表的合并-a

笑着哭i 提交于 2020-02-27 02:32:26
已知两个已排序链表头节点指针l1与l2,将这两个链表合并,合并后认为有序的,返回合并后的头节点。 思路: 比较l1和l2指向的节点,将较小的节点插入到pre指针后,并向前移动较小节点对应的指针。 # include <stdio.h> struct ListNode { int val ; ListNode * next ; ListNode ( int x ) : val ( x ) , next ( NULL ) { } } ; class Solution { public : Solution ( ) { } ~ Solution ( ) { } ListNode * mergeTwoLists ( ListNode * l1 , ListNode * l2 ) { ListNode temp_head ( 0 ) ; ListNode * pre = & temp_head ; while ( l1 && l2 ) { if ( l1 - > val < l2 - > val ) { pre - > next = l1 ; l1 = l1 - > next ; } else { pre - > next = l2 ; l2 = l2 - > next ; } pre = pre - > next ; } if ( l1 ) { pre - > next = l1 ; }

两数相加(C语言)

老子叫甜甜 提交于 2020-02-27 02:10:12
两数相加 给出两个 非空 的链表用来表示两个非负的整数。 其中,它们各自的位数是按照 逆序 的方式存储的,并且它们的每个节点只能存储 一位 数字。 如果,我们将这两个数相加起来,则会返回一个新的链表来表示它们的和。 您可以假设除了数字 0 之外,这两个数都不会以 0 开头。 输入:(2 -> 4 -> 3) + (5 -> 6 -> 4) 输出:7 -> 0 -> 8 原因:342 + 465 = 807 分析:首先,既然是两个非空链表,那么就不用考虑链表为空的情况了; 这道题我原本想先把两个整数相加,然后把相加后的和的位数按照逆序用链表存储一下,但是这样会有一个问题,如果链表特别长的话,整数就会特别大,就会溢出,显然这样做是行不通的。 因为两个整数的位数是按照逆序的方式存储的,那么每个链表的第一个元素都是个位,那么依次遍历两个链表从个位开始相加就可以,同时用 signal 来记录是否需要进位,若需要进位就把 signal 设置为1,计算更高一位的时候把 signal 的值也加上即可。 下边是代码实现: 1 /** 2 * Definition for singly-linked list. 3 * struct ListNode { 4 * int val; 5 * struct ListNode *next; 6 * }; 7 */ 8 9 10 struct ListNode

LeetCode02 - 两数相加(Java 实现)

[亡魂溺海] 提交于 2020-02-27 02:05:16
LeetCode02 - 两数相加(Java 实现) 来源:力扣(LeetCode) 链接:https://leetcode-cn.com/problems/add-two-numbers 题目描述 给出两个 非空 的链表用来表示两个非负的整数。其中,它们各自的位数是按照 逆序 的方式存储的,并且它们的每个节点只能存储 一位 数字。 如果,我们将这两个数相加起来,则会返回一个新的链表来表示它们的和。 您可以假设除了数字 0 之外,这两个数都不会以 0 开头。 示例: 输入:(2 -> 4 -> 3) + (5 -> 6 -> 4) 输出:7 -> 0 -> 8 原因:342 + 465 = 807 Java 实现与实现思路 /** * <p> * 02: 给出两个非空的链表用来表示两个非负的整数。其中,它们各自的位数是按照逆序的方式存储的,并且它们的每个节点只能存储一位数字。 * 如果,我们将这两个数相加起来,则会返回一个新的链表来表示它们的和。 * 您可以假设除了数字 0 之外,这两个数都不会以 0 开头。 * * @author XiaoPengwei * @since 2019-07-14 */ public class LeetCode02TwoAdd { public static void main(String[] args) { // 链表 1 ListNode

面试题36:复杂链表的复制

非 Y 不嫁゛ 提交于 2020-02-27 00:59:34
原地进行复制:时间复杂度O(n),空间复杂度O(1) 第一步:将链表节点复制,并将其链接 eg:1->2->3->4---------1->1->2->2->3->3->4->4 第二步:将自由链接进行链接,N->S可转化为N->N’------>S->S’ 第三步:将原节点与复制节点分开,奇节点链接起来,偶节点链接起来 /* // Definition for a Node. class Node { public: int val; Node* next; Node* random; Node(int _val) { val = _val; next = NULL; random = NULL; } }; */ class Solution { public : Node * copyRandomList ( Node * head ) { CloneNodes ( head ) ; connectRandomNodes ( head ) ; return ReConnectNodes ( head ) ; } void CloneNodes ( Node * head ) { Node * pNode = head ; while ( pNode != nullptr ) { Node * pCloneNode = new Node ( pNode - > val ) ;

C语言实现反转链表 II(指定2个节点反转)

人走茶凉 提交于 2020-02-27 00:50:34
要求: 反转从位置 m 到 n 的链表。请使用一趟扫描完成反转。 说明: 1 ≤ m ≤ n ≤ 链表长度。 示例: 输入: 1->2->3->4->5->NULL, m = 2, n = 4 输出: 1->4->3->2->5->NULL 方法迭代链接反转 算法 在看具体算法之前,有必要先弄清楚链接反转的原理以及需要哪些指针。举例而言,有一个三个不同结点组成的链表 A → B → C,需要反转结点中的链接成为 A ← B ← C。 假设我们有两个指针,一个指向结点 A,一个指向结点 B。 分别记为 prev 和 cur。则可以用这两个指针简单地实现 A 和 B 之间的链接反转: cur.next = prev 这样做唯一的问题是,没有办法继续下去,换而言之,这样做之后就无法再访问到结点 C。因此,我们需要引入第三个指针,用于帮助反转过程的进行。因此,我们不采用上面的反转方法,而是: third = cur.next cur.next = prev prev = cur cur = third 迭代 地进行上述过程,即可完成问题的要求。下面来看看算法的步骤。 1.如上所述,我们需要两个指针 prev 和 cur。 2.prev 指针初始化为 None,cur 指针初始化为链表的 head。 3.一步步地向前推进 cur 指针,prev 指针跟随其后。 4.如此推进两个指针,直到

带你逐行分析 HashMap 源码

邮差的信 提交于 2020-02-26 23:46:23
带你逐行分析 HashMap 源码 一、写在前面 相信读者也看过了不少讲解 HashMap 源码的文章了,笔者认为,一切脱离源码去讲原理的都是泛泛而谈。一些所谓的原理大都是阅读源码之后的个人概括,这些概括参差不齐,再加上没有阅读源码,读者们是很难有切身体会的。正因如此,笔者逐行分析了 HashMap 的源码后,开启了本场 Chat。 笔者在阅读 HashMap 源码的时候,曾对每个内部属性,每个内部方法和方法调用逻辑做了简要注释,但在整理成文的时候,还是遇到了略微的困难。对于一些内部属性的解释,需要结合它在一些方法的使用中发挥的作用来综合说明,笔者打算按照从浅到深的顺序,先带读者熟悉 HashMap 的宏观设计思想,再通读一遍源码,然后讲解源码的设计细节。要让读者边看文字边对照源码进行学习,形成自己的领悟和体会,避免造成笔者一人的泛泛而谈。 无论自己的领悟是深是浅,终归是自己的,无论别人的领悟多么高深,那也是别人的。希望每个读者都能有自己的收获和体会。 Java 版本 $ java -version java version "1.8.0\_211" Java(TM) SE Runtime Environment (build 1.8.0\_211-b12) Java HotSpot(TM) 64-Bit Server VM (build 25.211-b12, mixed

python-数据结构-DAY_3

爷,独闯天下 提交于 2020-02-26 23:27:33
1.链表及其结构 链表是一种线性表,节点与节点之间靠一条链连接,从一个点出发,可以找到链上的所有数据 从图中可以看到,头节点是0x11,尾节点是0x21,链表与顺序表是不同的,每一个数据自己构成一个存储单元,一个存储单元包括自身数据加上目标地址,这样就可以通过目标地址到下一个存储元素。 2.单链表的常用操作 3.python独有交换数据的方式 a = 10 b = 20 a , b = b , a python是所有语言中交换数据最方便的语言,这跟他的存储形式有关,变量a,b在未告知具体类型的时候,他就是一个存放地址的存储单元,通过存储的地址去访问数据,如果设定了数据类型,那么他只能操作包含对应类型的数据。 4.链表常用的一些语句 创建一个对象,在创建函数 class node ( self ) : cur = self . _head 将cur游标设定为自身变量的头部 cur = cur . next 将游标指向链表的下一个存储单元 cur = cur . prev 游标指向上一个存储单元 通过上述的步骤就可以判断链表长度,获取指定位置信息等功能了 5.单链表与是顺序表的对比 6.双向链表 双向链表区别于单向链表,双向链表的存储单元结构是表头+数据+表尾,在操作上会有关于表头的操作(.prev),单向链表基本不会涉及表头操作,直接指向存储结构的数据 7.单向循环链表

数据结构和对应的集合

試著忘記壹切 提交于 2020-02-26 22:18:11
栈结构和队列结构 栈: 先进后出。 队列: 先进先出。 6.数组和链表 数组: 在内存中是一片连续的空间。 查询快,增删慢。 查询快:因为可以通过数组的地址值和索引直接定位到某个元素。 增删慢:因为数组不可变,每次要添加或者删除都要创建一个新的数组。 把老数组中的元素赋值给新数组。 链表: 是多个节点组成的。 每一个节点都是单独new出来的对象,在内存中链表不是一个连续的空间。 是通过互相记录地址值实现的。 单向链表: 前一个记录后一个地址值。 但是后一个不会记录前一个地址值。 双向链表 也是由节点组成的。 前一个记录后一个地址值。 后一个也会记录前一个。 7.ArrayList 和 LinkedList ArrayList : 底层是一个数组。 特点:查询快,增删慢 LinkedList : 底层是一个双向链表。 特点:查询慢,增删快 总结: ArrayList 和 LinkedList 基本使用是一模一样的。 增 删 改 查,所写代码几乎一样。 但是在底层数据结构是不一样的。 8.LinkedList void addFirst(E e) 向集合中第一个位置添加元素 void addLast(E e) 向集合中最后一个位置添加元素 E getFirst() 获取集合中第一个元素 E getLast() 获取集合中最后一个元素 E removeFirst() 删除集合中第一个元素

每天一更 Leecode每日一题--mergeTwoLists

瘦欲@ 提交于 2020-02-26 21:33:48
题目 将两个有序链表合并为一个新的有序链表并返回。新链表是通过拼接给定的两个链表的所有节点组成的。 示例: 输入: 1 - > 2 - > 4 , 1 - > 3 - > 4 输出: 1 - > 1 - > 2 - > 3 - > 4 - > 4 来源:力扣(LeetCode) 链接:https://leetcode-cn.com/problems/merge-two-sorted-lists 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。 解题 做了这么久的题目终于有个明显的算法题 it is 链 表 题 \color{red}{链表题} 链 表 题 官方解法有两种 我只用第二种 因为好解释… 方法 2:迭代 想法 我们可以用迭代的方法来实现上述算法。我们假设 l1 元素严格比 l2元素少,我们可以将 l2 中的元素逐一插入 l1 中正确的位置。 算法 首先,我们设定一个哨兵节点 “prehead” ,这可以在最后让我们比较容易地返回合并后的链表。我们维护一个 prev 指针,我们需要做的是调整它的 next 指针。然后,我们重复以下过程,直到 l1 或者 l2 指向了 null :如果 l1 当前位置的值小于等于 l2 ,我们就把 l1 的值接在 prev 节点的后面同时将 l1 指针往后移一个。否则,我们对 l2 做同样的操作

线性表和链表的比较

谁都会走 提交于 2020-02-26 19:13:22
区别 1、存取(读写)方式 顺序表可以顺序存取,也可以随机存取;链表只能从表头顺序存取元素。 例如:在第 i 个位置上执行存取操作,顺序表只需访问一次,而链表则需要从表头开始依次访问 i 次。 2、逻辑结构与物理结构 采用顺序存取时,逻辑结构上相邻的元素,对应的物理存储位置也是相邻的;而采用链式存储时,逻辑结构上相邻的元素,物理存储位置则不一定相邻,对应的逻辑关系也是通过指针链接来表示的。 3、查找,插入和删除操作 对于按值查找,顺序表无序时,两者的时间复杂度均为O(n);当顺序表有序时,可采用折半查找,此时的时间复杂度为0(log2n); 对于按序号查找,顺序表支持随机访问,时间复杂度仅为O(1),而链表的平均时间复杂度为O(n); 顺序表的插入,删除操作,平均需要移动半个表长的元素,链表的插入,删除操作,只需要修改相关结点的指针域即可,由于链表的每个结点都带有指针域,故其存储密度不够大。 4、空间分配 顺序存储在静态存储分配情形下,一旦存储空间装满就不能扩充了,若要再加入新的元素,则会出现内存溢出,因此需要预先分配存储空间;若预先分配空间过大,可能会导致顺序表后部大量闲置,若预先分配空间过小,又会造成溢出;动态存储分配虽然存储空间可以扩充,但是需要移动大量元素,导致操作效率降低,而且若内存中没有更大块的连续存储空间,则会导致分配失败;链式存储的结点空间只在需要的时申请分配