链表

什么是数组?

倾然丶 夕夏残阳落幕 提交于 2020-02-09 23:34:24
今天要介绍的主角就是- 数组 ,数组也是数据呈线性排列的一种数据结构。与前一节中的 链表 不同,在数组中,访问数据十分简单,而添加和删除数据比较耗工夫。这和 什么是数据结构 那篇文章中讲到的姓名按拼音顺序排列的电话簿类似。 数组 如上就是数组的概念图,Blue、Yellow、Red 作为数据存储在数组中,其中 a 是数组的名字,后面 [] 中的数字表示该数据是数组中的第几个数据,该数字也就是 数组下标,下标从 0 开始计数 ,比如 Red 就是数组 a 的第 2 个数据。 那么 为什么许多编程语言中的数组都从 0 开始编号的呢 ?先别急,可以先自己思考下,将会在文末进行讲解。 从图中可以看出来,数组的数据是按 顺序存储 在内存的连续空间内的。 由于数据是存储在连续空间内的,所以每个数据的内存地址(在内存上的位置)都可以通过数组下标算出,我们也就可以借此直接访问目标数据,也就是 随机访问 。 比如现在我们想要访问 Red,如果是链表的话,只能使用指针就只能从头开始查找,但在数组中,只需要指定 a[2],便能直接访问 Red。 但是,如果想在任意位置上添加或者删除数据,数组的操作就要比链表复杂多了。这里我们尝试将 Green 添加到第 2 个位置上。 首先,在数组的末尾确保需要增加的存储空间。 为了给新数据 Green 腾出位置,要把已有数据一个个移开,首先把 Red 往后移。 然后把

PTA|《C语言程序设计(第3版)》习题11-7 奇数值结点链表 (20分)

左心房为你撑大大i 提交于 2020-02-09 20:36:49
题目 本题要求实现两个函数,分别将读入的数据存储为单链表、将链表中奇数值的结点重新组成一个新的链表。链表结点定义如下: struct ListNode { int data ; ListNode * next ; } ; 函数接口定义: struct ListNode * readlist ( ) ; struct ListNode * getodd ( struct ListNode * * L ) ; 函数readlist从标准输入读入一系列正整数,按照读入顺序建立单链表。当读到−1时表示输入结束,函数应返回指向单链表头结点的指针。 函数getodd将单链表L中奇数值的结点分离出来,重新组成一个新的链表。返回指向新链表头结点的指针,同时将L中存储的地址改为删除了奇数值结点后的链表的头结点地址(所以要传入L的指针)。 裁判测试程序样例: # include <stdio.h> # include <stdlib.h> struct ListNode { int data ; struct ListNode * next ; } ; struct ListNode * readlist ( ) ; struct ListNode * getodd ( struct ListNode * * L ) ; void printlist ( struct ListNode * L ) {

List、Set、数据结构、Collections

荒凉一梦 提交于 2020-02-09 15:14:03
第一章 数据结构 1.1 数据结构有什么用? 当你用着java里面的容器类很爽的时候,你有没有想过,怎么ArrayList就像一个无限扩充的数组,也好像链表之类的。好用吗?好用,这就是数据结构的用处,只不过你在不知不觉中使用了。 现实世界的存储,我们使用的工具和建模。每种数据结构有自己的优点和缺点,想想如果Google的数据用的是数组的存储,我们还能方便地查询到所需要的数据吗?而算法,在这么多的数据中如何做到最快的插入,查找,删除,也是在追求更快。 我们java是面向对象的语言,就好似自动档轿车,C语言好似手动档吉普。数据结构呢?是变速箱的工作原理。你完全可以不知道变速箱怎样工作,就把自动档的车子从 A点 开到 B点,而且未必就比懂得的人慢。写程序这件事,和开车一样,经验可以起到很大作用,但如果你不知道底层是怎么工作的,就永远只能开车,既不会修车,也不能造车。当然了,数据结构内容比较多,细细的学起来也是相对费功夫的,不可能达到一蹴而就。我们将常见的数据结构:堆栈、队列、数组、链表和红黑树 这几种给大家介绍一下,作为数据结构的入门,了解一下它们的特点即可。 1.2 常见的数据结构 数据存储的常用结构有:栈、队列、数组、链表和红黑树。我们分别来了解一下: 栈 栈 : stack ,又称堆栈,它是运算受限的线性表,其限制是仅允许在标的一端进行插入和删除操作,不允许在其他任何位置进行添加

单向链表的实现

