News:

Let's find out together what makes a PIC Tick!

Main Menu

Sorting Question ?

Started by Craig, Oct 15, 2021, 09:15 PM

Previous topic - Next topic

Craig

Hi

I have a lot of Byte Variables (About 30 each) to Compare and Sort From the LOWEST to the Highest. I have to ALWAYS choose the LOWEST Value in the sort and use it.
I have looked at the Bubble sorting but, These Values are loaded into byte variables and I have to keep track of the Variable Names as I use them later to attach other Variables to. If I push them into an Array and do a Bubble Sort then I will Not Know which Value is attached to Which Variable Name?
 
I have been using the following statements but, What I was wondering is there not a less cumbersome way of doing this which is more practical and efficient?

Some of the Variables will have a Value of "0" Zero.

Any Ideas will be very Much appreciated!

Regards
Craig

'___________________________________________________________________________
' Small Example Code Snippet
'___________________________________________________________________________

Sorting:
   If LH1A > 0 Then                     ' If Bigger than 0 Go Into the Loop
    If LH1A < LH1B Or LH1B = 0 Then
    LH1A_Hold = LH1A
    ElseIf LH1A < LH1C Or LH1C = 0 Then
           LH1A_Hold = LH1A
    ElseIf LH1A < LH1D Or LH1D = 0 Then
           LH1A_Hold = LH1A 
    ElseIf LH1A < LH1E Or LH1E = 0 Then
           LH1A_Hold = LH1A   
    ElseIf LH1A < LH2A Or LH2A = 0 Then
           LH1A_Hold = LH1A 
    ElseIf LH1A < LH2B Or LH2B = 0 Then
           LH1A_Hold = LH1A
    ........................
    .....................
    .................. etc.
    EndIf
    Else   LH1A = 0
    EndIf


    If LH1B > 0 Then                    ' If Bigger than 0 Go Into the Loop
    If LH1B < LH1C Or LH1C = 0 Then
       LH1B_Hold = LH1B   
    ElseIf LH1B < LH1D Or LH1D = 0 Then
           LH1B_Hold = LH1B
    ElseIf LH1B < LH1E Or LH1E = 0 Then
           LH1B_Hold = LH1B
    ElseIf LH1B < LH2A Or LH2A = 0 Then
           LH1B_Hold = LH1B
    ElseIf LH1B < LH2B Or LH2B = 0 Then
           LH1B_Hold = LH1B
    ElseIf LH1B < LH2C Or LH2C = 0 Then
           LH1B_Hold = LH1B
    ........................
    .....................
    .................. etc.
    EndIf
    Else    LH1B = 0
    EndIf

Return

trastikata

#1
Do you have enough RAM for an additional Word array to put the sorted result into? Using kind of insertion sort, the Low Byte can hold the value and the High byte can hold the original array position.

 

top204

#2
With the Positron compilers, individual variables can be aliased to the elements within an array, and this is unique to the compilers. So the following program may do as you want because the variables are aliased to a holding array that is then sorted low value to high value. This means that each individual aliased variable is also sorted. :-)

'
'   /\\\\\\\\\
'  /\\\///////\\\
'  \/\\\     \/\\\                                                 /\\\          /\\\
'   \/\\\\\\\\\\\/        /\\\\\     /\\\\\\\\\\     /\\\\\\\\   /\\\\\\\\\\\  /\\\\\\\\\\\  /\\\\\\\\\
'    \/\\\//////\\\      /\\\///\\\  \/\\\//////    /\\\/////\\\ \////\\\////  \////\\\////  \////////\\\
'     \/\\\    \//\\\    /\\\  \//\\\ \/\\\\\\\\\\  /\\\\\\\\\\\     \/\\\         \/\\\        /\\\\\\\\\\
'      \/\\\     \//\\\  \//\\\  /\\\  \////////\\\ \//\\///////      \/\\\ /\\     \/\\\ /\\   /\\\/////\\\
'       \/\\\      \//\\\  \///\\\\\/    /\\\\\\\\\\  \//\\\\\\\\\\    \//\\\\\      \//\\\\\   \//\\\\\\\\/\\
'        \///        \///     \/////     \//////////    \//////////      \/////        \/////     \////////\//
'                                  Let's find out together what makes a PIC Tick!
'
' Sort an array and alias individual variables to it
' Note that this program is not suitable for the legacy standard 14-bit core devices because of their fragmented RAM
'
' Written for the Positron8 BASIC compiler by Les Johnson
'
    Device = 18F25K20
    Declare Xtal = 16
'
' Setup USART1
'
    Declare Hserial_Baud = 9600
    Declare HRSOut1_Pin = PORTC.6
'
' Create some variables for the demo
'
    Dim bHolderArray[10] As Byte          ' Create a holding array, so the variables can be aliased to its elements
'
' Alias the individual variables to the holder array's elements, so when it is sorted, so are the variables
'   
    Dim bLH1A As bHolderArray#0
    Dim bLH1B As bHolderArray#1
    Dim bLH1C As bHolderArray#2
    Dim bLH1D As bHolderArray#3
    Dim bLH1E As bHolderArray#4
    Dim bLH1F As bHolderArray#5
    Dim bLH1G As bHolderArray#6
    Dim bLH1H As bHolderArray#7
    Dim bLH1I As bHolderArray#8
    Dim bLH1J As bHolderArray#9 
   
