在单链列表中找到最小的物品并移到头部?

时间:2019-02-14 03:42:30

标签: python singly-linked-list

我最近进行了一个测验,这就是问题的模样:-

您可以使用以下Node类:

class Node:
  """Lightweight, nonpublic class for storing a singly linked node."""
  __slots__ = 'element', 'next'       # streamline memory usage

  def __init__(self, element, next):  # initialize node's fields
    self.element = element            # reference to user's element
    self.next = next                  # reference to next node

假设您有一个唯一整数的单链接列表。编写一个遍历此列表的Python方法以查找最小的元素,删除包含该值的节点,然后将最小值插入列表开头的新节点。最后,返回头指针。为简单起见,您可以假定包含最小值的节点尚未位于列表的开头(即,您将不必删除标题节点并再次添加)。

您的方法将作为参数(属于Node类型)传递到列表的开头,如以下方法签名所示:

def moveSmallest(head): 您只能使用Node类。没有其他方法(如size()等)可用。此外,您拥有的唯一指针是head(作为参数传递)。您无权访问尾指针。

例如,如果列表包含:

5→2→1→3 结果列表将包含:

1→5→2→3 提示1:这个问题有几个部分;分解问题,并考虑如何分别做每个部分。

提示2:如果需要提前退出循环,可以使用break命令。

提示3:对于空列表或仅包含一个元素的列表,没有任何关系!

我的答案:

def moveSmallest(h):
 if h==None or h.next==None:
   return h

 # find part
 temp=h
 myList=[]
 while temp!=None:
   myList.append(temp.element)
   temp=temp.next
 myList.sort()
 sv=myList[0]

 # remove part
 if h.element==sv and h.next!=None:
   h=h.next
 else:
   start=h
   while start!=None:
     if start.next.element==sv and start.next.next!=None:
       start.next=start.next.next
       break
     if start.next.element==sv and start.next.next==None:
       start.next=None
       break
     start=start.next

 # Insert part
 newNode=Node(sv)
 newNode.next=h
 h=newNode
 return h

已收到标记= 10/30

反馈我的答案:

“不应该使用排序;搜索列表应该是我们在课堂上介绍的方式。

您在列表中提前了太多,而没有检查是否存在节点。

查看“单链接列表”幻灯片,并按照示例所示回答此问题。”

如您所见,我正在列表中找到该元素并将其删除,然后将其作为头节点添加到列表中。我运行了这段代码,它工作正常。正如您在反馈中看到的那样,他说:“您在列表中前进了太多,而没有检查是否存在节点。”我的答案中的第一个if语句和“不应该使用排序;搜索列表应该是我们在课堂上介绍的方法”会注意这一点。我认为我的错误是首先使用该列表,但考虑到代码,最终得分应大于或等于20/30。你们可以检查一下还是对这个反馈意见?

1 个答案:

答案 0 :(得分:0)

  

正如您在反馈中看到的,他说:“您前进的太远了   在列表中而不检查节点是否存在。”   在我的答案中的第一个if语句之前

它没有得到照顾。函数的第一个if语句只是检查头部是否存在以及头部之后的节点是否也存在(基本上,断言链接列表中至少有两个节点)。

您所拥有的:

if h.element==sv and h.next!=None:
   h=h.next
 else:
   start=h
   while start!=None:
     if start.next.element==sv and start.next.next!=None:

如果进入while循环,您只会了解以下内容:

  1. 您的链接列表至少包含两个元素
  2. h.element!= sv或h.next ==无
  3. 当前节点不是None

但是,当前节点之后的节点(start.next)在某些时候可能为“无”-当您到达链接列表的末尾时。因此,您正在尝试访问不存在的节点。

这就是我要做的。我还没有测试过,但是我很确定这可以工作:

def moveSmallest(head):

    if head is None or head.next is None:
        return head

    # First, determine the smallest element.
    # To do this, we need to visit each node once (except the head).
    # Create a cursor that "iterates" through the nodes
    # (The cursor can start at the 2nd element because we're guaranteed the head will never have the smallest element.)
    cursor = head.next
    current_minimum = head.next.element
    while cursor is not None:
        if current_minimum > cursor.element:
            # We've found the new minimum.
            current_minimum = cursor.element
        cursor = cursor.next

    # At this point, current_minimum is the smallest element.
    # Next, go through the linked list again until right before we reach the node with the smallest element.
    cursor = head
    while cursor.next is not None:
        if cursor.next.element == current_minimum:
            # We want to reconnect the arrows.
            if cursor.next.next is None:
                cursor.next = None
            else:
                cursor.next = cursor.next.next
            break

    new_node = Node(current_minimum, head)
    head = new_node
    return head