我正在尝试使用python在单个链接列表中实现quicksort。在我的quicksort_recur()中,newhead是Node()类型,没有值,但是newhead不会在partition()中更新其值。
class Node(object):
def __init__(self, data):
super(Node, self).__init__()
self.data = data
self.next=None
class Linkedlist(object):
def __init__(self):
self.head = None
#Returns the last node of the list
def get_tail(self, node):
while node.next:
node = node.next
return node
#Partitions the list taking the last element as the pivot
def partition(self,head,end,newhead,newend):
pivot=end
prev=None
curr=head
tail=pivot
# During partition, both the head and end of the list might change
# which is updated in the newHead and newEnd variables
while curr is not pivot:
if curr.data<pivot.data:
# First node that has a value less than the pivot - becomes the new head
if newhead is None:
newhead=curr
prev=curr
curr=curr.next
else:
#If cur node is greater than pivot
#Move cur node to next of tail, and change tail
if prev:
prev.next=curr.next
temp=curr.next
curr.next=None
tail.next=curr
tail=curr
curr=temp
# If the pivot data is the smallest element in the current list,
# pivot becomes the head
if newhead is None:
newhead=pivot
newend=tail
return pivot
#here the sorting happens exclusive of the end node
def quicksort_recur(self,head,end):
lists=Linkedlist()
if head is None or head is end:
return head
newhead=Node(None)
newend=Node(None)
#Partition the list, newHead and newEnd will be updated by the partition function
pivot=lists.partition(head,end,newhead,newend)
# If pivot is the smallest element - no need to recur for the left part
if newhead is not pivot:
#Set the node before the pivot node as NULL
temp=newhead
while temp.next is not pivot:
temp=temp.next
temp.next=None
#Recur for the list before pivot
newhead=lists.quicksort_recur(newhead,temp)
#Change next of last node of the left half to pivot
temp=lists.get_tail(newhead)
temp.next=pivot
#Recur for the list after the pivot element
pivot.next=lists.quicksort_recur(pivot.next,newend)
return newhead
# The main function for quick sort. This is a wrapper over recursive
# function quickSortRecur()
def quick_sort(self,head):
lists=Linkedlist()
tail=lists.get_tail(head)
head=lists.quicksort_recur(head,tail)
return
lists=Linkedlist()
lists.head=Node(10)
l1=Node(11)
l2=Node(12)
l3=Node(13)
lists.head.next=l1
l1.next=l2
l2.next=l3
lists.quick_sort(lists.head)
10Traceback(最近通话最近):
中的文件“ C:\ Users \ Didarul Amin \ Desktop \ ML算法代码\ practice_linked_list.py”,第160行11 12 13 sort lists.quick_sort(lists.head) File "C:\Users\Didarul Amin\Desktop\ML algo code\practice_linked_list.py", line 130, in quick_sort head=lists.quicksort_recur(head,tail) File "C:\Users\Didarul Amin\Desktop\ML algo code\practice_linked_list.py", line 116, in quicksort_recur temp=temp.next AttributeError: 'NoneType' object has no attribute 'next' [Finished in 0.1s with exit code 1]
'''
答案 0 :(得分:0)
newhead=Node(None)
这是问题的根本原因。
您正在将newhead创建为Nonetype。
答案 1 :(得分:0)
替代示例。分区代码创建3个列表,元素<枢轴,元素==枢轴,元素>枢轴,在列表上递归!=枢轴,然后将它们连接起来。添加了push_back()函数。缺少pop_back(),push_front()和pop_front()。虚拟节点用于简化代码。合并排序会更快。
class Node(object):
def __init__(self, data):
super(Node, self).__init__()
self.data = data
self.next=None
class Linkedlist(object):
def __init__(self):
self.head = None
self.tail = None
def push_back(self, data):
new = Node(data)
if(self.tail is None):
self.head = self.tail = new
else:
self.tail.next = new
self.tail = new
def show(self, head, tail):
arr = []
if(head is None):
print(arr)
return
while(True):
if(head.data is not None):
arr.append(head.data)
if(head is tail):
break
head = head.next
print(arr)
def quicksort(self,head,tail):
if(head is tail): # if single node return
return head,tail
hlt = Node(None) # head, tail < pivot list
tlt = hlt
heq = Node(None) # head, tail = pivot list
teq = heq
hgt = Node(None) # head, tail > pivot list
tgt = hgt
pivot = head
curr = head
end = tail.next
while(curr is not end):
if(curr.data < pivot.data):
tlt.next = curr
tlt = curr
elif(curr.data == pivot.data):
teq.next = curr
teq = curr
else:
tgt.next = curr
tgt = curr
curr = curr.next
# self.show(hlt,tlt) # display partitioned lists
# self.show(heq,teq)
# self.show(hgt,tgt)
# print()
heq = heq.next # at least 1 node (should release node)
if(hlt is tlt): # if none < pivot
hlt = heq # (should release node)
tlt = heq
else: # else recurse on list < pivot
hlt = hlt.next # (should release node)
hlt,tlt = self.quicksort(hlt,tlt)
tlt.next = heq
if(hgt is tgt): # if none > pivot
hgt = teq # (should release node)
tgt = teq
else: # else recurse on list > pivot
hgt = hgt.next # (should release node)
hgt,tgt = self.quicksort(hgt,tgt)
teq.next = hgt
return(hlt,tgt)
def sort(self):
if (self == None): # if null reference return
return
if (self.head == None): # if empty list return
return
self.head,self.tail = self.quicksort(self.head,self.tail)
self.tail.next = None
return
lists=Linkedlist()
lists.push_back(27)
lists.push_back(35)
lists.push_back(23)
lists.push_back(22)
lists.push_back(38)
lists.push_back(26)
lists.push_back(31)
lists.push_back(24)
lists.push_back(37)
lists.push_back(25)
lists.push_back(33)
lists.push_back(32)
lists.push_back(28)
lists.push_back(36)
lists.push_back(21)
lists.push_back(34)
lists.sort()
lists.show(lists.head, lists.tail)