#include <stdio.h> #include <stdlib.h> /*排序算法,从小到大排序*/ void swap(int *a, int *b); int max(int a[], int n); void array_print(int a[], int n); int array_insert(int a[], int n, const int data); void sort_select(int a[], int n); void sort_bubble(int a[], int n); void sort_insert(int a[], int n); /* *名称:选择排序 *思想:每次选一个最大的放到数组的最后面。 */ void sort_select(int a[], int n) { int size = 0, index = 0; for(size = n; size > 1; size--) { index = max(a, size); swap(&a[size - 1], &a[index]); } } //找数组中最大的元素,返回下标 int max(int a[], int n) { int i = 0, index = 0; for(i = 0; i < n; i++) { index = ((a[index] >= a[i]) ? index : i); } return index; } //交换两个元素 void swap(int *a, int *b) { int tmp = *a; *a = *b; *b = tmp; } /* *名称:冒泡排序,及时终止的排序 *思想:每次通过逐个比较选出最大的放在最后面。 *区别:比较的过程会改变经过比较的元素的顺序, * 对比选择排序,可能不需要比较n个循环。 */ void sort_bubble(int a[], int n) { int size = 0, j = 0, flag = 0; for(size = n; size > 1; size--) { flag = 0; for(j = 0; j < size-1; j++) { if(a[j] > a[j+1]) { swap(&a[j], &a[j+1]); flag = 1; } } if(flag == 0) { printf("%d\n", size);//输出比较循环的次数 break; } } } /* *名称:插入排序 *思想:保护一个元素的数组是有序的,加入一个元素时也按顺序插入,结果还是有序的。 */ void sort_insert(int a[], int n) { int size = 0, i = 0; for(size = 1; size < n; size++) { array_insert(a, size+1, a[size]); //把a[size-1]插入有序数组a中; } } int array_insert(int a[], int n, int data) { int i = 0; for(i = n-2; i >= 0 && data < a[i]; i--) { a[i+1] = a[i]; } a[i+1] = data; return 0; } /* *名称:归并排序 *思想:分治的策略,若n为1,算法终止;否则,将这个集合分解为2个子集合,分别排序 * 然后将排序好的子集合归并为一个集合。 *分析:归并排序最好最坏的时间复杂度是一样的,都等于nlogn。 */ void sort_merge(int a[], int left, int right) { int b[]; if(left < right) { int i = (left + right)/2; sort_merge(a, left, i); sort_merge(a, i+1, right); merge(a, b, left, i, right);//合并到b copy(b, a, left, right);//复制到a } } /* *名称:自然归并排序 *思想:在普通归并排序的基础上,首先对输入序列中已经存在的有序子序列进行归并, * 然后再按上面的归并算法归并。 *分析:自然归并排序最好的时间复杂度等于N,只扫描一次即可。 */ /* *名称:快速排序 *思想:选取一个支点,把数组分成两个部分,左边元素都小于支点,右边元素都大于支点, * 然后对左右两边的分组进行快速排序。 *快速排序最坏情况下复杂度等于n2(n的平方),最好等于nlogn,平均为nlogn。 */ //算法总是选取第一个元素作为支点 void sort_quick(int a[], int l, int r) { if(l >= r) return; int i = l; //从左边开始的游标 int j = r+1; //从右边开始的游标 int pivot = a[l]; //支点 while(true) { do{ // 在左边找大于支点的元素 i = i+1; }while(a[i] < pivot); do{ // 在右边找小于支点的元素 j = j-1; }while(a[j] > pivot); if(i >= j) break; swap(a[i], a[j]); } //把支点放到左边和右边的中间位置 a[l] = a[j]; a[j] = pivot; sort_quick(a, l, j-1); //对左边排序 sort_quick(a, j+1, r); //对右边排序 } /* *名称:堆排序 *思想:把数组组织成堆,然后从堆中一次删除元素 *堆的初始化等于N,删除元素O(logN) ,总的复杂度为O(nlogn). */ //输出数组元素 void array_print(int a[], int n) { int i = 0; for(i = 0; i < n; i++) { printf("%d ", a[i]); } printf("\n"); } int main() { printf("hello.\n"); /*tst*/ int a[10] = {3, 6, 2, 1, 87, 35, 96, 8, 12, 100}; array_print(a, 10); //sort_select(a, 10); //sort_bubble(a, 10); sort_insert(a, 10); array_print(a, 10); system("pause"); return 0; }