簡體   English   中英

Python反向鏈接列表

[英]Python Reverse a Linked List

我正在做一個實現鏈接列表以支持一些功能的Python程序,我需要做的功能之一就是反轉堆棧。 我已經制作了Node,LinkedList和Stack類,到目前為止,這是我的代碼:

class ListNode:

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

class LinkedList:

    def __init__(self):
        self.head = None # first node
        self.tail = None # last node

    def addLast(self, Object):
        newNode = ListNode(Object)
        if self.head == None:
            self.head = newNode
            self.tail = newNode
        else:
           self.tail.next = newNode
           self.tail = newNode

    def removeFirst(self):
        if self.head == None:
            return

        self.head = self.head.next
        if self.head == None:
            self.tail = None

    def removeLast(self, Object):
        if self.head == None:
            return

        current = self.head
        prev = None
        while current.next != None:
            prev = current
            current = current.next

        if prev == None:
            self.head = None
            self.tail = None
        else:
            prev.next = None
            self.tail = prev

    def get(self, index):
        current = self.head
        i = 0
        while i < index and current != None:
            current = current.next
            i = i + 1
        if current != None and index >= 0:
            return current.Object
        else:
            return None

    def size(self):
        current = self.head
        count = 0
        while current != None:
            count = count + 1
            current = current.next
        return count

    def isEmpty(self):
        return self.head == None

    def printList(self):
        if self.head != None:
            current = self.head
            while current != None:
                print(current.Object, end = ' ')
                current = current.next
        print()

# -------------------- STACK ---------------------------------------------------
class Stack:
    # constructor implementation
    def __init__(self):
        self.llist = LinkedList()

    def front(self):
        return self.llist.get(0)

    def dequeue(self):
        self.llist.removeFirst()

    def queue(self, Object):
        self.llist(Object)

    def push(self, Object):
        self.llist.addLast(Object)

    def pop(self, Object):
        self.llist.removeLast(Object)

    def printStack(self):
        self.llist.printList()

    def size(self):
        return self.llist.size()

    def isEmpty(self):
        return self.llist.isEmpty()

# ----------------------- Reverse LIST ------------------------------
def Reverse(S):
    # S is a Stack Object

這是我嘗試解決的問題:

def rRecursive( self ) :
    self._rRecursive( self.head )

def _reverseRecursive( self, n ) :
    if None != n:
      right = n.next
      if self.head != n:
        n.next = self.head
        self.head = n
      else:
        n.next = None

      self._rRecursive( right )

def Reverse(S):
    s.rRecursive()

如果這是一個普通列表,我可以使用[::-1]輕松地將其反轉,但是由於鏈表是一個對象,所以我不能。 我在想也許可以使用臨時值,以便有人可以將堆棧的開頭附加到列表中,然后以某種方式將其轉換回堆棧對象。

編輯重復項 :我的程序的目標是使用現有的Stack並反轉它。 鏈接的帖子處理的鏈接列表已經是列表格式。

def get(self, index):
        current = self.head
        i = 0
        while i < index and current != None:
            current = current.next
            i = i + 1
        if current != None and index >= 0:
            return current.Object
        else:
            return None

編輯2 :添加了我的get函數。

class Stack:
    # constructor implementation
    def __init__(self):
        self.llist = LinkedList()

    def front(self):
        return self.llist.get(0)

        # push method implementation
    def push(self, Object):
        self.llist.addLast(Object)

    def pop1(self):
        self.llist.removeLast1()

def Reverse(S): 
    new_stack = Stack()
    while not S.isEmpty():
        new_stack.push(S.front())
        S.pop1()
    return new_stack

# Current Stack after Push: 12 14 40 13
# Stack after Pop: 12 14 40
# Stack after Reversal: 12 12 12

編輯3 :添加了我的代碼的返工,它返回錯誤的反轉,第一個元素一遍又一遍。

使用基本堆棧操作來反轉堆棧非常容易。 從舊堆棧中彈出每個項目,然后將其推入新的項目。

def reverse(stack):
    new_stack = Stack()
    while not stack.isEmpty():
        new_stack.push(stack.front())
        stack.pop()
    return new_stack

您可以執行類似的操作,在重新使用堆棧對象本身的同時,破壞性地反轉StackLinkedList ,您只需要使用列表操作,而不是使用別名的堆棧操作。

說到堆棧操作,您可能會發現,如果從正面而不是背面推動和彈出,堆棧的性能會更好。 從鏈接列表的末尾刪除項目需要遍歷整個列表(以找到倒數第二個節點)。 相反,從前面添加和刪除都很快。

您不必在反轉函數中擺弄鏈接指針。 我假設您的堆棧中有pop()方法和其他基礎知識; 如果不是,則克隆您的removeFirst函數以返回已刪除的節點。

現在,遞歸功能很簡單:彈出列表的開頭,反轉剩余的堆棧(如果有),然后將彈出的節點添加到末尾。 這樣可以解決您的問題嗎?

def reverseStack(self):
    move_me = self.pop()
    if not self.isEmpty():
        return (self.reverseStack()).addLast(move_me)
    else:
        new_stack = Stack()
        return new_stack.addLast(move_me)

解決此問題的其他方法:作弊。

定義__iter__方法(在任何情況下都有意義;迭代是Python的核心行為),以使您的類型可迭代。 簡單的例子:

def __iter__(self):
    cur = self.head
    while cur is not None:
        yield cur.Object
        cur = cur.next

然后做:

values = list(self)  # Creates a list containing the current set of values
self.head = self.tail = None  # Clear existing linked list
# Add back all the values in reverse order
for value in reversed(values):
    self.addLast(value)

當然,在內存分配/重新分配開銷方面,效率可能不如適當地低。 但是效果可能很小,並且極大地簡化了實現代碼。

當然,正確地進行操作並不難,只是有些混亂(完全未經測試,但應該接近正確):

def reverse(self):
    # Start at beginning, which will be new end
    cur, last = self.head, None
    # Reverse head and tail pointers in advance
    self.head, self.tail = self.tail, self.head
    # Traverse while reversing direction of each node pointer
    while cur is not None:
        # Tuple pack and unpack allows one-line variable swap
        cur.next, cur, last = last, cur.next, cur

使用基本數據結構反轉事物的常用算法是利用堆棧是先進先出數據結構的事實。 這意味着,如果您pop直到堆疊為空,您將以與push它們相反的順序獲得它們。

但是看起來您想通過遞歸函數而不是顯式堆棧來執行此操作-在這種情況下,您的函數通常會獲取front元素, 然后對其余數據結構進行遞歸, 然后處理該第一個元素。 這樣可以使所有元素按順序排列,但是在每次遞歸調用完成時,您將以相反的順序處理它們,然后按自己的方式備份調用堆棧。 如果您需要將元素添加到反向數據結構中(而不僅僅是打印它們),則可以通過返回值來構建它,方法是:如果當前元素之后的所有內容都具有反向屬性,則只需附加該元素到最前面,您所擁有的一切都與您相反。

class Node(object):
    def __init__(self, data=None, next_node=None):
       self.data = data
       self.next = next_node


def Reverse(head):
    if head == None :
        return None
    elif head.next == None :
        return head            # returns last element from stack
    else :
        temp = head.next       # stores next element while moving forward  
        head.next = None       # removes the forward link
        li = Reverse(temp)     # returns the last element
        temp.next = head       # now do the reverse link here
        return li

def main() :
    temp4 = Node(4,None)
    temp3 = Node(3,temp4)
    temp2 = Node(2,temp3)
    head = Node(1,temp2)
    res = Reverse(head)
    while res != None :
        print(res.data)
        res = res.next
main()

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM