链表(维基百科)

链表(Linked list)是一种常见的基础数据结构,是一种线性表,但是并不会按线性的顺序存储数据,而是在每一个节点里存到下一个节点的指针(Pointer)。由于不必须按顺序存储,链表在插入的时候可以达到O(1)的复杂度,比另一种线性表顺序表快得多,但是查找一个节点或者访问特定编号的节点则需要O(n)的时间,而顺序表相应的时间复杂度分别是O(logn)和O(1)。使用链表结构可以克服数组链表需要预先知道数据大小的缺点,链表结构可以充分利用计算机内存空间,实现灵活的内存动态管理。但是链表失去了数组随机读取的优点,同时链表由于增加了结点的指针域,空间开销比较大。在计算机科学中,链表作为一种基础的数据结构可以用来生成其它类型的数据结构。链表通常由一连串节点组成,每个节点包含任意的实例数据(data fields)和一或两个用来指向上一个/或下一个节点的位置的链接("links")。链表最明显的好处就是,常规数组排列关联项目的方式可能不同于这些数据项目在记忆体或磁盘上顺序,数据的访问往往要在不同的排列顺序中转换。而链表是一种自我指示数据类型,因为它包含指向另一个相同类型的数据的指针(链接)。链表允许插入和移除表上任意位置上的节点,但是不允许随机存取。链表有很多种不同的类型:单向链表,双向链表以及循环链表。单向链表(又名单链表、线性链表)是链表的一种,其特点是链表的链接方向是单向的,对链表的访问要通过从头部开始,依序往下读取.

定义

我们来看一下单向链表的定义实现:

class ListNode(object):
def __init__(self, value):
self.value = value
self.next = None

 一个节点有value的属性定义该节点的值,还有一个next的指针,指向下一个节点,类似于1>2>4>5>6>3这样。

操作

单向链表的操作主要有:添加一个节点,删除一个节点,遍历一条链表,具体的实现如下:

def add(pre, new_node):
"""
pre节点后面插入一个新的节点
:param pre: pre节点
:param new_node: 新插入的节点
:return:
"""
new_code.next = pre.next
pre.next = new_node def delete(pre):
"""
pre节点的后面删除一个节点
:return:
"""
if pre.next:
pre.next = pre.next.next def traverse(head):
while head:
print(head.value)
head = head.next

  在pre节点后面插入一个节点:只需要把新节点的指针指向pre节点指针指向的节点,把pre节点的指针指向新节点。

  在pre节点后面删除一个节点:只需要把pre节点的指针指向pre节点的指针的指针节点(要注意pre节点的指针不为None)

题目

我们来看一个关于链表的一个算法题,来自于leetcode:

删除链表中的元素

删除链表中等于给定值 val 的所有元素。

示例
给定: 1 --> 2 --> 6 --> 3 --> 4 --> 5 --> 6, val = 6
返回: 1 --> 2 --> 3 --> 4 --> 5

分析:一般来讲,我们首先会考虑到遍历一下这个链表,移除掉value值等于给定val的节点就好。但是这里要返回一个新的链表,我们知道,对于单向链表,我们只能知道当前元素的后置节点,而不知道当前元素的前置节点。所以我们要构建一个前置节点。

   看代码:

def removeElements(head, val):
""" :param head: listNode
:param val: int
:return: listNode
"""
dump = ListNode(-1)
dump.next = head
cur = head
pre = dump
while cur:
if cur.value == val:
pre.next = cur.next
else:
pre = pre.next
cur = cur.next return dump.next

  我们构建一个dump节点作为第一个节点,cur节点为当前循环的节点,pre节点为cur节点的前置节点。

  当前节点的value为给定val的时候,把当前cur的前置节点pre指针指向cur的后置节点,也就是cur.next。然后接着遍历这个链表。

  由于第一个节点dump是我们自己构造的(我用的值是-1,你可以用其他不为val的值,一般使用-1),它的next是给出的head,我们只是对head做了调整。所以最后新的列表就是dump.next,也就是调整后的head。

学习技术交流群:226704167,愿和各位一起进步!

