Smaller And Smarter Python数据结构:展开链接链表(超级有趣的链表)

简介: Smaller And Smarter Python数据结构:展开链接链表(超级有趣的链表)

简说Python,号主老表,Python终身学习者,数据分析爱好者,从18年开始分享Python知识,原创文章227篇,写过Python、SQL、Excel入门文章,也写过Web开发、数据分析文章,老表还总结整理了一份2022Python学习资料和电子书资源,关注后私信回复:2022 即可领取。

今天给大家分享的书籍《Python程序员面试算法宝典》第一章第十二小节:链表进行重新排序。

如果你是第一次看,也许,你可以看看本系列下面的文章:

Smaller And Smarter Python数据结构:链表逆转Smaller And Smarter Python数据结构:删除无序链表重复结点Smaller And Smarter Python数据结构:链表相加Smaller And Smarter Python数据结构:链表进行重新排序Smaller And Smarter Python数据结构:链表倒数第K个元素+检测单链表环算法Smaller And Smarter Python数据结构:翻转链表相邻结点+k个相邻结点Smaller And Smarter Python数据结构:合并两个有序链表Smaller And Smarter Python数据结构:单链表删除给定结点,只给该结点+判断&找出交叉结点

今日问题

"""
目标:写一段程序,展开链接链表
例如:
输入-> 3 -> 10 -> 15 -> 24
      |    |    |    |
      4     11    16   26
      |    |    |    |
      7     16    19   36
      33
输出-> 3 -> 4 -> 7 -> 10 -> 11 -> 15 -> 16 -> 16 -> 19 -> 24 -> 26 -> 33 -> 36
Goal: write a program to expand the linked list
For example:
Input-> 3 -> 10 -> 15 -> 24
        |    |    |    |
        4     11    16   26
        |    |    |    |
        7     16    19   36
        33
Output - > 3 - > 4 - > 7 - > 10 - > 11 - > 15 - > 16 - > 16 - > 19 - > 24 - > 26 - > 33 - > 36
"""

趣的问题:怎么初始化和遍历这样一个链表

# 初始化特殊链表
@staticmethod
def init_snode(right_data, down_data):
    # 初始化一个头指针
    head = SNode("head")
    cur = head
    for i in range(len(right_data)):
        right_node = SNode(right_data[i])  # right,主干
        right_node.next = ListOperation.init_list(down_data[i]).next  # down
        cur.right = right_node
        cur = right_node  # 相当于 cur = cur.next,后移
    return head
# 遍历特殊链表
@staticmethod
def ergodic_s_list(head):
    right_node = head.right
    while right_node:
        print(right_node.data, end=" ")
        down_node = right_node.next
        while down_node:
            print(down_node.data, end=" ")
            down_node = down_node.next
        print()
        print("*************************")
        right_node = right_node.right

你能看懂吗?

1、 初始化时,输入两个参数

def init_snode(right_data, down_data)
right_data : 主干道结点数据域(right方向),列表类型。
down_data :down方向链表数据域,列表类型。
初始化right方向链表同时,初始化down方向链表,
每个right结点对应一个down方向链表。

2、 遍历时,输入一个参数

def ergodic_s_list(head)
head :特殊链表的头结点(right方向头结点)
遍历rigth方向链表,每遍历到一个right结点,
就按该结点遍历down方向链表。

解题前准备

首先我们写好链表的基本操作,在a_0_base.py文件中,目前包含对链表的定义类,初始化函数,遍历函数。(带头结点)

# -*- coding: utf-8 -*-
"""
@author = 老表
@date = 2019-10-19
@个人微信公众号 : 简说Python
"""
import random
# 链表数据结构定义
class ListNode:
    def __init__(self, x):
        self.data = x
        self.next = None
# 特殊链表结构定义
class SNode:
    def __init__(self, x):
        self.data = x
        self.right = None
        self.next = None
