我在visual basic中实现链表快速排序时遇到了一些困难,问题是经典的堆栈溢出。由于这是一个递归算法,我认为这是我所缺少的相当简单的东西,但我已经盯着它看了好几个小时,在纸上追踪它——它只能处理三个或更少的项目,有时是四个。任何帮助都将不胜感激。
我遵循的算法是
- 从列表中拾取一个称为轴心的元素
- 重新排序列表,使所有值小于枢轴的元素位于枢轴之前,而所有值大于枢轴的元素则位于枢轴之后(相等的值可以任意选择(。分区之后,枢轴处于其最终位置。这称为分区操作
- 将上述步骤递归应用于具有较小值的元素的子列表,并分别应用于具有较大值的元素子列表
变量"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
感谢阅读,我希望我已经很好地解释了这个问题,没有遗漏任何内容(这是可能的,因为这是一个更大程序的一部分(。
编辑
以下是完整的类定义和第一个子类,希望能更好地解释它:
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
当lower和higher被声明为"New Allcolumns"时,它们将有自己的countABC值,当节点被放入列表时,这些值会增加?
我不认为例程是导航到pivot,然后对它之后的所有值进行排序,例程的这一部分是实际排序,"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))
我应该先说得更清楚一点,道歉。
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
似乎是您的全局节点计数,而不是您当前排序的子段的节点计数,因此此条件始终为true,因此您将有无限递归。
此外,start
究竟来自哪里(它在哪里更新(?
最后,在我看来,您正在导航到pivot节点,然后根据比较添加到左右子列表中,但pivot之前的节点呢?