'NoneType'对象没有属性'next'

时间:2019-08-21 14:04:48

标签: python python-3.x quicksort singly-linked-list

我正在尝试使用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]

'''

2 个答案:

答案 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)