赞
踩
实现链表的插入,增加,查找,删除,查看长度和打印的方法。链表的介绍如下:
本次挑战中,你需要在 linkedlist.py
文件中补充类 Node
和类 LinkedList
的空缺部分。
Node
类是定义的结点类。
Node
中的 __init__
方法用于初始化结点,结点包含数据元素 data
和指向下一个结点地址的指针 next_node
。
Node
中的 __str__
方法用于返回当使用 print
输出对象时打印的信息,它需要返回结点的数据元素。
LinkedList
类是定义的链表类。
LinkedList
中的 __init__
方法用于初始化链表,参数 head
为链表头的指针。
LinkedList
中的 __len__
方法用于返回链表的结点个数,它需要返回一个数字。
LinkedList
中的 insert_to_front
方法用于在链表前面插入结点,参数 data
用于指定结点的数据元素,它需要返回插入的结点。如果 data
为 None
则返回 None
。
LinkedList
中的 append
方法用于在链表后面增加结点,参数 data
用于指定结点的数据元素,它需要返回增加的结点。如果 data
为 None
则返回 None
。
LinkedList
中的 find
方法用于查找链表中包含指定数据元素的结点,参数 data
用于指定结点的数据元素,它需要返回找到的结点。如果无法找到数据,则返回 None
。
LinkedList
中的 delete
方法用于删除链表中包含指定数据元素的结点,参数 data
用于指定结点的数据元素,它不需要返回任何值。如果链表没有结点,或者指定元素不在链表中,则不进行删除操作。
LinkedList
中的 print_list
方法用于打印链表所有结点的数据元素。它需要使用 print
函数从链表头至链表尾依次打印出结点的数据元素。
LinkedList
中的 get_all_data
方法用于将链表转化为数组,数组的元素为链表结点的数据元素,它需要返回一个数组。
linkedlist.py
文件中,且不能修改示例代码中出现的类名和函数名。linkedlist.py
文件,并复制示例代码到文件中完成补充。补充完整后点击「提交检测」,系统将会给出判定结果。- class Node(object):
-
- def __init__(self, data, next_node=None):
- ### 补充代码 ###
- pass
-
- def __str__(self):
- ### 补充代码 ###
- pass
-
-
- class LinkedList(object):
-
- def __init__(self, head=None):
- ### 补充代码 ###
- pass
-
- def __len__(self):
- ### 补充代码 ###
- pass
-
- def insert_to_front(self, data):
- ### 补充代码 ###
- pass
-
- def append(self, data):
- ### 补充代码 ###
- pass
-
- def find(self, data):
- ### 补充代码 ###
- pass
-
- def delete(self, data):
- ### 补充代码 ###
- pass
-
- def print_list(self):
- ### 补充代码 ###
- pass
-
- def get_all_data(self):
- ### 补充代码 ###
- pass
内容编译自 Donne Martin 的开源项目,该项目使用 Apache 2.0 LICENSE,我们修改了部分解题和单元测试代码以适应实验楼在线环境。
- class Node(object):
-
- def __init__(self, data, next=None):
- self.next = next
- self.data = data
-
- def __str__(self):
- return self.data
-
-
- class LinkedList(object):
-
- def __init__(self, head=None):
- self.head = head
-
- def __len__(self):
- curr = self.head
- counter = 0
- while curr is not None:
- counter += 1
- curr = curr.next
- return counter
-
- def insert_to_front(self, data):
- if data is None:
- return None
- node = Node(data, self.head)
- self.head = node
- return node
-
- def append(self, data):
- if data is None:
- return None
- node = Node(data)
- if self.head is None:
- self.head = node
- return node
- curr_node = self.head
- while curr_node.next is not None:
- curr_node = curr_node.next
- curr_node.next = node
- return node
-
- def find(self, data):
- if data is None:
- return None
- curr_node = self.head
- while curr_node is not None:
- if curr_node.data == data:
- return curr_node
- curr_node = curr_node.next
- return None
-
- def delete(self, data):
- if data is None:
- return
- if self.head is None:
- return
- if self.head.data == data:
- self.head = self.head.next
- return
- prev_node = self.head
- curr_node = self.head.next
- while curr_node is not None:
- if curr_node.data == data:
- prev_node.next = curr_node.next
- return
- prev_node = curr_node
- curr_node = curr_node.next
-
- def print_list(self):
- curr_node = self.head
- while curr_node is not None:
- print(curr_node.data)
- curr_node = curr_node.next
-
- def get_all_data(self):
- data = []
- curr_node = self.head
- while curr_node is not None:
- data.append(curr_node.data)
- curr_node = curr_node.next
- return data
上述代码定义了两个类:Node
和 LinkedList
,它们共同实现了一个简单的单向链表结构。下面是对这两个类及其方法的详细分析:
Node
类表示链表中的节点。每个节点包含两个属性:
data
:存储节点的数据。next
:指向链表中下一个节点的引用,如果这是链表的最后一个节点,则此引用为 None
。Node
类还定义了一个 __str__
方法,该方法返回节点的数据,使得在打印节点对象时,输出的是节点的数据值而不是默认的对象表示。
LinkedList
类表示整个链表,并提供了一系列方法来操作链表,包括插入、追加、查找、删除节点以及打印和获取链表中的所有数据。
__init__(self, head=None)
:构造函数,初始化链表的头节点。如果调用时没有提供头节点,则链表为空。
__len__(self)
:返回链表中节点的数量。通过遍历链表并计数来实现。
insert_to_front(self, data)
:在链表的前端插入一个新节点。如果插入的数据为 None
,则不进行任何操作。此方法通过创建一个新节点,并将其 next
指向当前的头节点,然后将新节点设置为新的头节点。
append(self, data)
:在链表的末尾追加一个新节点。如果链表为空,则新节点成为头节点。否则,遍历链表直到最后一个节点,并将其 next
指向新节点。
find(self, data)
:在链表中查找具有指定数据的节点。如果找到,则返回该节点;否则返回 None
。
delete(self, data)
:从链表中删除具有指定数据的节点。如果头节点就是要删除的节点,则更新头节点为下一个节点。否则,遍历链表找到要删除的节点的前一个节点,并将其 next
指向要删除节点的下一个节点,从而实现删除。
print_list(self)
:遍历链表并打印每个节点的数据。
get_all_data(self)
:遍历链表并将所有节点的数据收集到一个列表中返回。
这段代码实现了一个基本的单向链表结构,并提供了一系列操作链表的方法。这些方法涵盖了链表的常见操作,如插入、删除、查找、遍历等。此外,还通过 __len__
和 __str__
方法增强了链表对象的可用性和可读性。不过,需要注意的是,delete
方法在删除节点时没有直接处理被删除节点的内存释放(在Python中,由于垃圾回收机制,这通常不是问题),但在其他语言或特定情况下可能需要注意内存管理。
实现一个算法来删除链表中数据元素重复的结点。要求如下:
本次挑战中,你需要在 removedupes.py
文件中补充函数 remove_dupes
的空缺部分。
MyLinkedList
类继承“实现链表类”挑战中的 LinkedList
类。MyLinkedList
类的 remove_dupes
方法用于删除链表的重复项,它没有输入,也没有返回值。linked_list.py
到主目录下:wget -nc https://labfile.oss.aliyuncs.com/courses/1512/linked_list.py
removedupes.py
文件中,且不能修改示例代码中出现的类名和函数名。removedupes.py
文件,并复制示例代码到文件中完成补充。补充完整后点击「提交检测」,系统将会给出判定结果。- from linked_list import LinkedList
-
-
- class MyLinkedList(LinkedList):
-
- def remove_dupes(self):
- ### 补充代码 ###
- pass
内容编译自 Donne Martin 的开源项目,该项目使用 Apache 2.0 LICENSE,我们修改了部分解题和单元测试代码以适应实验楼在线环境。
- from linked_list import LinkedList
-
-
- class MyLinkedList(LinkedList):
-
- def remove_dupes(self):
- if self.head is None:
- return
- node = self.head
- seen_data = set()
- while node is not None:
- if node.data not in seen_data:
- seen_data.add(node.data)
- prev = node
- node = node.next
- else:
- prev.next = node.next
- node = node.next
这段代码定义了一个名为 MyLinkedList
的类,它继承自一个名为 LinkedList
的基类。MyLinkedList
类中添加了一个名为 remove_dupes
的方法,旨在移除链表中的重复元素。
下面是 remove_dupes
方法的详细分析:
self.head
)是否为 None
。如果是,表示链表为空,方法直接返回,不执行任何操作。node
的变量,初始化为链表的头节点(self.head
)。这个变量将用于遍历链表。seen_data
的集合,用于存储遍历过程中遇到的唯一数据值。while
循环遍历链表,直到 node
变为 None
(即遍历到链表的末尾)。node
)的数据(node.data
)是否已经在 seen_data
集合中。seen_data
集合中,并更新 prev
变量为当前节点,然后移动到下一个节点。seen_data
集合中,说明这是一个重复的数据,需要从链表中移除。通过将 prev.next
更新为 node.next
来移除当前节点,然后移动到下一个节点。通过这种方式,remove_dupes
方法能够有效地遍历链表,并移除所有重复的元素,只保留唯一的元素。注意,这个方法修改了原始链表,而不是创建一个新的链表。
实现一个算法来寻找离链表最后一个结点 k
个距离的结点,即链表倒数第 k+1
个结点,并得到此结点的数据元素。
本次挑战中,你需要在 kth_to_last.py
文件中补充函数 kth_to_last_elem
的空缺部分。
MyLinkedList
类继承“实现链表类”挑战中的 LinkedList
类。MyLinkedList
类的 kth_to_last_elem
方法用于寻找离链表最后一个结点 k
个距离的结点,参数 k
用于指定距离,它需要返回结点的数据元素。None
;如果 k
大于或等于链表的长度,也返回 None
。linked_list.py
到主目录下:wget -nc https://labfile.oss.aliyuncs.com/courses/1512/linked_list.py
kth_to_last.py
文件中,且不能修改示例代码中出现的类名和函数名。kth_to_last.py
文件,并复制示例代码到文件中完成补充。补充完整后点击「提交检测」,系统将会给出判定结果。- from linked_list import LinkedList
-
-
- class MyLinkedList(LinkedList):
-
- def kth_to_last_elem(self, k):
- ### 补充代码 ###
- pass
内容编译自 Donne Martin 的开源项目,该项目使用 Apache 2.0 LICENSE,我们修改了部分解题和单元测试代码以适应实验楼在线环境。
- from linked_list import LinkedList
-
-
- class MyLinkedList(LinkedList):
-
- def kth_to_last_elem(self, k):
- if self.head is None:
- return None
- fast = self.head
- slow = self.head
-
- # Give fast a headstart, incrementing it
- # once for k = 1, twice for k = 2, etc
- for _ in range(k):
- fast = fast.next
- # If k >= num elements, return None
- if fast is None:
- return None
-
- # Increment both pointers until fast reaches the end
- while fast.next is not None:
- fast = fast.next
- slow = slow.next
- return slow.data
这段代码定义了一个名为 MyLinkedList
的类,它继承自 LinkedList
类。MyLinkedList
类中添加了一个名为 kth_to_last_elem
的方法,该方法用于找到链表中倒数第 k
个元素的值。
检查链表是否为空:首先,方法检查链表的头节点 self.head
是否为 None
,即链表是否为空。如果为空,则直接返回 None
。
初始化两个指针:接着,方法初始化两个指针 fast
和 slow
,都指向链表的头节点 self.head
。
给 fast
指针一个“头开始”:通过循环,fast
指针先向前移动 k
步。这个步骤是为了确保 fast
和 slow
指针之间有 k
个节点的距离。如果在这个过程中 fast
指针到达链表末尾(即 fast
变为 None
),则说明链表中的元素数量少于 k
,因此方法返回 None
。
同时移动两个指针:当 fast
指针成功移动 k
步后,fast
和 slow
指针同时向前移动,直到 fast
指针到达链表末尾。这时,slow
指针指向的节点就是链表中倒数第 k
个节点。
返回结果:最后,方法返回 slow
指针指向的节点的数据值,即链表中倒数第 k
个元素的值。
这段代码通过双指针技巧有效地解决了找到链表中倒数第 k
个元素的问题。它首先确保链表不为空,并且 k
的值不超过链表的长度。然后,通过移动两个指针来找到目标节点,并返回其数据值。这种方法的时间复杂度为 O(n),其中 n 是链表的长度,因为它需要遍历整个链表。
实现一个算法来删除链表的结点。
本次挑战中,你需要在 del_node.py
文件中补充函数 delete_node
的空缺部分。
MyLinkedList
类继承“实现链表类”挑战中的 LinkedList
类。MyLinkedList
类的 delete_node
方法用于删除链表的结点,参数 node
用于指定需要删除的结点,它没有返回值。None
。None
,则不进行删除操作。linked_list.py
到主目录下:wget -nc https://labfile.oss.aliyuncs.com/courses/1512/linked_list.py
del_node.py
文件中,且不能修改示例代码中出现的类名和函数名。del_node.py
文件,并复制示例代码到文件中完成补充。补充完整后点击「提交检测」,系统将会给出判定结果。- from linked_list import LinkedList
-
-
- class MyLinkedList(LinkedList):
-
- def delete_node(self, node):
- ### 补充代码 ###
- pass
内容编译自 Donne Martin 的开源项目,该项目使用 Apache 2.0 LICENSE,我们修改了部分解题和单元测试代码以适应实验楼在线环境。
- from linked_list import LinkedList
-
-
- class MyLinkedList(LinkedList):
-
- def delete_node(self, node):
- if node is None:
- return
- if node.next is None:
- node.data = None
- else:
- node.data = node.next.data
- node.next = node.next.next
这段代码定义了一个名为 MyLinkedList
的类,它继承自一个名为 LinkedList
的类。MyLinkedList
类中添加了一个名为 delete_node
的方法,用于删除链表中的一个节点。下面是对这个方法的详细分析:
node
:这是 delete_node
方法的唯一参数,表示要删除的节点。node
是否为 None
。如果是,那么方法直接返回,不执行任何操作。node.next
是否为 None
,即判断该节点是否为链表的最后一个节点。如果是,那么将该节点的数据设置为 None
,这实际上并没有从链表中移除节点,只是清空了节点中的数据。node
不是最后一个节点,那么将 node
的数据更新为 node.next
的数据,并将 node.next
更新为 node.next.next
。这样,实际上是将 node
的下一个节点的数据移动到了 node
中,并跳过了 node
的下一个节点,从而在逻辑上“删除”了 node
的下一个节点。Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。