数据结构与算法 —— 链表linked list(01)的更多相关文章

  1. 数据结构与算法 —— 链表linked list(03)

    继续关于linked list的算法题: 删除排序链表中的重复元素 给定一个排序链表,删除所有重复的元素使得每个元素只留下一个. 案例: 给定 1->1->2,返回 1->2 给定  ...

  2. 数据结构与算法 —— 链表linked list(06)

    回文链表 链接 请检查一个链表是否为回文链表. 进阶:你能在 O(n) 的时间和 O(1) 的额外空间中做到吗? 解题思路: 回文链表的特点就是对称. 把链表放到栈中去,利用栈的先进后出的规则,和原链 ...

  3. 数据结构与算法——链表 Linked List(单链表、双向链表、单向环形链表-Josephu 问题)

    链表是有序的列表,但是在内存中存储图下图所示 链表是以 节点 的方式来存储,是 链式存储 每个节点包含 data 域.next 域,指向下一个节点 链表的各个节点 不一定是连续存储,如上图所示 链表还 ...

  4. 数据结构与算法 —— 链表linked list(02)

    我们继续来看链表的第二道题,来自于leetcode: 两数相加 给定两个非空链表来代表两个非负整数,位数按照逆序方式存储,它们的每个节点只存储单个数字.将这两数相加会返回一个新的链表. 你可以假设除了 ...

  5. 数据结构与算法 —— 链表linked list(04)

    我们在上篇文章里面提到了链表的翻转,给定一个链表,对每两个相邻的节点作交换,并返回头节点,今天的这道题是它的升级版,如下: k个一组翻转链表 给出一个链表,每 k 个节点一组进行翻转,并返回翻转后的链 ...

  6. 数据结构与算法 —— 链表linked list(05)

    反转一个单链表. 进阶:链表可以迭代或递归地反转.你能否两个都实现一遍? 示例 : 给定这个链表:1->2->3->4->5 返回结果: 5->4->3->2 ...

  7. JavaScript数据结构与算法-链表练习

    链表的实现 一. 单向链表 // Node类 function Node (element) { this.element = element; this.next = null; } // Link ...

  8. python数据结构与算法——链表

    具体的数据结构可以参考下面的这两篇博客: python 数据结构之单链表的实现: http://www.cnblogs.com/yupeng/p/3413763.html python 数据结构之双向 ...

  9. 《数据结构与算法之美》 <01>复杂度分析(上):如何分析、统计算法的执行效率和资源消耗?

    我们都知道,数据结构和算法本身解决的是“快”和“省”的问题,即如何让代码运行得更快,如何让代码更省存储空间.所以,执行效率是算法一个非常重要的考量指标. 那如何来衡量你编写的算法代码的执行效率呢?这里 ...

随机推荐

  1. 论文学习:Fully Convolutional Networks for Semantic Segmentation

    发表于2015年这篇<Fully Convolutional Networks for Semantic Segmentation>在图像语义分割领域举足轻重. 1 CNN 与 FCN 通 ...

  2. 【Spring源码分析】AOP源码解析(上篇)

    前言 前面写了六篇文章详细地分析了Spring Bean加载流程,这部分完了之后就要进入一个比较困难的部分了,就是AOP的实现原理分析.为了探究AOP实现原理,首先定义几个类,一个Dao接口: pub ...

  3. 【经验随笔】Java通过代理访问互联网平台提供的WebService接口的一种方法

    背景 通常有两点原因需要通过代理访问互联网平台的提供的WebService接口: 1. 在公司企业内网访问外部互联网平台发布的接口,公司要求通过代理访问外网. 2. 频繁访问平台接口,IP被平台封了, ...

  4. javaScript数组操作整理

    一.js数组 1.创建数组: var arr = new Array();//创建没有元素空数组 var arr1 = new Array("value1","valeu ...

  5. c# List实现原理

    在研究前辈们写的代码,总是搞不明白.word文中引文的索引和引文列表中的索引对应关系是什么呢?是如何对应上的?我冥思苦想,昨天又系统地看了下代码,才所有悟,所以记录下我的探索过程. 如下图所示: 图1 ...

  6. static与final的区别

    final被修饰的变量为常量一旦赋值不能修改,被修改的方法为最终方法不能被重写,被修饰的类是最终类,不能被继承static被修饰的变量和方法,为该整个类及其类的对象所共享,一个类或对象修改了被定义的类 ...

  7. pycharm中的光标变粗的问题

    pycharm中的光标变粗后不能自动打成对的小括号和中括号及引号---->解决办法:按下insert键  按下:insert键进行切换

  8. go语言的数组和切片区别

    这里不介绍数组和切片的使用技巧,主要看下2者的区别. 首先看下它们的定义: 数组:类型 [n]T 表示拥有 n 个 T 类型的值的数组. 切片:类型 []T 表示一个元素类型为 T 的切片. 看一个数 ...

  9. FNV算法实战

    HASH算法介绍 Hash,一般翻译做"散列",也有直接音译为"哈希"的,就是把任意长度的输入(又叫做预映射, pre-image),通过散列算法,变换成固定长 ...

  10. 第一迭代目标——future weather

    第一个迭代目标(主要数据) 引导界面.获取天气数据(api接口).天气分享 人员工作分配: 引导界面:周子静,界面的引导,耗时3天 获取天气数据:包舒婷.俞先浩,api接口,耗时5天 天气分享:郭磊蕾 ...