JohnnyCake
JohnnyCake

Reputation: 7

Bubble Sort logical error VB.NET

This program suppose to sort records(in arySort) in ascending order by last name(index 1 in aryTemp and aryTemp2) and place the result in the list box over the old, preloaded, unsorted records.

It sorts them strangely, I have to click multiple times the Ascending button to get the actual sort result that I suppose to get from clicking the button once.

Why doesn't it sort items with a single mouse click?

The source:

Public Class Form1
    Dim FILE_NAME As String = "Students.txt"
    Dim numberOfRecords As Integer 'total number of records
    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        If System.IO.File.Exists(FILE_NAME) = True Then
            Dim objReader As New System.IO.StreamReader(FILE_NAME)
            Do While objReader.Peek() <> -1
                lstBox.Items.Add(objReader.ReadLine)
                numberOfRecords += 1
            Loop
            objReader.Close()
        End If
    End Sub

    Private Sub btnAscending_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnAscending.Click
        'load all students into array
        Dim arySort(numberOfRecords - 1) As String
        Dim aryTemp() As String 'holds first record's last name
        Dim aryTemp2() As String 'holds second record's last name
        For i = 0 To numberOfRecords - 1
            arySort(i) = lstBox.Items(i)
        Next
        Dim temp As String 'holds temporary record
        Dim k As Integer
        For i = 0 To arySort.Length - 2
            aryTemp = Split(arySort(i), " ")
            For k = i + 1 To arySort.Length - 1
                aryTemp2 = Split(arySort(k), " ")
                If aryTemp(1) < aryTemp2(1) Then
                    temp = arySort(k)
                    arySort(k) = arySort(i)
                    arySort(i) = temp
                End If
            Next
        Next
        lstBox.Items.Clear()
        numberOfRecords = 0
        For i = 0 To arySort.Length - 1
            lstBox.Items.Add(arySort(i))
            numberOfRecords += 1
        Next
    End Sub
End Class

Upvotes: 0

Views: 1601

Answers (3)

Heinzi
Heinzi

Reputation: 172390

If you just need to sort your list (as you say in the comment), don't implement your own sort mechanism but use the one of .NET:

' Define how we want to compare items '
Function compareByLastName(ByVal item1 As String, ByVal item2 As String) As Integer
    Return String.Compare(item1.Split(" ")(1), item2.Split(" ")(1))
End Function

Private Sub btnAscending_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnAscending.Click
    ' load all students into array '
    Dim arySort(numberOfRecords - 1) As String
    For i = 0 To numberOfRecords - 1
        arySort(i) = lstBox.Items(i)
    Next

    ' Use built-in .NET magic '
    Array.Sort(arySort, AddressOf compareByLastName)

    ' Write the values back into your list box '
    lstBox.Items.Clear()
    numberOfRecords = 0
    For i = 0 To arySort.Length - 1
        lstBox.Items.Add(arySort(i))
        numberOfRecords += 1
    Next
End Sub

This uses the built-in quicksort algorithm of the .NET class library. Here's the documentation of the method we are using: Array.Sort(T(), Comparison(Of T)).

Upvotes: 1

Heinzi
Heinzi

Reputation: 172390

I see a two major issues with your algorithm:

  • It's not bubble sort. Bubble sort swaps adjacent elements, i.e., it swaps i with i+1. You, on the other hand, swap some element i with the first j > i where name(i) < name(j). Maybe you should show us, in pseudo code, which algorithm you are actually trying to implement?

  • aryTemp contains element i and aryTemp2 contains some element j > i. Why do you swap the elements if aryTemp(1) < aryTemp2(1)? Isn't that already the correct order if you want your elements to be sorted ascending?

Upvotes: 0

Ali Tarhini
Ali Tarhini

Reputation: 5358

compare with my working bubble sort:

Public Sub BubbleSort(ByVal arr() As Integer)
    Dim flag As Boolean = False
    For i As Integer = 0 To arr.Length - 1
        For j As Integer = 0 To arr.Length - 2 - i
            If arr(j + 1) < arr(j) Then
                flag = True
                Dim temp As Integer = arr(j)
                arr(j) = arr(j + 1)
                arr(j + 1) = temp
            End If
        Next
        If flag = False Then Return ' no swaps =>already sorted
    Next
End Sub

Upvotes: 0

Related Questions