【问题标题】:Inserting and Deleting node at given position of a Linked List in Python在 Python 中的链表的给定位置插入和删除节点
【发布时间】:2018-01-21 12:23:44
【问题描述】:

我正在使用链接列表来存储由 3 个属性 idbookNameauthorName 组成的集合作为添加书籍的参数。对象在“Book”类中定义。

代码将像图书馆中的书架一样工作,将idBookNameAuthorName 三种类型的信息存储到“图书”类的链表节点中。

我现在正在研究 LinkedList 类中的 3 个不完整的方法。

他们是:

AddBookToPosition (newBook, n) - 将图书添加到所需位置“n”(例如 2) DeleteBookAtPosition (n) - 将 Book 删除到所需位置 'n'(例如 3) SortByAuthorName() - 将存储在链表中的作者姓名按升序排序。

问题:
编译时没有错误,但是 AddBookAtPosition 不起作用并且不显示在输出中添加的书。 DeleteBookAtPosition 也无法正常工作。

我需要帮助(对于 AddBookAtPosition)和删除(DeleteBookAtPosition),它们将分别添加或删除链表第 n 位置的节点,假设程序从位置 0、1、2 开始按顺序显示书籍,依此类推.

感谢您的建议。

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

class Book :
    def __init__(self,n,id,bookName,authorName):
        self.n = n
        self.id = id
        self.bookName = bookName
        self.authorName = authorName

    def print(self):
        print("Position: {}".format(self.n))
        print("Book ID: {}".format(self.id))
        print("Book Name: {}".format(self.bookName))
        print("Author Name: {}".format(self.authorName))


class LinkedList :
    def __init__(self):
        self.head = None

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

    def __len__(self):
       return len(list(self))

    def __getitem__(self, i):
        node = self.head
        if node is None:
            raise IndexError('LinkedList index out of range')
        for n in range(i-1):
            node = node.next
            if node is None:
                raise IndexError('LinkedList index out of range')
            return node

    #this will add the book to the top of the list
    def AddBookToFront (self, newBook):
        new_node = Node(newBook)
        new_node.next = self.head
        self.head = new_node

    def AddBookAtPosition (self, newBook, n):
        counter = 1
        if n == 0:
            newBook.setNext(self.head)
            self.head = newBook

        else:
            node = self.head
            while node.next is not None :
                if counter == n :
                    newBook.setNext(node.next)
                    node.setNext(newBook)
                    return
                node = node.next
                counter = counter + 1    

    def DeleteBookAtPosition(self, n):

        # If linked list is empty
        if self.head == None:
            return

        # Store head node
        temp = self.head

        # If head needs to be removed
        if n == 0:
            self.head = temp.next
            temp = None
            return

        # Find previous node of the node to be deleted
        for i in range(n -1 ):
            temp = temp.next
            if temp is None:
                break

        # If position is more than number of nodes
        if temp is None:
            return
        if temp.next is None:
            return

        # Node temp.next is the node to be deleted
        # store pointer to the next of node to be deleted
        next = temp.next.next

        # Unlink the node from linked list
        temp.next = None
        temp.next = next





    def __delitem__(self, i):
        if self.head is None:
            raise IndexError('LinkedList index out of range')
        if i == 0:
            self.head = self.head.next
        else:
            node = self.head
            for n in range(i-1):
                if node.next is None:
                    raise IndexError('LinkedList index out of range')
                node = node.next
            if node.next is None:
                raise IndexError('LinkedList index out of range')
            node.next = node.next.next



BookList = LinkedList()
BookList.AddBookToFront(Book(1, "J.R.R. Tolkien", "Lord of the Rings"))
BookList.AddBookToFront(Book(2, "Lewis Carroll", "Alice in Wonderland"))
BookList.AddBookAtPosition(Book(3, "Star Wars: Aftermath", "Chuck Wendig"), 3)

for book in BookList:
    print(book.data.n)
    print(book.data.id)
    print(book.data.bookName)
    print(book.data.authorName)

电流输出

2
Lewis Carroll
Alice in Wonderland
1
J.R.R. Tolkien
Lord of the Rings  

所需输出 - 按位置升序显示 (1,2,3)

Position : 1
Book ID : 3
Book Name: Star Wars: Aftermath
Author Name: Chuck Wendig

