如何实现链表快速排序? (大部分代码完成)

时间:2013-04-03 22:21:37

标签: vb.net sorting recursion linked-list quicksort

我在visual basic中实现链表快速排序时遇到了一些困难,问题是经典的堆栈溢出。因为它是一个递归算法,我认为它是一个相当简单的我想念的东西,但我一直盯着这几个小时,在纸上追踪它 - 它只能使用三个项目或更少,有时四个。任何帮助将非常感激。

我遵循的算法是

  1. 从列表中选择一个名为pivot的元素。
  2. 对列表重新排序,使得值小于枢轴的所有元素都在枢轴之前,而值大于枢轴的所有元素都在它之后(相等的值可以是任意一种)。在此分区之后,枢轴处于其最终位置。这称为分区操作。
  3. 递归地将上述步骤应用于具有较小值的元素的子列表,并单独应用具有较大值的元素的子列表。
  4. 变量“countABC”保存列表中的项目数。

    以下是节点类的代码:

    Public Class Node
        'Each node contains the values for one value and is stored 
        'in the dynamic linked list.
        Public Name As String
        Public NextNode As Node
        Public PKey As Integer
        Public Sub New()
            'Initializes a new node
            Name = ""
            NextNode = Nothing
            PKey = 0
        End Sub
    End Class
    Public start As Node
    Public Sub New()
        'Initializes a new linked list by setting start as the first node
        start = New Node
    End Sub
    

    对于添加例程:

    Public Sub AddABC(ByVal Name As String, ByVal PKey As Integer)
        'Adds items to a dynamic linked list ordered in alphabetical order
        Dim NewNode As New Node
        Dim ptr As Node = start.NextNode
        Dim prev As Node = start
        NewNode.PKey = PKey
        While ptr IsNot Nothing AndAlso ptr.Name < NewNode.Name
            prev = ptr
            ptr = ptr.NextNode
        End While
        NewNode.Name = Name
        NewNode.NextNode = ptr
        prev.NextNode = NewNode
        countABC += 1
    End Sub
    

    排序所需的两个函数(连接列表用于连接)

    Public Function SortAlphabetically() As AllColumns
        'This is a quicksort routine that creates a new linked list 
        '(that is not saved) in alphabetical order
        If countABC > 1 Then
            Dim pivotPkey As Integer = Math.Ceiling(countABC / 2)
            Dim pivot As New Node
            Dim ptr As Node = start.NextNode
    
            While ptr IsNot Nothing
                If ptr.PKey = pivotPkey Then
                    pivot = ptr
                End If
                ptr = ptr.NextNode
            End While
    
            Dim lower As New AllColumns
            Dim higher As New AllColumns
    
            ptr = start.NextNode
    
            While ptr IsNot Nothing
                If ptr.Name < pivot.Name Then
                    lower.AddABC(ptr.Name, ptr.PKey)
                Else
                    higher.AddABC(ptr.Name, ptr.PKey)
                End If
                ptr = ptr.NextNode
            End While
    
            Return (Joinlists(lower.SortAlphabetically, pivot, 
                                             higher.SortAlphabetically))
    
        Else
            Return Me
        End If
    End Function
    
    Private Function Joinlists(ByVal lower As AllColumns, 
                               ByVal pivot As Node, 
                               ByVal higher As AllColumns) As AllColumns
        'Joins two dynamic linked lists together with a pivot value 
        'separating them
        Dim list As AllColumns = lower
        list.AddABC(pivot.Name, pivot.PKey)
    
        Dim ptr As Node = higher.start.NextNode
    
        While ptr IsNot Nothing
            list.AddABC(ptr.Name, ptr.PKey)
            ptr = ptr.NextNode
        End While
        Return list
    
    End Function
    

    感谢阅读,我希望我已经很好地解释了这个问题,并且没有遗漏任何错误(这是可能的,因为它是更大程序的一部分)。

    修改

    这是完整的类定义和第一个sub,希望能更好地解释它:

    Public Class AllColumns
    Public countABC As Integer = 0
    Public Class Node
        'Each node contains the values for one value and is stored in the dynamic linked list.
        Public Name As String
        Public NextNode As Node
        Public PKey As Integer
        Public Sub New()
            'Initialises a new node
            Name = ""
            NextNode = Nothing
            PKey = 0
        End Sub
    End Class
    
    Public start As Node
    
    Public Sub New()
        'Initialises a new linked list by setting start as the first node
        start = New Node
        countABC = 0
    End Sub
    

    是不是因为较低和较高被声明为“New Allcolumns”,它们将拥有自己的countABC值,当节点放入列表时会增加?

    我不认为例程导航到数据透视表然后对其后的所有值进行排序,例程的这部分是实际的排序,“ptr”设置为“start.nextnode”即。事先列表中的第一项。

     ptr = start.NextNode
    
        While ptr IsNot Nothing
            If ptr.Name < pivot.Name Then
                lower.AddABC(ptr.Name, ptr.PKey)
            Else
                higher.AddABC(ptr.Name, ptr.PKey)
            End If
            ptr = ptr.NextNode
        End While
    
        Return (Joinlists(lower.SortAlphabetically, pivot, 
                                         higher.SortAlphabetically))
    

    我应该首先明白这一点,道歉。

1 个答案:

答案 0 :(得分:0)

Public Function SortAlphabetically() As AllColumns
    'This is a quicksort routine that creates a new linked list 
    '(that is not saved) in alphabetical order
    If countABC > 1 Then
        ...
        Return (Joinlists(lower.SortAlphabetically, pivot, 
                                         higher.SortAlphabetically))

countABC似乎是您的全局节点数,而不是您当前正在排序的子节的节点数,因此这种情况总是如此,因此您将获得无限递归。

此外,start究竟来自哪里(哪里更新)?

最后,在我看来,您正在导航到枢轴节点,并从那里根据比较添加到左侧和右侧子列表,但是在枢轴之前的节点呢?