Python链表指定位置增删节点问题求助(含Book类实现)
Let's walk through the bugs in your code and fix them one by one. First, let's note the core issues breaking your add/delete functions:
1. Critical Bug: Book Class Constructor Mismatch
Looking at how you create Book instances:
BookList.AddBookToFront(Book(1, "J.R.R. Tolkien", "Lord of the Rings"))
But your Book constructor expects 4 parameters (n, id, bookName, authorName) and you're only passing 3—plus the order is wrong! This means your id, bookName, and authorName properties are all assigned incorrectly. We'll fix the constructor calls and rename parameters for clarity.
2. Fixing AddBookAtPosition
Your current method has two major flaws:
- You're trying to call
setNext()on aBookobject (which doesn't exist) instead of wrapping the book in aNode(your linked list storesNodeobjects, not rawBooks). - The position counting logic is off (you start at 1 for a 0-indexed list, and can't add to the end of the list).
Here's the corrected method:
def AddBookAtPosition(self, newBook, n): # Wrap the new book in a Node (required for your linked list structure) new_node = Node(newBook) # Case 1: Add to the front (position 0) if n == 0: new_node.next = self.head self.head = new_node return # Case 2: Traverse to the node just before the target position current = self.head for _ in range(n - 1): if current is None: raise IndexError("Position out of range") current = current.next # Insert the new node between current and current.next new_node.next = current.next current.next = new_node
Key fixes:
- Created a
Nodefor the new book (matches howAddBookToFrontworks) - Adjusted the loop to correctly navigate to the pre-target node for 0-indexed positions
- Added error handling for out-of-bounds positions
3. Fixing DeleteBookAtPosition
Your delete method silently fails for out-of-bounds positions and has a logic error in finding the pre-target node. Here's the corrected version:
def DeleteBookAtPosition(self, n): # Handle empty list case if self.head is None: raise IndexError("Cannot delete from empty list") # Case 1: Delete the head node (position 0) if n == 0: self.head = self.head.next return # Case 2: Find the node before the one to delete current = self.head for _ in range(n - 1): current = current.next if current is None or current.next is None: raise IndexError("Position out of range") # Unlink the target node from the list node_to_delete = current.next current.next = node_to_delete.next node_to_delete = None # Clean up unused reference
Key fixes:
- Added explicit error raising for empty lists and invalid positions (no more silent failures)
- Fixed the loop to ensure we don't try to delete a non-existent node
- Cleaned up the deleted node reference
4. Bonus: Fix getitem (Used Internally)
Your __getitem__ method was returning the wrong node (stopped at i-1 steps instead of i). Here's the corrected version:
def __getitem__(self, i): node = self.head if node is None: raise IndexError('LinkedList index out of range') for _ in range(i): node = node.next if node is None: raise IndexError('LinkedList index out of range') return node
Full Corrected Code
Here's the complete working code with all fixes, plus adjusted Book constructor calls:
class Node : def __init__(self, data=None, next=None): self.data = data self.next = next # Fixed: originally hardcoded to None, now uses passed value class Book : def __init__(self, position, book_id, book_name, author_name): # Renamed parameters for clarity self.position = position self.id = book_id self.bookName = book_name self.authorName = author_name def print(self): print("Position: {}".format(self.position)) 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 _ in range(i): node = node.next if node is None: raise IndexError('LinkedList index out of range') return node def AddBookToFront (self, newBook): new_node = Node(newBook) new_node.next = self.head self.head = new_node def AddBookAtPosition(self, newBook, n): new_node = Node(newBook) if n == 0: new_node.next = self.head self.head = new_node return current = self.head for _ in range(n - 1): if current is None: raise IndexError("Position out of range") current = current.next new_node.next = current.next current.next = new_node def DeleteBookAtPosition(self, n): if self.head is None: raise IndexError("Cannot delete from empty list") if n == 0: self.head = self.head.next return current = self.head for _ in range(n - 1): current = current.next if current is None or current.next is None: raise IndexError("Position out of range") node_to_delete = current.next current.next = node_to_delete.next node_to_delete = None 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 _ 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 # Fixed Book constructor calls (4 arguments in correct order) BookList = LinkedList() BookList.AddBookToFront(Book(2, 1, "Lord of the Rings", "J.R.R. Tolkien")) BookList.AddBookToFront(Book(1, 2, "Alice in Wonderland", "Lewis Carroll")) # Add to position 2 (0-indexed, end of the current list) BookList.AddBookAtPosition(Book(3, 3, "Star Wars: Aftermath", "Chuck Wendig"), 2) # Print all books for book_node in BookList: book_node.data.print() print("---")
Expected Output
Position: 1 Book ID: 2 Book Name: Alice in Wonderland Author Name: Lewis Carroll --- Position: 2 Book ID: 1 Book Name: Lord of the Rings Author Name: J.R.R. Tolkien --- Position: 3 Book ID: 3 Book Name: Star Wars: Aftermath Author Name: Chuck Wendig ---
内容的提问来源于stack exchange,提问作者Daniel