class ListOperation:
    # 根据链表数据初始化链表,带头结点
    @staticmethod
    def init_list(n_list):
        # 初始化一个头指针
        head = ListNode("head")
        cur = head
        for i in n_list:
            node = ListNode(i)
            cur.next = node
            cur = node  # 相当于 cur = cur.next,后移
        return head
    # 根据链表数据初始化链表,不带头结点
    @staticmethod
    def init_list_n(n_list):
        head = ListNode(n_list[0])
        cur = head
        for i in range(1, len(n_list)):
            node = ListNode(n_list[i])
            cur.next = node
            cur = node  # 相当于 cur = cur.next,后移
        return head
    # 根据链表数据初始化一个有环的链表
    @staticmethod
    def init_ring_list(n_list):
        # 初始化一个头指针
        head = ListNode("head")
        cur = head
        for i in n_list:
            node = ListNode(i)
            cur.next = node
            cur = node  # 相当于 cur = cur.next,后移
        cur.next = head.next.next.next.next  # 随意的,让最后一个结点指向第四个结点
        return head
    # 遍历链表,不带头结点
    @staticmethod
    def ergodic_list_n(head):
        # print(head.data)
        cur = head
        while cur:
            print(cur.data, end="   ")
            cur = cur.next
    # 遍历链表
    @staticmethod
    def ergodic_list(head):
        # print(head.data)
        cur = head.next
        while cur:
            print(cur.data)
            cur = cur.next
    # 获取链表长度
    @staticmethod
    def get_len_list(head):
        cur = head.next
        len_list = 0
        while cur:
            len_list = len_list + 1
            cur = cur.next
        return len_list
    # 随机获取一个结点
    @staticmethod
    def get_random_node(head):
        cur = head.next
        i = 0
        len_list = ListOperation.get_len_list(head)
        while cur.next:
            if i == random.randint(0, len_list-1):
                break
            cur = cur.next
        return cur
    # 制作一个随机交叉链表
    @staticmethod
    def get_random_link(n_list, head1):
        p = ListOperation.get_random_node(head1)  # 获取一个链表1的随机结点
        # 初始化一个头指针
        head = ListNode("head")
        cur = head
        for i in n_list:
            node = ListNode(i)
            cur.next = node
            cur = node  # 相当于 cur = cur.next,后移
        cur.next = p  # 将链表1的从p结点开始的后半部分,添加到当前链表后
        # 当前链表与链表1相交
        return head  # 返回新创建的链表头结点
    # 初始化特殊链表
    @staticmethod
    def init_snode(right_data, down_data):
        # 初始化一个头指针
        head = SNode("head")
        cur = head
        for i in range(len(right_data)):
            right_node = SNode(right_data[i])  # right,主干
            right_node.next = ListOperation.init_list(down_data[i]).next  # down
            cur.right = right_node
            cur = right_node  # 相当于 cur = cur.next,后移
        return head
    # 遍历特殊链表
    @staticmethod
    def ergodic_s_list(head):
        right_node = head.right
        while right_node:
            print(right_node.data, end=" ")
            down_node = right_node.next
            while down_node:
                print(down_node.data, end=" ")
                down_node = down_node.next
            print()
            print("*************************")
            right_node = right_node.right

解题

开始程序前需提前导入前面写好的链表基本操作包和结点数据结构,在Linked_list的a_0_base.py中。

from Linked_list.a_0_base import ListOperation

思路分析

"""
Method One : 归并排序(递归)法
核心思想:先遍历主干结点(right方向),递归过去,到尾结点,
然后回溯,主干结点相当于down方向的头结点,依次从后将相邻的
两个链表合并成一个有序链表,然后返回,继续合并,直至回溯结
束。
时间复杂度:O(N)
空间复杂度:O(1)
"""

辅助函数:合并两个有序链表

# 辅助函数:合并两个有序链表
def merge_list(l1, l2):
    # 如果有一个链表为空,
    # 则直接返回另一个链表
    if not l1:
        return l2
    if not l2:
        return l1
    # 判断两个链表结点数据值大小
    if l1.data < l2.data:  # 链表2的结点数据值大
        result = l1  # 链表1在前
        l1.next = merge_list(l1.next, l2)  # 递归遍历,把小结点插到后面
    else:  # 链表2的结点数据值大
        result = l2   # 链表2在前
        l2.next = merge_list(l1, l2.next)  # 递归遍历,把小结点插到后面
    return result  # 返回小结点

主功能函数

def expand_link_list_one(head):
    # 空链表直接返回头结点
    if not head or not head.right:
        return head
    root = head # 记录当前头结点(right线)
    # 递归处理主干链表
    root.right = expand_link_list_one(root.right)
    # 把root结点对应的链表与右边的链表合并
    root = merge_list(root, root.right)  # 合并两个有序链表
    return root

测试代码

# 当然,也许还有别的方法,比如建一个辅助的链表
# 欢迎你说出你的想法
# 程序入口,测试函数功能
if __name__ == "__main__":
    # 第一步:初始化特殊链表
    # 1.初始化特殊链表主干(right走向)
    right_data = [3, 10, 15, 24]  # 主干道数据,right
    list_data1 = [4, 7, 33]  # 链表1初始化数据,down
    list_data2 = [11, 16]  # 链表2初始化数据,down
    list_data3 = [16, 19]  # 链表3初始化数据,down
    list_data4 = [26, 36]  # 链表4初始化数据,down
    down_data = [list_data1, list_data2, list_data3, list_data4]  # down data
    head = ListOperation.init_snode(right_data, down_data)  # 初始化特殊链表,带头结点
    ListOperation.ergodic_s_list(head)  # 未操作前,遍历打印特殊链表
    print("___________________________")
    result = expand_link_list_one(head.right)  # 测试方法一
    head.next = result
    ListOperation.ergodic_list(head)  # 操作后,打印链表