岁酱吖の 提交于 2020-02-09 13:26:20
一前言 出于好奇发了点时间实现了一个简单的单向链表,本篇之中是使用单方向的方式实现,感觉不是很满意,有空应该研究一下头和尾的实现方式;数据结构有点弱,研究起来挺头疼,市面上也没有较好的书籍; 二 链表介绍 Java中ArrayList就是单向链表的实现方式(有研究过源码的读者肯定发行了ArrayList的链表实现方式是依赖于数组实现的),单向链表的查找比较慢,但是增删却很快;链表的每个节点(称为Node)都存储有一个数据(data)和下一个节点的指针(本文称为next);链表的尾节点指向null; 三 链表的实现 3.1 定义节点 节点中定义了data储存数据,方便实现使用了整型;Node类中还定义了下一个节点的指针;这样就简单实现了一个链表,前一个节点中就存储着下一个节点的引用; /** * @Author lsc * <p> 链表节点</p> */ public class Node { // 表示储存数据 public Integer data; // 表示指向下一个Node的指针 public Node next; // 构造函数 Node(){ } Node(Integer data){ this.data = data; } } 3.2 添加节点 思路 : 就是在链表的尾节点添加数据作为链表新的尾节点 /** * @Author lsc * <p> 单链表实现 </p>

力扣 OJ 234. 回文链表

蹲街弑〆低调 提交于 2020-02-09 09:19:48
题目: 请判断一个链表是否为回文链表。 示例 1: 输入: 1->2 输出: false 示例 2: 输入: 1->2->2->1 输出: true 进阶: 你能否用 O(n) 时间复杂度和 O(1) 空间复杂度解决此题? 代码: int GetLength(ListNode *p)//获取链表长度 { int ans = 0; while (p) { ans++; p = p->next; } return ans; } ListNode * Reverse(ListNode *p)//链表反转,返回新的head { if (p == NULL)return p; ListNode * q1; ListNode * q2; q1 = p->next, p->next = NULL; while (q1) { q2 = q1->next, q1->next = p, p = q1, q1 = q2; } return p; } class Solution { public: bool isPalindrome(ListNode* head) { if (head == NULL)return true; int length = GetLength(head); length = (length - 1) / 2; ListNode* p = head; while

看一遍就理解,图解单链表反转

断了今生、忘了曾经 提交于 2020-02-09 08:26:43
前言 反转链表是程序员必备的基本素养,经常在面试、笔试的过程中出现。一直觉得反转链表实现代码不是很好理解,决定搬leetcode那道经典反转链表题出来,用十多张图去解析它,希望加深大家对链表反转的理解,谢谢阅读。 leetcode的反转链表原题&答案 题目描述: 反转一个单链表。 输入: 1->2->3->4->5->NULL 输出: 5->4->3->2->1->NULL 分析: 假设存在链表 1 → 2 → 3 → Ø,我们想要把它改成 Ø ← 1 ← 2 ← 3。 在遍历列表时,将当前节点的 next 指针改为指向前一个元素。由于节点没有引用其上一个节点,因此必须事先存储其前一个元素。在更改引用之前,还需要另一个指针来存储下一个节点。不要忘记在最后返回新的头引用! 代码实现: public ListNode reverseList(ListNode head) { ListNode prev = null; ListNode curr = head; while (curr != null) { ListNode nextTemp = curr.next; curr.next = prev; prev = curr; curr = nextTemp; } return prev; } 图解链表反转代码的实现 接下来,我们图解以上代码实现,先对以上实现代码加上行号,如下:

LeetCode160题 相交链表

人走茶凉 提交于 2020-02-09 05:24:20
编写一个程序,找到两个单链表相交的起始节点。 注意: 如果两个链表没有交点,返回 null . 在返回结果后,两个链表仍须保持原有的结构。 可假定整个链表结构中没有循环。 程序尽量满足 O( n ) 时间复杂度,且仅用 O( 1 ) 内存。 思路: 指针追逐 1 class Solution160 { 2 3 public ListNode getIntersectionNode(ListNode headA, ListNode headB) { 4 ListNode p1 = headA; 5 ListNode p2 = headB; 6 7 while (p1 == p2) { 8 p1 = p1 == null ? headB : p1.next; 9 p2 = p2 == null ? headA : p2.next; 10 } 11 12 return p1; 13 } 14 } 来源: https://www.cnblogs.com/rainbow-/p/10565711.html

LeetCode160 相交链表

拥有回忆 提交于 2020-02-09 05:17:57
编写一个程序,找到两个单链表相交的起始节点。 例如,下面的两个链表: A: a1 → a2 ↘ c1 → c2 → c3 ↗ B: b1 → b2 → b3 在节点 c1 开始相交。 注意: 如果两个链表没有交点,返回 null . 在返回结果后,两个链表仍须保持原有的结构。 可假定整个链表结构中没有循环。 程序尽量满足 O( n ) 时间复杂度,且仅用 O( 1 ) 内存。 致谢: 特别感谢 @stellari 添加此问题并创建所有测试用例。 //章节 - 链表 //二、双指针技巧 //3.相交链表 /* 算法思想:一个常规方法, 如果两个链长度相同的话,那么对应的一个个比下去就能找到,所以只需要把长链表变短即可。具体算法为:分别遍历两个链表,得到分别对应的长度。然后求长度的差值,把较长的那个链表向后移动这个差值的个数,然后一一比较即可。 */ //算法实现: /** * Definition for singly-linked list. * struct ListNode { * int val; * ListNode *next; * ListNode(int x) : val(x), next(NULL) {} * }; */ /* class Solution { public: ListNode * getIntersectionNode(ListNode

leetcode 160相交链表

人盡茶涼 提交于 2020-02-09 04:12:30
暴力解法当然可以遍历两个链表,不过time O(mn) space O(1)暂且不说, 方法一:双指针, time O(m+n),space O(1) 可以对比判断环形链表的快慢指针法。 这种方法构思十分十分十分巧妙,假设有两个链表,链表A: 1 2 3 * # 和链表B: a b c d e * # ,可以得出相交的第一个节点为*。那么A长度为la=5,*前面有lapre=3个元素;B长度为lb=7,*前面有lbpre=5个元素;可以发现lbpre+la=lapre+lb。 因此,只要用两个指针,每次前进一个节点,当pA到达末尾让其指向headB,当pB到达末尾让其指向headA那么当遍历10次后,两个指针都刚好到达*处,因此得到结果。 同时,针对无解的情况,记录两个链表的长度m和n,并且记录遍历次数i如果i>m+n时还没有满足条件的节点,可以断定无解;或者记录到达NULL的次数,如果第三次到达NULL之前还没有解,那么则无解。 /** * Definition for singly-linked list. * struct ListNode { * int val; * ListNode *next; * ListNode(int x) : val(x), next(NULL) {} * }; */ class Solution { public: ListNode

160. 相交链表

。_饼干妹妹 提交于 2020-02-09 03:55:46
编写一个程序,找到两个单链表相交的起始节点。 如下面的两个链表: 在节点 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], listB =