Position : 2
Book ID : 1
Book Name: Lord of the Rings
Author Name: J.R.R. Tolkien

【问题讨论】:

  • 为什么不直接列出书籍对象呢?然后你可以添加/删除任何你想要的对象。

标签: python linked-list nodes


【解决方案1】:

为什么 book 有 self.n 和 self.id?这本书本身不应该知道它的位置。两个链表节点都不应该知道它的位置。链表的主要功能是在插入新元素时只需要修改一个现有元素。如果您将位置存储在 Book/Node 中,您将消除所有好处,因为您必须在插入链接列表后更新所有以下元素。

首先,这样修改书:

class Book :
    def __init__(self, id, bookName, authorName):
        self.id = id
        self.bookName = bookName
        self.authorName = authorName

您可以实现自己的 LinkedList.iteritems() 方法,该方法将在您遍历节点时返回节点位置:

def iteritems(self):
    pos = 0
    for book in self:
        yield pos, book
        pos += 1

请注意,如果您在迭代链表时修改链表,它将显示错误值。使用示例:

BookList = LinkedList()
# you've mixed up book name and author name 
BookList.AddBookToFront(Book(1, "J.R.R. Tolkien", "Lord of the Rings"))
BookList.AddBookToFront(Book(2, "Lewis Carroll", "Alice in Wonderland"))
BookList.AddBookToFront(Book(3, "Donald Knuth", "C programming language"))
BookList.AddBookAtPosition(Book(4, "Star Wars: Aftermath", "Chuck Wendig"), 1)

for position, book in BookList.iteritems():
    print("Position: %s" % position)
    print("Book ID: %s" % book.data.id)
    print("Book Name: %s" % book.data.bookName)
    print("Author Name: %s" % book.data.authorName)

输出:

Position: 0
Book ID: 3
Book Name: Donald Knuth
Author name: C programming language
Position: 1
Book ID: 4
Book Name: Star Wars: Aftermath
Author name: Chuck Wendig
Position: 2
Book ID: 2
Book Name: Lewis Carroll
Author name: Alice in Wonderland
Position: 3
Book ID: 1
Book Name: J.R.R. Tolkien
Author name: Lord of the Rings

A 还为您修复了“AddBookAtPosition”,因为它不起作用。它使用“新书”而不是“新节点”:

def AddBookAtPosition(self, newBook, n):
    new_node = Node(newBook)
    counter = 1
    if n == 0:
        new_node.next = self.head
        self.head = new_node

    else:
        node = self.head
        while node.next is not None :
            if counter == n :
                new_node.next = node.next
                node.next = new_node
                return
            node = node.next
            counter = counter + 1

【讨论】:

  • 谢谢。这有助于我更好地理解。请问,如何通过添加方法“SortByBookName”让列表按升序显示书籍?你可以看看这里 - github.com/darkgenesisx/d1/blob/master/BookCollection.py
  • LinkedList 特定的排序算法可能很难开始。我认为你可以实现冒泡排序。您比较 node.data.bookNamenode.next.data.bookName 并在需要时交换它们。您从第一个节点到最后一个节点,一次又一次地执行此操作,并在从第一个节点到最后一个节点完全运行后停止它,没有任何变化(使用布尔标志)。它效率不高,但它会起作用。
【解决方案2】:

我认为 python 列表会为您完成工作。 (除非您指定为什么需要 LL)

class Book :
    def __init__(self,id,bookName,authorName):
        self.id = id
        self.bookName = bookName
        self.authorName = authorName

    def print(self):
        print("Book ID: {}".format(self.id))
        print("Book Name: {}".format(self.bookName))
        print("Author Name: {}".format(self.authorName))


BookList = list()
#to add book object using index
BookList.insert(0,Book(1, "J.R.R. Tolkien", "Lord of the Rings"))
BookList.insert(1,Book(2, "Lewis Carroll", "Alice in Wonderland"))
BookList.insert(2,Book(3, "Star Wars: Aftermath", "Chuck Wendig"))

# to remove object from list using index
del BookList[1]

#print whole list
for book in BookList:
    print(book.id)
    print(book.bookName)
    print(book.authorName)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-12-22
    • 2022-01-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-10-18
    • 1970-01-01
    相关资源
    最近更新 更多