• python中的单向链表实现


    引子

    数据结构指的是是数据的组织的方式。从单个数据到一维结构(线性表),二维结构(树),三维结构(图),都是组织数据的不同方式。

    为什么需要链表?  

    顺序表的构建需要预先知道数据大小来申请连续的存储空间,而在进行扩充时又需要进行数据的搬迁,所以使用起来并不是很灵活。

    链表结构可以充分利用计算机内存空间,实现灵活的内存动态管理。

    链表(Linked list)是一种常见的基础数据结构,是一种线性表,但是不像顺序表一样连续存储数据,而是在每一个节点(数据存储单元)里存放下一个节点的位置信息(即地址)。

    什么是单链表?

    单向链表也叫单链表,是链表中最简单的一种形式,它的每个节点包含两个域,一个信息域(元素域)和一个链接域。这个链接指向链表中的下一个节点,而最后一个节点的链接域则指向一个空值。   

     

    单链表应当支持哪些基本操作?

    • is_empty() 链表是否为空
    • length() 链表长度
    • travel() 遍历整个链表
    • add(item) 链表头部添加元素
    • append(item) 链表尾部添加元素
    • insert(pos, item) 指定位置添加元素
    • remove(item) 删除节点
    • search(item) 查找节点是否存在 

    操作图解:

    add

    insert

    remove

     

    代码实现

    注意点:

    因为没有计数,因此诸多操作都离不开遍历,何时停止不可迷糊。另外,不要忘记经常要考虑的特殊情况。如果为空会如何?如果链表中只有一个节点会如何?构造新链时,该遵循怎样的顺序?(先保证原链不断)

    class Node(object):
        def __init__(self, value):
            # 元素域
            self.value = value
            # 链接域
            self.next = None
    
    
    class LinkedListOneway(object):
        def __init__(self, node=None):
            self.__head = node
    
        def __len__(self):
            # 游标,用来遍历链表
            cur = self.__head
            # 记录遍历次数
            count = 0
            # 当前节点为None则说明已经遍历完毕
            while cur:
                count += 1
                cur = cur.next
            return count
    
        def is_empty(self):
            # 头节点不为None则不为空
            return self.__head == None
    
        def add(self, value):
            """
            头插法
            先让新节点的next指向头节点
            再将头节点替换为新节点
            顺序不可错,要先保证原链表的链不断,否则头节点后面的链会丢失
            """
            node = Node(value)
            node.next = self.__head
            self.__head = node
    
        def append(self, value):
            """尾插法"""
            node = Node(value)
            cur = self.__head
            if self.is_empty():
                self.__head = node
            else:
                while cur.next:
                    cur = cur.next
                cur.next = node
    
        def insert(self, pos, value):
            # 应对特殊情况
            if pos <= 0:
                self.add(value)
            elif pos > len(self) - 1:
                self.append(value)
            else:
                node = Node(value)
                prior = self.__head
                count = 0
                # 在插入位置的前一个节点停下
                while count < (pos - 1):
                    prior = prior.next
                    count += 1
                # 先将插入节点与节点后的节点连接,防止链表断掉,先链接后面的,再链接前面的
                node.next = prior.next
                prior.next = node
    
        def remove(self, value):
            cur = self.__head
            prior = None
            while cur:
                if value == cur.value:
                    # 判断此节点是否是头节点
                    if cur == self.__head:
                        self.__head = cur.next
                    else:
                        prior.next = cur.next
                    break
                # 还没找到节点,有继续遍历
                else:
                    prior = cur
                    cur = cur.next
    
        def search(self, value):
            cur = self.__head
            while cur:
                if value == cur.value:
                    return True
                cur = cur.next
            return False
    
        def traverse(self):
            cur = self.__head
            while cur:
                print(cur.value)
                cur = cur.next
  • 相关阅读:
    PHP header的几种用法
    Elasticsearch 学习笔记
    elsearch 安装过程中遇到的错误解决方式
    python常用模块
    python 列表和字段的相关函数
    Nginx+Redis+Ehcache大型高并发高可用三层架构总结
    Docker技术底层架构剖析
    ELK日志分析平台环境部署 (yum安装)
    禁止root直接登陆linux系统
    浅谈Rsync+Inotify实时同步
  • 原文地址:https://www.cnblogs.com/yifeixu/p/8954991.html
Copyright © 2020-2023  润新知