排序的稳定性,是指排序前后,相同元素的位置先后关系是否改变.稳定排序,是位置先后关系不变.不稳定排序,是先后位置关系改变,当然,也存在不改变的可能.更说明了他的不稳定.可笑吧?哈哈...
<>的一道课后习题,问了几种常见排序的稳定性问题,以及如何将不稳定排序改为稳定排序.为了探寻这个问题,我决定动手写出这些排序.这是昨天的事,昨天开始写的.到现在写完了,中途干了许多别的事情.
还是第一次,默写这些个排序.收获很多,可以说,最起码克服了默写这些排序的恐惧.而且,也发现了,如何将稳定排序改为不稳定排序,呵呵.常言说得好,知其然不知其所以然,是不行的...呵呵.还是要明白,这东西的原理,才能得心应手.恩...以至于,很多东西,写过之后,用的时候忘记了,可能也就是这个原因吧.
这些个排序,每一个都是单独的一个函数.为了紧凑考虑,才这么做的.不怎么好看,但很适合研究.这么写代码的感觉,就像一位发疯的钢琴家敲击着他的琴键,即使声音杂乱,也是音乐.呵呵...什么跟什么?呵呵.胡言乱语.又开始练习胡言乱语.
那个测试函数,并非每次都能测试出不稳定排序.因为,存在不稳定排序出现稳定效果的可能.
到现在,写完了,我还是不知道,如何将不稳定排序改为稳定排序.
贴吧,期待发现这一切的那一天.
/* test.c -- 测试排序稳定性 */ #include #include #include #define MAX (20) #define SIZE (40) typedef struct { int primary ; int secondary ; } Item ; int main (void) ; int initialize (Item * const array, const int size) ; /* Some kinds of sorting algorithm. */ void insertionSort (Item * const array, const int size) ; void shellSort (Item * const array, const int size) ; void heapSort (Item * const array, int size) ; void mergeSort (Item * const array, const int left, const int right) ; void quickSort (Item * const array, int left, const int right) ; void bubbleSort (Item * const array, int size) ; void selectSort (Item * const array, const int size) ; void countSort (Item * const array, const int size, const int min, const int max) ; int test (const Item * const array, const int size, const char * name) ; void printArray (const Item * const array, const int size) ; int main (void) { Item array[SIZE] ; int size ; size = SIZE ; initialize (array, size) ; insertionSort (array, size) ; test (array, size, "insertionSort") ; printArray (array, size) ; initialize (array, size) ; shellSort (array, size) ; test (array, size, "shellSort") ; printArray (array, size) ; initialize (array, size) ; heapSort (array, size) ; test (array, size, "heapSort") ; printArray (array, size) ; initialize (array, size) ; mergeSort (array, 0, size - 1) ; test (array, size, "mergeSort") ; printArray (array, size) ; initialize (array, size) ; quickSort (array, 0, size - 1) ; test (array, size, "quickSort") ; printArray (array, size) ; initialize (array, size) ; bubbleSort (array, size) ; test (array, size, "bubbleSort") ; printArray (array, size) ; initialize (array, size) ; selectSort (array, size) ; test (array, size, "selectSort") ; printArray (array, size) ; initialize (array, size) ; countSort (array, size, 0, MAX) ; test (array, size, "countSort") ; printArray (array, size) ; return 0 ; } int initialize (Item * const array, const int size) { int * temp ; int max, i ; max = MAX ; temp = (int *) malloc (sizeof (int) * max) ; if (NULL == temp) return 0 ; srand ((unsigned int) time (NULL)) ; for (i = 0; i < size; i++) array[i].primary = rand () % max ; for (i = 0; i < max; i++) temp[i] = 0 ; for (i = 0; i < size; i++) temp[array[i].primary]++ ; for (i = size - 1; i >= 0; i--) array[i].secondary = temp[array[i].primary]-- ; free (temp) ; return 1 ; } void insertionSort (Item * const array, const int size) { Item temp ; int i, j ; for (i = 1; i < size; i++) { temp = array[i] ; for (j = i; j > 0; j--) { if (temp.primary < array[j - 1].primary) array[j] = array[j - 1] ; else break ; } array[j] = temp ; } } void shellSort (Item * const array, const int size) { Item temp ; int p, i, j ; for (p = size / 2; p > 0; p /= 2) { for (i = p; i < size; i++) { temp = array[i] ; for (j = i; j - p >= 0; j -= p) { if (temp.primary < array[j - p].primary) array[j] = array[j - p] ; else break ; } array[j] = temp ; } } } void heapSort (Item * const array, int size) { Item temp ; int i, j, child ; /* Build heap. */ for (i = size / 2; i >= 0; i--) { temp = array[i] ; for (j = i; j * 2 + 1 <= size - 1; j = child) { child = j * 2 + 1 ; if (child != size - 1 && array[child].primary < array[child + 1].primary) child++ ; if (temp.primary < array[child].primary) array[j] = array[child] ; else break ; } array[j] = temp ; } while (size > 1) { /* Swap */ temp = array[0] ; array[0] = array[size - 1] ; array[size - 1] = temp ; size-- ; /* Percolate down. */ temp = array[0] ; for (j = 0; j * 2 + 1 <= size - 1; j = child) { child = j * 2 + 1 ; if (child != size - 1 && array[child].primary < array[child + 1].primary) child++ ; if (temp.primary < array[child].primary) array[j] = array[child] ; } array[j] = temp ; } } void mergeSort (Item * const array, const int left, const int right) { Item * temp ; int size, middle, i, j, k ; if (left < right) { middle = (left + right) / 2 ; mergeSort (array, left, middle) ; mergeSort (array, middle + 1, right) ; /* Merge. */ size = right - left + 1 ; temp = (Item *) malloc (sizeof (Item) * size) ; if (NULL == temp) { puts ("Out of space.") ; return ; } i = left ; j = middle + 1 ; k = 0 ; while (i <= middle && j <= right) { /* "<=" */ if (array[i].primary <= array[j].primary) temp[k++] = array[i++] ; else temp[k++] = array[j++] ; } if (i > middle) { while (j <= right) temp[k++] = array[j++] ; } else { while (i <= middle) temp[k++] = array[i++] ; } j = 0 ; for (i = left; i <= right; i++) array[i] = temp[j++] ; free (temp) ; } } void quickSort (Item * const array, int left, const int right) { Item temp ; int i, j, pivot ; while (left < right) { i = left ; j = right - 1 ; pivot = right ; while (i < j) { while (i != right && array[i].primary <= array[pivot].primary) i++ ; while (j != left && array[j].primary > array[pivot].primary) j-- ; if (i < j) { temp = array[i] ; array[i] = array[j] ; array[j] = temp ; } else break ; } temp = array[i] ; array[i] = array[pivot] ; array[pivot] = temp ; quickSort (array, left, i - 1) ; left = i + 1 ; } } void bubbleSort (Item * const array, int size) { Item temp ; int j ; int index ; index = 1 ; for (; 1 == index && size > 1; size--) { index = 0 ; for (j = 1; j < size; j++) { if (array[j].primary < array[j - 1].primary) { index = 1 ; temp = array[j] ; array[j] = array[j - 1] ; array[j - 1] = temp ; } } } } void selectSort (Item * const array, const int size) { Item temp ; int i, j, minIndex ; for (i = 0; i < size - 1; i++) { minIndex = i ; for (j = i + 1; j < size; j++) { if (array[j].primary < array[minIndex].primary) minIndex = j ; } if (minIndex != i) { temp = array[i] ; array[i] = array[minIndex] ; array[minIndex] = temp ; } } } void countSort (Item * const array, const int size, const int min, const int max) { Item * result ; int * temp ; int i, extent ; extent = max - min ; temp = (int *) malloc (sizeof (int) * extent) ; if (NULL == temp) return ; result = (Item *) malloc (sizeof (Item) * size) ; if (NULL == result) { free (temp) ; return ; } for (i = 0; i < extent; i++) temp[i] = 0 ; for (i = 0; i < size; i++) temp[array[i].primary - min]++ ; for (i = 1; i < extent; i++) temp[i] += temp[i - 1] ; for (i = size - 1; i >= 0; i--) result[--temp[array[i].primary - min]] = array[i] ; for (i = 0; i < size; i++) array[i] = result[i] ; free (temp) ; free (result) ; } int test (const Item * const array, const int size, const char * name) { int i ; printf ("----------------%-15s-----------------/n", name) ; for (i = 1; i < size; i++) { if (array[i].primary == array[i - 1].primary && array[i].secondary < array[i - 1].secondary) { puts ("Is erratic.") ; printf ("------------------------------------------------/n", name) ; return 0 ; } } puts ("Is stable.") ; printf ("------------------------------------------------/n", name) ; return 1 ; } void printArray (const Item * const array, const int size) { int i ; for (i = 0; i < size; i++) printf ("Primary:%-3dSecondary:%3d/n", array[i].primary, array[i].secondary) ; }