'----------------------------------------------------------------
' The main program starts here
' Sort a set of aliased variables low value to high value and transmit the ASCII decimal values on a serial terminal
'
Main:
'
' Load the variables with misc values
'
    bLH1A = 190
    bLH1B = 30
    bLH1C = 20
    bLH1D = 70
    bLH1E = 50
    bLH1F = 20
    bLH1G = 80
    bLH1H = 120
    bLH1I = 130
    bLH1J = 100
'
' Display the unsorted variables on a serial terminal
'
    HRSOutLn "Before"     
    HRSOutLn Dec bLH1A, ",",
             Dec bLH1B, ",",
             Dec bLH1C, ",",
             Dec bLH1D, ",",
             Dec bLH1E, ",",
             Dec bLH1F, ",",
             Dec bLH1G, ",",
             Dec bLH1H, ",",
             Dec bLH1I, ",",
             Dec bLH1J
   
    Sort8(bHolderArray, SizeOf(bHolderArray))   ' Sort the array, holding the aliased variables, low value to high value
'
' Display the sorted variables on a serial terminal
'   
    HRSOutLn "After"
    HRSOutLn Dec bLH1A, ",",
             Dec bLH1B, ",",
             Dec bLH1C, ",",
             Dec bLH1D, ",",
             Dec bLH1E, ",",
             Dec bLH1F, ",",
             Dec bLH1G, ",",
             Dec bLH1H, ",",
             Dec bLH1I, ",",
             Dec bLH1J

'----------------------------------------------------------------
' An unsigned 8-bit bubble sort procedure that uses indirect access to the array passed to it
' Input     : pArrayAddr holds the address of the Byte array to sort
'           : pArraySize holds the size of the array to sort (length 2 to 255)
' Output    : Sorts the array passed to it
' Notes     : None
'
Proc Sort8(ByRef pArrayAddr As Word, pArraySize As Byte)
    Dim tSwap_Occured As Bit                                    ' Indicates if the sort is complete
    Dim bElementCount As Byte                                   ' Holds a count of the size of the array being sorted
    Dim bElement_0    As Byte                                   ' Holds the value of an element within the array being sorted
    Dim bElement_1    As Byte                                   ' Holds the value of an element + 1 within the array being sorted
    Dim wArrayAddress As Word = pArrayAddr                      ' Place the start address of the array into a working variable

    Repeat                                                      ' Create a loop until the sorting is complete
        wArrayAddress = pArrayAddr                              ' Place the start address of the array into wArrayAddress
        tSwap_Occured = 0                                       ' Clear the flag that indicates a swap occured
        bElementCount = 1                                       ' Reset the array element counter
        Repeat                                                  ' Loop for each element of the array...
            bElement_0 = Ptr8(wArrayAddress++)                  ' Extract an element from the array then increment the address
            bElement_1 = Ptr8(wArrayAddress--)                  ' Extract an element from the array then decrement the address
            If bElement_0 > bElement_1 Then                     ' Is the contents of element + 0 greater than the contents of element + 1?
                Ptr8(wArrayAddress++) = bElement_1              ' Yes. So store the element + 1 into element + 0 then increment the address
                Ptr8(wArrayAddress) = bElement_0                ' Store element + 0 into element + 1
                tSwap_Occured = 1                               ' Set the flag if a swap occurred
            Else                                                ' Otherwise....
                Inc wArrayAddress                               ' Increment the array address to examine the next element pair
            EndIf
            Inc bElementCount                                   ' Check the next element of the array
        Until bElementCount = pArraySize                        ' Until the end of the array is reached
    Until tSwap_Occured = 0                                     ' Keep sorting until no more swaps occur
EndProc

On the serial terminal, you will see:

Before
190,30,20,70,50,20,80,120,130,100
After
20,20,30,50,70,80,100,120,130,190


So in the demo listing above, you will know that variable bLH1A will always hold the lowest value (or one of the lowest values), and bLH1J will always hold the highest value (or one of the highest values).

Craig

Thank you Trastikata for your idea, I Do Have a bit of extra Ram for the Array.

Regards
Craig


Craig

Thank you Les for your beautifully Written code that is exactly what I was looking for and it will work like a treat.
Les Thank you for All your Kindness and Always Helping I Very much appreciate it.
Kind Regards

Craig

top204

#5
Many thanks for you kind words Craig. I'm glad it worked for you. :-)

I wish I had the time and money to write a few books for the Positron compilers, full of the clear code listings that I create naturally. :-) I have seen far too many listings in books and, so called, professional applications that are just dreadful! I create the code like that for my own use as well, but when writing for a third party, it is vitally important to make the code clear and understandable, with comments that do not get in the way of the actual code, but explain what the code is doing, and, sometimes, why the code is doing what it does.

I have so many ideas for projects in a book, but not the means to achieve it. :-(