本文代码思路部分来自书籍《Python程序员面试宝典》,书中部分代码有问题或未提供代码,文中已经修改过了,并添加上了丰厚的注释,方便大家学习,后面我会把所有内容开源放到Github上,包括代码,思路,算法图解(手绘或者电脑画),时间充裕的话,会录制视频。

希望大家多多支持。

大家好,我是老表

觉得本文不错的话,转发、留言、点赞,是对我最大的支持。

欢迎关注微信公众号:简说Python

关注后回复:1024,可以领取精选编程学习电子书籍。

相关文章
|
2月前
|
Java 数据挖掘 数据处理
(Pandas)Python做数据处理必选框架之一!(一):介绍Pandas中的两个数据结构;刨析Series:如何访问数据;数据去重、取众数、总和、标准差、方差、平均值等;判断缺失值、获取索引...
Pandas 是一个开源的数据分析和数据处理库,它是基于 Python 编程语言的。 Pandas 提供了易于使用的数据结构和数据分析工具,特别适用于处理结构化数据,如表格型数据(类似于Excel表格)。 Pandas 是数据科学和分析领域中常用的工具之一,它使得用户能够轻松地从各种数据源中导入数据,并对数据进行高效的操作和分析。 Pandas 主要引入了两种新的数据结构:Series 和 DataFrame。
390 0
|
5月前
|
存储 监控 安全
企业上网监控系统中红黑树数据结构的 Python 算法实现与应用研究
企业上网监控系统需高效处理海量数据,传统数据结构存在性能瓶颈。红黑树通过自平衡机制,确保查找、插入、删除操作的时间复杂度稳定在 O(log n),适用于网络记录存储、设备信息维护及安全事件排序等场景。本文分析红黑树的理论基础、应用场景及 Python 实现,并探讨其在企业监控系统中的实践价值,提升系统性能与稳定性。
159 1
|
12月前
|
存储 缓存 监控
局域网屏幕监控系统中的Python数据结构与算法实现
局域网屏幕监控系统用于实时捕获和监控局域网内多台设备的屏幕内容。本文介绍了一种基于Python双端队列(Deque)实现的滑动窗口数据缓存机制,以处理连续的屏幕帧数据流。通过固定长度的窗口,高效增删数据,确保低延迟显示和存储。该算法适用于数据压缩、异常检测等场景,保证系统在高负载下稳定运行。 本文转载自:https://www.vipshare.com
314 66
|
9月前
|
存储 人工智能 索引
Python数据结构:列表、元组、字典、集合
Python 中的列表、元组、字典和集合是常用数据结构。列表(List)是有序可变集合,支持增删改查操作;元组(Tuple)与列表类似但不可变,适合存储固定数据;字典(Dictionary)以键值对形式存储,无序可变,便于快速查找和修改;集合(Set)为无序不重复集合,支持高效集合运算如并集、交集等。根据需求选择合适的数据结构,可提升代码效率与可读性。
|
10月前
|
存储 机器学习/深度学习 算法
C 408—《数据结构》算法题基础篇—链表(下)
408考研——《数据结构》算法题基础篇之链表(下)。
364 30
|
10月前
|
存储 算法 C语言
C 408—《数据结构》算法题基础篇—链表(上)
408考研——《数据结构》算法题基础篇之链表(上)。
455 25
|
12月前
|
存储 运维 监控
探索局域网电脑监控软件:Python算法与数据结构的巧妙结合
在数字化时代,局域网电脑监控软件成为企业管理和IT运维的重要工具,确保数据安全和网络稳定。本文探讨其背后的关键技术——Python中的算法与数据结构,如字典用于高效存储设备信息,以及数据收集、异常检测和聚合算法提升监控效率。通过Python代码示例,展示了如何实现基本监控功能,帮助读者理解其工作原理并激发技术兴趣。
223 20
|
11月前
|
机器学习/深度学习 存储 C++
【C++数据结构——线性表】单链表的基本运算(头歌实践教学平台习题)【合集】
本内容介绍了单链表的基本运算任务,涵盖线性表的基本概念、初始化、销毁、判定是否为空表、求长度、输出、求元素值、按元素值查找、插入和删除数据元素等操作。通过C++代码示例详细解释了顺序表和链表的实现方法,并提供了测试说明、通 - **任务描述**:实现单链表的基本运算。 - **相关知识**:包括线性表的概念、初始化、销毁、判断空表、求长度、输出、求元素值、查找、插入和删除等操作。 - **测试说明**:平台会对你编写的代码进行测试,提供测试输入和预期输出。 - **通关代码**:给出了完整的C++代码实现。 - **测试结果**:展示了测试通过后的预期输出结果。 开始你的任务吧,祝你成功!
507 5
|
12月前
|
数据库
数据结构中二叉树,哈希表,顺序表,链表的比较补充
二叉搜索树,哈希表,顺序表,链表的特点的比较
数据结构中二叉树,哈希表,顺序表,链表的比较补充

热门文章

最新文章

推荐镜像

更多