在Python中的链接列表的给定位置插入和删除节点

时间:2018-01-21 12:23:45

标签: python linked-list nodes

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

代码将像库中的工具架一样工作,将3种类型的信息idBookNameAuthorName存储到“Book”类的Linked List节点中。< / p>

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

他们是:

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

问题:
编译时没有错误,但是 AddBookAtPosition 不起作用,并且不显示在输出中添加的Book。此外, 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

2 个答案:

答案 0 :(得分:0)

为什么书既有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

答案 1 :(得分:0)

我认为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)