2014-06-11 六种排序方式 sort.c
1. 选择排序 select_sort
void select_sort(int* arr, int len){ int i, j; for(i = 0; i < len - 1; i++) { int min = i; for(j = i + 1; j < len; j++) { if(arr[min] > arr[j]) min = j; } if(min != i) _swap(&arr[i], &arr[min]); }}
2. 插入排序 insert_sort
void insert_sort(int* arr, int len){ int i, j, flag, tmp; for(i = 1; i < len; i++) { for(j = i; j > 0; j--) { if(arr[j - 1] < arr[i]) break; } flag = j; if(flag != i) { tmp = arr[i]; for(j = i; j > flag; j--) { arr[j] = arr[j - 1]; } arr[j] = tmp; } }}
3. 冒泡排序 bubble_sort
void bubble_sort(int* arr, int len){ int i, j; for(i = 0; i < len - 1; i++) { for(j = len; j > i; j--) { if(arr[j] < arr[j - 1]) _swap(&arr[j], &arr[j - 1]); } }}
4. 快速排序 quick_sort
/* * 分治Partition, * 两个下标分别从首尾向中间扫描 */int partition(int* arr, int len) { int left = 0, right = len - 1; int pivot = arr[left]; //以当前表中第一个元素为枢轴值进行划分 while(left < right) //结束条件 { while(left < right && arr[right] >= pivot) right--; arr[left] = arr[right]; //比枢轴值小的元素移动到左端 while(left < right && arr[left] < pivot) left++; arr[right] = arr[left]; //比枢轴值大的元素移动到右端 } arr[left] = pivot; //枢轴元素放到最终位置 return left; //返回该位置}void quick_sort(int* arr, int len){ if(len > 0) { int part = partition(arr, len); quick_sort(arr, part); quick_sort(arr + part + 1, len - part - 1); }}
5. 堆排序 heap_sort
/* * 本函数功能是:根据数组 arr 构建大根堆 * arr 是待调整的堆数组, * i 是待调整的数组元素的位置, * len 是数组的长度 */void heap_adjust(int* arr, int i, int len){ int child; for(; 2*i+1 < len; i = child) { child=2*i+1; //子结点的位置=2*(父结点位置)+1 if(child < len-1 && arr[child+1] > arr[child]) //得到子结点中较大的结点 ++child; if(arr[i] < arr[child]) //如果较大的子结点大于父结点那么把较大的子结点往上移动,替换它的父结点 _swap(&arr[i], &arr[child]); else //否则,不需要再向下调整,直接跳出 break; }}/* * 堆排序算法 */void heap_sort(int* arr, int len){ //调整序列的前半部分元素,调整完之后第一个元素是序列的最大的元素 //length/2-1是最后一个非叶节点,此处"/"为整除 for(int i = len/2-1; i >= 0; --i) heap_adjust(arr, i, len); //从最后一个元素开始对序列进行调整,不断的缩小调整的范围直到第一个元素 for(int i = len-1; i > 0; --i) { //把第一个元素和当前的最后一个元素交换, //保证当前的最后一个位置的元素都是在现在的这个序列之中最大的 _swap(&arr[0], &arr[i]); //不断缩小调整heap的范围,每一次调整完毕保证第一个元素是当前序列的最大值 heap_adjust(arr, 0, i); }}
6. 归并排序
/* * 归并: * 将有两个有序数组 * a[first ... mid], * a[mid ... last] * 合并 */void mergearray(int arr[], int first, int mid, int last, int temp[]){ int i = first, j = mid + 1; int k = 0; while (i <= mid && j <= last) //两边都有元素时,进行比较,将较小元素存入临时数组 { if (arr[i] <= arr[j]) temp[k++] = arr[i++]; else temp[k++] = arr[j++]; } while (i <= mid) //剩下一个数组可能还存在多余元素,直接存入临时数组 temp[k++] = arr[i++]; while (j <= last) //同上 temp[k++] = arr[j++]; for (i = 0; i < k; i++) //将临时数组中的有序数赋给原数组 arr[first + i] = temp[i]; } /* * 归并排序算法 */void mergesort(int arr[], int first, int last, int temp[]) { if (first < last) { int mid = (first + last) / 2; mergesort(arr, first, mid, temp); //左边有序 mergesort(arr, mid + 1, last, temp); //右边有序 mergearray(arr, first, mid, last, temp); //再将两个有序数列合并 }}bool merge_sort(int arr[], int len) { int *p = new int[len]; //在此处开辟临时数组, //防止在算法中多次开辟和删除临时数组造成的开销(耗时)过大 if (p == NULL) return false; mergesort(arr, 0, len - 1, p); delete[] p; return true; }
50个随机数测试
#include <stdio.h>#include <stdlib.h>#include <time.h>#define SIZE 50void _swap(int* a, int* b){ int tmp = *a; *a = *b; *b = tmp;}void print(int* arr, int len){ int i; for(i = 0; i < len; i++) { printf("%4d", arr[i]); if((i + 1)%10 == 0) printf("\n"); }}int main(){ srand(time(NULL)); int arr[SIZE]; int i; for(i = 0; i < SIZE; i++) { arr[i] = rand()%1000; } printf("before sort:\n"); print(arr, SIZE); printf("\n"); //select_sort(arr, SIZE); //insert_sort(arr, SIZE); //bubble_sort(arr, SIZE); //quick_sort(arr, SIZE); //heap_sort(arr, SIZE); merge_sort(arr, SIZE); printf("after sort:\n"); print(arr, SIZE); return 0;}