Reputation: 51
I need to use a quick sort to order some very large lists (thousands of items). However when I attempt this I get the exception System.StackOverflowException.
From some quick googling I know this is either from having a very large list, however I have ruled out this possibility by using the function on a small list) or from having a subroutine called recursively infinitely. Although the bit of code below does use recursion when I remove one calling of the subroutine Swap() the exception stops happening, despite Swap() not actually calling any other subroutines.
Can anyone spot anything immediately wrong with this code? It is my first time using recursion.
#Region "QuickSort"
'Subroutine for QuickSort, called upon recursively until list is sorted'
Private Sub QuickSort(ByRef list(,) As Integer, ByVal min As Integer, ByVal max As Integer) 'min is index of first term, max is index of last term'
If min < max Then 'Checks if list is sorted'
Dim pivotLoc = Partition(list, min, max) 'Gets the next pivot position'
QuickSort(list, min, pivotLoc) 'Sorts the two new sublists'
QuickSort(list, pivotLoc + 1, max)
End If
End Sub
Private Function Partition(ByRef list(,) As Integer, ByVal min As Integer, ByVal max As Integer) As Integer
Dim pivot = list(min, 0) 'Initially sets the pivot to be the minimum value in the list'
Dim leftWall = min
For i As Integer = min + 1 To max 'For each item in sublist'
If list(i, 0) < pivot Then 'If current item is less than the pivot swap it onto other side of pivot'
Swap(list, i, leftWall)
leftWall += 1 'Increment leftWall'
End If
Next
Swap(list, min, leftWall) 'When this line exists System.StackOverflowException occurs'
Return leftWall
End Function
'Subroutine that swaps values in list around using temporary storage variables'
Private Sub Swap(ByRef list(,) As Integer, ByVal x As Integer, ByVal y As Integer)
Dim tempVal = list(x, 0)
Dim tempIndex = list(x, 1)
list(x, 0) = list(y, 0)
list(x, 1) = list(y, 1)
list(y, 0) = tempVal
list(y, 1) = tempIndex
End Sub
#End Region
Thanks, Alex.
EDIT: If it helps anyone, here is the psuedo code I based it off: here
Upvotes: 0
Views: 151
Reputation: 51
This is the working solution:
#Region "QuickSort"
'Subroutine for QuickSort, called upon recursively until list is sorted'
Private Sub QuickSort(ByRef list(,) As Integer, ByVal min As Integer, ByVal max As Integer) 'min is index of first term, max is index of last term'
If min < max Then 'Checks if list is sorted'
Dim pivotLoc = Partition(list, min, max) 'Gets the next pivot position'
QuickSort(list, min, pivotLoc) 'Sorts the two new sublists'
QuickSort(list, pivotLoc + 1, max)
End If
End Sub
Private Function Partition(ByRef list(,) As Integer, ByVal min As Integer, ByVal max As Integer) As Integer
Dim pivot = list(min, 0) 'Initially sets the pivot to be the minimum value in the list'
Dim pivotIndex = list(min, 1)
Dim leftWall = min
For i As Integer = min + 1 To max 'For each item in sublist'
If list(i, 0) < pivot Then 'If current item is less than the pivot swap it onto other side of pivot'
Swap(list, i, leftWall)
leftWall += 1 'Increment leftWall'
End If
Next
'Swap(list, min, leftWall) 'When this line exists System.StackOverflowException occurs'
'Instead do this'
list(leftWall, 0) = pivot
list(leftWall, 1) = pivotIndex
Return leftWall
End Function
'Subroutine that swaps values in list around using temporary storage variables'
Private Sub Swap(ByRef list(,) As Integer, ByVal x As Integer, ByVal y As Integer)
Dim tempVal = list(x, 0)
Dim tempIndex = list(x, 1)
list(x, 0) = list(y, 0)
list(x, 1) = list(y, 1)
list(y, 0) = tempVal
list(y, 1) = tempIndex
End Sub
#End Region
Upvotes: 3