Notes 11:
Addendum to Essentials of Data Structures, Cpt 11

Math 61 -- D. C. Smolarski, S.J.
Santa Clara University, Department of Mathematics and Computer Science

[Return to Math 61 Homepage | Return to Notes Listing Page]

Contents


Heapsort

(DCS sec. 11.1, pp 128ff) (Cf. F&T, sec 13.2, pp 688ff)

The definition of the class Heap is found in F&T p 690 and the core section of the HeapSort code is found on p 703 with other methods on previous pages.

Quicksort

(DCS sec. 11.2, pp 135ff) (Cf. F&T, sec 14.2, pp 786ff)

The QuickSort code is found on pg 791 in F&T. This book implements the Quicksort algorithm in an "integrated" fashion in this sense. The code that many books separate into an independent "split" procedure has been included into the body of the Quicksort code.

The "split" section of the code works this way:

Thus, for the initial array used in the other examples, we get the following states:

Addendum: Statistics on Various Sorting Routines

The following chart and accompanying notes are taken from Niklaus Wirth's first Data Structures book, Data Structures + Algorithms = Programs. (Wirth is the Swiss Computer Scientist who wrote the language Pascal and its successors.) There are similar figures given in F&T on pagees 794-95. The numbers refer to the time (in milliseconds) consumed by the various sorting methods executed in Pascal on a CDC 6400 computer (in the early 1970's).

In each of the three categories, the left column refers to a list of 256 items, while the right column refers to a list of 512 items.

(It is an interesting exercise to approximate the difference in time between the two numbers, based on the fact that the second refers to a list that is double the first.)

It should be noted from examining the data that

Sorting MethodOrderedRandom Inversely Ordered
Straight insertion12 23 366 1444 704 2836
Binary insertion56 125 373 1327 662 2490
Straight selection4891907 5091956 6952675
Bubblesort5402165 10264054 14925931
Bubblesort w/flag58 11044270 16456542
Shakersort59 9613642 16196520
Shellsort58116 127349 157492
Heapsort116253 110241 104226
Quicksort3169 60146 3779
Mergesort99234 102242 99232

Noteworthy are the following points:

  1. The improvement of binary insertion over straight insertion is marginal indeed, and even negative in the case of an already existing order.
  2. Bubblesort is definitely the worst sorting method among all compared. Its improved version "Shakersort" is still worse than straight insertion and straight selection (except in the pathological case of sorting a sorted array).
  3. Quicksort beats Heapsort by a factor of 2 to 3. It sorts the inversely ordered array with speed practically identical to the one which is already sorted.

Merging

(Not in DCS) (cf. F&T, p. 645. prog 12.5)

Supppose we have two arrays, both sorted, and we would like to combine them into another sorted array.

One option would be to copy one array to a third array, then copy the other array, then sort the new array from scratch using an efficient soring routine. This would be a straight-forward method, but it would ignore the fact that the original arrays were already sorted.

Instead, the common mergin algorihtm used is similar to this:

     1)    set pointers of all 3 arays to 1;
     WHILE (more items still exist in BOTH input arrays) DO
     |     2)    compare lead items to find the smaller of
     |           the input arrays;
     |     3)    copy the smaller item to the merged array;
     |     4)    increment pointer of the merged array,
     |_________  and of the appropriate input array;
     5)    copy rest of unused input arrays to merged array.
For example,
Array A:   1  2  5  6  8  9
Array B:   3  4  7  10 11 12

Code for Merging

   void mergarr(int a[], int b[], int c[], 
                int an, int bn, int & cn, int climit)
   {  int aptr, bptr, cptr;
      if(an+bn > climit)
      {   cerr << "too many elements to be merged" << endl;
          exit(1);
       }
      else {
         cn = an + bn;
	 // initialize pointers
	 aptr = 0; bptr = 0; cptr = 0;
	 // major loop -- test to see if we have
	 // reached the end of one of the input arrays
	 while (aptr < an) && (bptr < bn){
	    if (a[aptr] < b[bptr])
	    {   c[cptr] = a[aptr];
	        aptr++; }
	    else
	    {   c[cptr] = b[bptr];
	        bptr++; }
	    cptr++;
	    }
	 // time to copy left-overs
	 // copy from a if a has anything left
	 while (aptr < an) {
	    c[cptr] = a[aptr];
	    cptr++; aptr++;
	    }
	 // else copy from b if b has anything left
	 while (bptr < bn) {
	    c[cptr] = b[bptr];
	    cptr++; bptr++;
	    }
	 }
    }

This page is maintained by Dennis C. Smolarski, S.J.
© Copyright 1998, 1999 Dennis C. Smolarski, SJ, All rights reserved.
Last changed: 7 April 1999. Minor correction 9 June 1999