Algorithms |
|
Sorting |
|
Seed7 contains a sort function to sort arrays with the quicksort algorithm. The argorithms below (bubble sort, cocktail sort, selection sort, shaker sort, insertion sort, merge sort, heap sort, shell sort and quicksort) are in-place sorting methods which are based on a comparison of two elements.
Bubble sort
Bubble sort works by repeatedly stepping through the array, comparing each pair of adjacent items and swapping them if they are in the wrong order. The bubble sort algorithm executes in O(n2) time.
const proc: bubbleSort (inout array elemType: arr) is func local var boolean: swapped is FALSE; var integer: i is 0; var elemType: help is elemType.value; begin repeat swapped := FALSE; for i range 1 to length(arr) - 1 do if arr[i] > arr[i + 1] then help := arr[i]; arr[i] := arr[i + 1]; arr[i + 1] := help; swapped := TRUE; end if; end for; until not swapped; end func;
Cocktail sort
Cocktail sort is an improvement over Bubble Sort. The search for adjacent items with wrong order is done in both directions. The cocktail sort algorithm executes in O(n2) time.
const proc: cocktailSort (inout array elemType: arr) is func local var boolean: swapped is FALSE; var integer: i is 0; var elemType: help is elemType.value; begin repeat swapped := FALSE; for i range 1 to length(arr) - 1 do if arr[i] > arr[i + 1] then help := arr[i]; arr[i] := arr[i + 1]; arr[i + 1] := help; swapped := TRUE; end if; end for; if swapped then swapped := FALSE; for i range length(arr) - 1 downto 1 do if arr[i] > arr[i + 1] then help := arr[i]; arr[i] := arr[i + 1]; arr[i + 1] := help; swapped := TRUE; end if; end for; end if; until not swapped; end func;
Selection sort
Selection sort searches the minimum value in the array and swaps it with the value in the first position. After that the process is repeated for the remainder of the array. The selection sort algorithm executes in O(n2) time.
const proc: selectionSort (inout array elemType: arr) is func local var integer: i is 0; var integer: j is 0; var integer: min is 0; var elemType: help is elemType.value; begin for i range 1 to length(arr) - 1 do min := i; for j range i + 1 to length(arr) do if arr[j] < arr[min] then min := j; end if; end for; help := arr[min]; arr[min] := arr[i]; arr[i] := help; end for; end func;
Shaker sort
Shaker sort is a variant of selection sort. It searches the minimum and maximum values in the array and swaps them with the values in the first and the last position respectively. After that the process is repeated for the remainder of the array. Note that the term shaker sort can also refer to cocktail sort, which is a variant of bubble sort. The shaker sort algorithm executes in O(n2) time.
const proc: shakerSort (inout array elemType: arr) is func local var integer: i is 1; var integer: j is 0; var integer: k is 0; var integer: min is 0; var integer: max is 0; var elemType: help is elemType.value; begin k := length(arr); while i < k do min := i; max := i; for j range succ(i) to k do if arr[j] < arr[min] then min := j; end if; if arr[j] > arr[max] then max := j; end if; end for; help := arr[min]; arr[min] := arr[i]; arr[i] := help; if max = i then help := arr[min]; arr[min] := arr[k]; arr[k] := help; else help := arr[max]; arr[max] := arr[k]; arr[k] := help; end if; incr(i); decr(k); end while; end func;
Insertion sort
Insertion sort forms a growing sorted list at the beginning of the array. Elements are removed from the array and then they are inserted into the correct position of the already-sorted list. The insertion sort algorithm executes in O(n2) time.
const proc: insertionSort (inout array elemType: arr) is func local var integer: i is 0; var integer: j is 0; var elemType: help is elemType.value; begin for i range 2 to length(arr) do j := i; help := arr[i]; while j > 1 and arr[pred(j)] > help do arr[j] := arr[pred(j)]; decr(j); end while; arr[j] := help; end for; end func;
Merge sort
Merge sort recognizes that a list with 0 or 1 elements is already sorted. Otherwise merge sort divides the unsorted list into two sublists of about half the size. Then each sublist is sorted by recursively calling merge sort. Afterwards the two sublists are merged into one sorted list. The merge sort algorithm executes in O(n log n) time.
const proc: mergeSort (inout array elemType: arr, in var integer: low, in integer: high) is func local var integer: mid is 0; var elemType: help is elemType.value; var integer: k is 0; begin if low < high then mid := (low + high) div 2; mergeSort(arr, low, mid); mergeSort(arr, succ(mid), high); incr(mid); while low < mid and mid <= high do if arr[low] < arr[mid] then incr(low); else help := arr[mid]; for k range mid downto succ(low) do arr[k] := arr[pred(k)]; end for; arr[low] := help; incr(low); incr(mid); end if; end while; end if; end func; const proc: mergeSort (inout array elemType: arr) is func begin mergeSort(arr, 1, length(arr)); end func;
Merge sort with additional storage
const proc: mergeSort2 (inout array elemType: arr, in integer: low, in integer: high, inout array elemType: scratch) is func local var integer: mid is 0; var integer: k is 0; var integer: t_low is 0; var integer: t_high is 0; begin if low < high then mid := (low + high) div 2; mergeSort2(arr, low, mid, scratch); mergeSort2(arr, succ(mid), high, scratch); t_low := low; t_high := succ(mid); for k range low to high do if t_low <= mid and (t_high > high or arr[t_low] < arr[t_high]) then scratch[k] := arr[t_low]; incr(t_low); else scratch[k] := arr[t_high]; incr(t_high); end if; end for; for k range low to high do arr[k] := scratch[k]; end for; end if; end func; const proc: mergeSort2 (inout array elemType: arr) is func local var array elemType: scratch is 0 times elemType.value; begin scratch := length(arr) times elemType.value; mergeSort2(arr, 1, length(arr), scratch); end func;
Heap sort
const proc: downheap (inout array elemType: arr, in var integer: k, in integer: n) is func local var elemType: help is elemType.value; var integer: j is 0; begin if k <= n div 2 then help := arr[k]; repeat j := 2 * k; if j < n and arr[j] < arr[succ(j)] then incr(j); end if; if help < arr[j] then arr[k] := arr[j]; k := j; end if; until help >= arr[j] or k > n div 2; arr[k] := help; end if; end func; const proc: heapSort (inout array elemType: arr) is func local var integer: n is 0; var integer: k is 0; var elemType: help is elemType.value; begin n := length(arr); for k range n div 2 downto 1 do downheap(arr, k, n); end for; repeat help := arr[1]; arr[1] := arr[n]; arr[n] := help; decr(n); downheap(arr, 1, n); until n <= 1; end func;
Shell sort
const proc: shellSort (inout array elemType: arr) is func local var integer: i is 0; var integer: j is 0; var integer: increment is 0; var elemType: help is elemType.value; begin increment := length(arr) div 2; while increment > 0 do for i range 1 to length(arr) do j := i; help := arr[i]; while j > increment and arr[j - increment] > help do arr[j] := arr[j - increment]; j -:= increment; end while; arr[j] := help; end for; increment := increment div 2; end while; end func;
Quicksort
const proc: quickSort (inout array elemType: arr, in integer: left, in integer: right) is func local var elemType: compare_elem is elemType.value; var integer: less_idx is 0; var integer: greater_idx is 0; var elemType: help is elemType.value; begin if right > left then compare_elem := arr[right]; less_idx := pred(left); greater_idx := right; repeat repeat incr(less_idx); until arr[less_idx] >= compare_elem; repeat decr(greater_idx); until arr[greater_idx] <= compare_elem or greater_idx = left; if less_idx < greater_idx then help := arr[less_idx]; arr[less_idx] := arr[greater_idx]; arr[greater_idx] := help; end if; until less_idx >= greater_idx; arr[right] := arr[less_idx]; arr[less_idx] := compare_elem; quickSort(arr, left, pred(less_idx)); quickSort(arr, succ(less_idx), right); end if; end func; const proc: quickSort (inout array elemType: arr) is func begin quickSort(arr, 1, length(arr)); end func;
|
|