MC logo

Table Sort Example


CS 402 Examples

Here is the table sort example from lecture. The keys are:

19 89 10 21 106 15 99 56 111 42 128

The first step is to build an index by reading the keys into an array, and associating each one with its position. This represents the location of the record which possesses the key:

[1][2][3][4][5][6][7][8][9][10][11]
1989102110615995611142128 key
1234567891011 record location

Then sort this index by the key values:

[1][2][3][4][5][6][7][8][9][10][11]
1015192142568999106111128 key
3614108275911 record location

The locations are then applied back to the yet unsorted records, where they act as "come from" indicators. That is, they tell where the record in each position should come from when the records are sorted:

[1][2][3][4][5][6][7][8][9][10][11]
1989102110615995611142128 record
3614108275911 come from

For instance, location 2 should contain the record presently at location 6.

Now the table sort algorithm begins. Note that in the index, the key values stand only for themselves. In the table sort, they stand for their entire record. It proceeds by looking for cycles. The outer loop scans through the list with the pointer cycstart to find the start of a cycle. A cycle is detected wherever a record is found which is not in its correct final position.

cystart
[1][2][3][4][5][6][7][8][9][10][11]
1989102110615995611142128 record
3614108275911 come from
cyscan

In this case, the first iteration of the outer loop detects a cycle, because position 1 should contain the record from position 3. The cycle is a chain of come from values which travels through the array back to its starting point. In the present case, the cycle we have detected at position 1 is very short: just 1, 3, and back to 1. We run the inner loop which follows that cycle. We initialize by moving the data from position 1 into a temp, and set cycscan to equal cycstart:

temp = 19
cystart
[1][2][3][4][5][6][7][8][9][10][11]
1989102110615995611142128 record
3614108275911 come from
cyscan

The inner loop executes one time: it moves the record from location 3 to 1, then moves the scanner on to 3 following the cycle:

temp = 19
cystart
[1][2][3][4][5][6][7][8][9][10][11]
1089102110615995611142128 record
1614108275911 come from
cyscan

The inner loop then exits after this single iteration, because we have reached the end of the cycle. We then leave the loop, and restore the record from temp into location 3, completing the cycle.

temp = 19
cystart
[1][2][3][4][5][6][7][8][9][10][11]
1089192110615995611142128 record
1634108275911 come from
cyscan

Notice how the come from values of positions 1 and 3 have changed to be 1 and 3, respectively, indicating that the records in those locations are the correct ones. Whenever we place a record into its correct position, we set its come from equal to its location since the location needs the record it contains.

The outer loop then advances cystart, and finds another cycle at 2, since position 2 should contain the data in position 6.

cystart
[1][2][3][4][5][6][7][8][9][10][11]
1089192110615995611142128 record
1634108275911 come from
cyscan

The cycle at this position is longer than the previous one, going 2, 6, 8, 7, 2. To see this, simply follow the chain of come from values. We prepare for the inner loop which follows the cycle:

temp = 89
cystart
[1][2][3][4][5][6][7][8][9][10][11]
1089192110615995611142128 record
1634108275911 come from
cyscan

Now, the inner loop will follow the chain of come from pointers. At each step, it moves the record into the location given by cyscan which belongs there, then advances cyscan to the next location, which is the source of the record.

temp = 89
cystart
[1][2][3][4][5][6][7][8][9][10][11]
1015192110615995611142128 record
1234108275911 come from
cyscan

temp = 89
cystart
[1][2][3][4][5][6][7][8][9][10][11]
1015192110656995611142128 record
1234106275911 come from
cyscan

temp = 89
cystart
[1][2][3][4][5][6][7][8][9][10][11]
1015192110656999911142128 record
1234106285911 come from
cyscan

Now, the inner loop halts because the cycle has been closed. We have reached the location which requires the record from the starting point. After we exit the inner loop, we move the value in temp (which originally came from location 2) into location 7.

temp = 89
cystart
[1][2][3][4][5][6][7][8][9][10][11]
1015192110656899911142128 record
1234106785911 come from
cyscan

Again, notice that whenever we move data into a location, we change the come from of the receiver to indicate that it should contain the record it does contain.

Now, the outer loop advances to position 3.

cystart
[1][2][3][4][5][6][7][8][9][10][11]
1015192110656899911142128 record
1234106785911 come from
cyscan

Since location 3 contains the data is should have, there is no cycle at 3, and the inner loop is not run. Likewise for position 4. When the outer loop reaches position 5, we find the cycle 5, 10, 9, 5, and begin the inner loop:

temp = 106
cystart
[1][2][3][4][5][6][7][8][9][10][11]
1015192110656899911142128 record
1234106785911 come from
cyscan

temp = 106
cystart
[1][2][3][4][5][6][7][8][9][10][11]
101519214256899911142128 record
123456785911 come from
cyscan

temp = 106
cystart
[1][2][3][4][5][6][7][8][9][10][11]
1015192142568999111111128 record
1234567851011 come from
cyscan

Then, leave the inner loop and restore the temp value:

temp = 106
cystart
[1][2][3][4][5][6][7][8][9][10][11]
1015192142568999106111128 record
1234567891011 come from
cyscan

We then return to the outer loop, which continues from position 6. It encounters no new cycles (all records are in position) and will quietly finish without running the inner loop again, or moving any more records.