【问题标题】:Python Linked List Merge Sort not workingPython链表合并排序不起作用
【发布时间】:2021-06-04 06:35:10
【问题描述】:

我已经为 uni 工作了一段时间,但我似乎无法弄清楚哪里出了问题。目标是将两个已经排序的链表合并为一个排序的链表。

唯一允许我更改的函数是 merge(a,b) 函数。我检查了三次,但我不断收到以下错误:

 in __repr__
    out += str(node.weight)
AttributeError: 'ItemList' object has no attribute 'weight'

有没有人可以弄清楚我应该改变什么?我很迷茫。

我的代码:

from __future__ import annotations
from typing import Optional
from dataclasses import dataclass


@dataclass
class Node:
    weight: float
    link: Optional[Node] = None


def merge(a: ItemList, b: ItemList) -> c:
    """
    This function takes two linked lists, assumed sorted, and merges them
    in-place, without creating new Nodes, just by changing the links.
    """

    # create a new ItemList and dummynode as head:
    c = ItemList()
    c.head = Node(0)

    # List1 is empty then return b
    if a.head is None:
        c._length += len(b)
        b._length -= len(b)
        return b

    # if List2 is empty then return a
    if b.head is None:
        c._length += len(a)
        a._length -= len(a)
        return a

    # If the weight of the element of a is smaller or equal to b's weight
    if a.head.weight <= b.head.weight:

        # We assign the weight of a's head to the head of c
        c.head.weight = a.head.weight

        #Give list a a new head (depletion) and subtract one from the length of a
        a.head = a.head.link
        a._length -= 1

        # We will go through the algorithm again (recursively) to check for the element next-in-line.
        c.head.link = merge(a, b)

    # If the weight of the element of a is smaller or equal to b's weight
    else:
        # We assign the weight of a's head to the head of c
        c.head.weight = b.head.weight

        #Give list b a new head (depletion) and subtract one from the length of b
        b.head = b.head.link
        b._length -= 1

        # We will go through the algorithm again (recursively) to check for the element next-in-line.
        c.head.link = merge(a, b)

    # return the merged list
    return c

class ItemList:
    head: Optional[Node]

    def __init__(self):
        """Initialize an empty linked list for warehouse items."""

        self.head = None
        self._length = 0

    def __len__(self) -> int:
        return self._length

    def insert(self, val: int) -> ItemList:
        """Insert a new item with given weight, at the beginning of the list"""

        new_node = Node(weight=val, link=self.head)
        self.head = new_node
        self._length += 1
        return self

    def __repr__(self):
        """This function prints the list in a nice way."""

        node = self.head
        out = "["
        while node is not None:
            out += str(node.weight)
            if node.link is not None:
                out += ", "
            node = node.link
        out += "]"
        return out

warehouse = (
    ItemList()
    .insert(8)
    .insert(6)
    .insert(4)
    .insert(2)
    .insert(0)
)
warehouse2 = (
    ItemList()
    .insert(9)
    .insert(7)
    .insert(5)
    .insert(3)
    .insert(1)
)
print(merge(warehouse,warehouse2))

【问题讨论】:

  • 您的仓库是反向排序的,而您的合并似乎假设创建一个升序数组?这不是“合并排序数组”的工作方式
  • 是的,我看到它就修好了。还是不行……
  • 这一行是错误的:c.head.link = merge(a, b) 将 LinkedList 分配给 Node 项。您需要重新考虑这种数据结构的工作原理
  • 谢谢。我的老师要求函数merge 的输入是两个LinkedLists。努力让它发挥作用。如果我找到了前进的方向,我会告诉你的。
  • 我找到了!应该是c.head.link = merge(a,b).head。感谢您的观看。

标签: python linked-list mergesort


【解决方案1】:

你可以写一个递归的mergeNodes函数:

def mergeNodes(a: Node, b: Node):
    """
    This function takes two linked lists of Nodes, assumed sorted, and
    merges them into a single linked list of Nodes, in-place, without
    creating new Nodes, just by changing the links.
    """
    if a is None:
        return b
    if b is None:
        return a
    if a.head.weight <= b.head.weight:
        a.link = mergeNodes(a.link, b)
        return a
    else
        b.link = mergeNodes(a, b.link)
        return b

合并列表变得非常简单:

def merge(a: ItemList, b: ItemList) -> ItemList:
    """
    This function takes two ItemList objects, assumed sorted, and merges them
    into a new ItemList, without creating new Nodes, just by changing the links.
    the original objects are destroyed
    """

    # create a new ItemList:
    c = ItemList()
    c._length = a._length + b._length;
    c.head = mergeNodes(a.head, b.head)
    # clear the original lists because the links are no longer consistent
    a._length = 0
    a.head = None
    b._length = 0
    b.head = None
    return c

注意merge 应该是ItemList 类的方法,并将作为参数传递的列表合并到self

【讨论】:

    猜你喜欢
    • 2017-01-13
    • 2015-09-20
    • 2016-08-19
    • 1970-01-01
    • 2018-12-04
    • 2015-02-09
    • 1970-01-01
    • 2016-01-18
    相关资源
    最近更新 更多