美文网首页
单向链表

单向链表

作者: zxhChex | 来源:发表于2019-09-26 08:42 被阅读0次

单向链表(单链表)是链表的一种,它由节点组成,每个节点都包含下一个节点的指针。

单链表的示意图如下:

231244591436996.jpg

表头为空,表头的后继节点是"节点10"(数据为10的节点),"节点10"的后继节点是"节点20"(数据为10的节点),...

单链表删除节点

231246130639479.jpg

删除"节点30" 删除之前:"节点20" 的后继节点为"节点30",而"节点30" 的后继节点为"节点40"。 删除之后:"节点20" 的后继节点为"节点40"。

单链表添加节点

231246431888916.jpg

在"节点10"与"节点20"之间添加"节点15" 添加之前:"节点10" 的后继节点为"节点20"。 添加之后:"节点10" 的后继节点为"节点15",而"节点15" 的后继节点为"节点20"。

单链表的特点是:节点的链接方向是单向的;相对于数组来说,单链表的的随机访问速度较慢,但是单链表删除/添加数据的效率很高。

#!/usr/bin/env python3
# -*- encoding:utf-8 -*-
"""
@author: jjcoder
@file: SingleLinkList.py
@time: 9/2/1910:56 PM
"""

class Node(object):
    """
    节点类
    表元素域elem用来存放具体的数据
    链接域next用来存放下一个节点的位置
    变量p指向链表的头节点位置,从p出发能找到表中的任意节点
    链表: 如果内存中没有一块完整的内存满足我们需要的存储(顺序表),我们可以使用链表充分利用内存空间,同样付出的代价也是高于顺序表的.
    """

    def __init__(self, elem):
        self.elem = elem
        self.next = None

class SingleLinkList(object):
    def __init__(self, node=None):
        self.__head = node

    # is_empty()链表是否为空
    def is_empty(self):
        return self.__head is None

    # length()链表的长度
    def length(self):
        # cur游标,用来移动遍历节点
        # 这里注意如果是空链表的话,也是满足条件的,但是如果count的初始值是1,就需要进行判空操作.
        cur = self.__head
        # count用来记录数量
        count = 0
        while cur is not None:
            # 这里先加1,在开始移动游标
            count += 1
            cur = cur.next
        return count

    # travel()遍历整个链表
    def travel(self):
        cur = self.__head
        while cur is not None:
            print(cur.elem, end=' ')
            print()
            cur = cur.next

    # add(item)头部插入元素
    def add(self, item):
        node = Node(item)
        # 这里如果原有的链表是空链表,也是满足效果的.
        # 为了防止后面的节点被丢弃,需要先将新的节点的next指向head指向的节点
        node.next = self.__head
        self.__head = node

    # append(item)链表尾部插入元素
    def append(self, item):
        # 通过传入的元素构建一个node节点
        node = Node(item)
        # 这里需要判断链表是否为空
        if self.is_empty():
            self.__head = node
        else:
            cur = self.__head
            # 这里需要游标走到最后一个节点停止,软后将cur.next指向node就可以了,注意与上面计算链表长度做对比.
            while cur.next is not None:
                cur = cur.next
            cur.next = node

    # insert(pos, item)指定位置插入元素
    def insert(self, pos, item):
        # 这里的pos是从0开始的
        node = Node(item)
        # 如果pos<=0理解为在头部插入元素,不支持反向插入
        if pos <= 0:
            self.add(item)
        # 如果pos>length() - 1, 就理解为在尾部插入元素,但是这里需要注意如果pos=length - 1,并不是在尾部插入元素,而是在最后面元素的前一位插入.
        elif pos > (self.length() - 1):
            self.append(item)
        else:
            cur = self.__head
            # for i in range(pos - 1):  # 这种方式也是可以的
            count = 0
            while count < (pos - 1):
                # 为防止后面的节点被丢弃,先将新节点的next区域指向cur的next区域,然后在将cur的next指向新节点
                # 这里也可以定义一个pre游标,为了方便继续使用cur游标
                count += 1
                cur = cur.next
            node.next = cur.next
            cur.next = node

    # remove(item)删除节点
    def remove(self, item):
        cur = self.__head
        pre = None
        # 如果是空链表也是满足条件的
        while cur is not None:
            if cur.elem == item:
                # 如果删除的元素恰好是首节点
                # 如果链表只有一个节点,下面的操作也满足
                # 先判断此节点是否是头节点
                if cur == self.__head:
                    self.__head = cur.next
                else:
                    # 如果删除的节点是尾节点,下面也是可以满足条件的
                    pre.next = cur.next
                break
            else:
                # 下面这两行代码顺序不能变
                pre = cur
                cur = cur.next

    # search(item)查找节点是否存在
    def search(self, item):
        cur = self.__head
        # 如果有相同的元素一样,这里不做过多的判断,只是需要找到给定的元素就可以了.
        # 特殊情况:如果链表是一个空链表,也是满足情况的.
        while cur is not None:
            if cur.elem == item:
                return True
            else:
                cur = cur.next
        return False

single_obj = SingleLinkList()

单链表的特点

链表增删元素的时间复杂度为O(1) 查找一个元素的时间复杂度为 O(n); 单链表不用像数组那样预先分配存储空间的大小,避免了空间浪费 单链表不能进行回溯操作,如:只知道链表的头节点的时候无法快读快速链表的倒数第几个节点的值。

相关文章

  • 8.单向链表SingleLinkList

    目录:1.单向链表的定义2.单向链表的图解3.单向链表定义操作4.单向链表的实现 1.单向链表的定义 2.单向链表...

  • 线性表-单向循环链表

    为了方便,本文介绍的单向循环链表不包含头节点 单向循环链表内容 单向循环链表的的定义 单向循环链表的创建 单向循环...

  • 10.单向循环链表SingleCycleLinkList

    目录:1.单向循环链表的定义2.单向循环链表的图解3.单向循环链表定义操作4.单向循环链表的实现 1.单向循环链表...

  • 数据结构与算法——线性表3

    线性表——单向循环链表 3、单向循环链表 在单向链表的基础上,单向链表的尾结点的Next指向链表的头部,就是为循环...

  • 04单向循环链表实现总结

    一、说说什么是单向循环链表? 人狠话不多. 上图. 单向循环链表就是这个样子!单向循环链表.png 与单向链表区别...

  • 数据结构基础--单向循环链表

    单向循环链表 单向循环链表是可循环的单链表,它与单链表的区别在于单向链表的最后一个元素的指针域为空,而单向循环链表...

  • 2019-12-04 Java-LinkedList源码解读

    @TOC 1、链表数据结构 链表分为单向链表和双向链表,他们的区别在于,单向链表只能单向寻址,而双向链表可以双向寻...

  • 数据结构与算法之循环链表(3.4)

    目录 单向循环链表双向循环链表约瑟夫问题如何发挥循环链表的最大威力? 一 单向循环链表 单向循环链表 - 只有一个...

  • day03-双向链表

    双向链表: 单向链表只能单向查找,双向链表可以双向查找。 啥是双向链表? 双向链表可以双向查数据,所以就不存在单向...

  • 链表

    一、单向链表 单向链表的普通实现 Java实现: Kotlin实现: 单向链表的递归实现 Java实现: 二、双向...

网友评论

      本文标题:单向链表

      本文链接:https://www.haomeiwen.com/subject/hotyyctx.html