内部排序算法

来源:互联网 发布:幼儿园早教软件 编辑:程序博客网 时间:2024/06/08 19:24
#include <stdlib.h>#include <stdio.h>#include <time.h>void swap(int *a int *b);/** * 选择排序 */void select_sort(int *a int size){int min loc;for(int i=0; i<size-1; i++){min = a[i];loc = i;for(int j=i; j<size-1; j++){if(a[j]<min){min = a[j];loc = j;}}if(loc != i){a[loc] = a[i];a[i] = min;}}}/** * 插入排序 */void insert_sort(int *a int size){int ijkey;for(i=1; i<size; i++)//只有一个元素的数列默认有序,因此从i=1位置开始处理。{key = a[i];for(j=i-1; j>0 && a[j]>key; j--)//对i位置前,有序的数列进行插入,插入方法是后移比当前元素大的元素,找到合适的位置插入{a[j+1] = a[j];}a[++j] = key;//找到位置,插入}}/** * 冒泡排序 */void bubble_sort(int *a int size){int tempij;for(i=0; i<size-1; i++) //注意点 size-1{for(j=0; j<size-1-i; j++) //注意点 size-1-i{if(a[j] > a[j+1]){temp = a[j+1];a[j+1] = a[j];a[j] = temp;}}}}/** * 快速排序 */int partition(int *a int low int high){int pivot = a[low];//用pivot记录a[low]的值,并在确定low=high位置之后,再赋回给a[low]while(low<high){while(high>low && a[high]>=pivot)//向下扫描,找到小于pivot的数值位置,交换a[low]<->a[high],不交换只赋值,是为了减少两次运算high--;a[low] = a[high];while(high>low && a[low]<=pivot)//向上扫描,找到大于pivot的数值位置,交换a[high]<->a[low]low++;a[high] = a[low];}a[low] = pivot;return low;//返回low位置,此时low = high}/* * 增加枢元的选择随机性,让快速排序算法不要遇到最坏的情况,可达期望的O(nlogn)的时间复杂度 */int random_partition(int *a int low int high){time_t t; srand(time(&t));//初始化随机种子int i = rand()%(high-low+1) + low;//选定一个随机数if(low != i)swap(&a[i] &a[low]);//将a[low]与a[i]交换,保证partition的从low值选定的枢元是随机的return partition(a low high);}void quick_sort(int *a int low int high){if(low<high){//普通快速排序//int pivotloc = partition(a low high);//quick_sort(a low pivotloc-1);//quick_sort(a pivotloc+1 high);//随机选择-快速排序int pivotloc = random_partition(a low high);quick_sort(a low pivotloc-1);quick_sort(a pivotloc+1 high);}}/** * 堆排序 *//* * shiftdown时,根结点的左右子树都已经满足堆的性质,  * 因为从最后一位上提为根结点,破坏了原堆的性质,所以要下移,找到合适的位置 */void shiftdown(int a[] int m int s){int keyichild;key = a[m];//记录m为堆顶值,准备下移for(i=m; 2*i+1<s; i=child){child = 2*i+1;if(child+1<s && a[child+1]<a[child])child = child+1;if(key<a[child])break;a[i] = a[child];a[child] = key;}}/** * 位操作实现的交换算法 */void swap(int *a int *b){*a = *a^*b;*b = *a^*b;*a = *a^*b;}void heap_sort(int *a int size){//初始建堆,keypoint:从最后一个非叶子节点开始执行shiftdown,也就是最中间的位置pin = (size-1)/2。//为什么是最后一个非叶子节点开始,因为最后一个非叶子节点,保证其子树只有一个或两个孩子节点,是不满足堆性质的,//通过shiftdown可以将这个最小规模的子树调整成堆。//然后从中间位置开始,以上往下,依次调整成堆。(分治策略,小解组合成最终解)for(int i=(size-1)/2; i>0; i--)shiftdown(a i size);for(int i=size-1; i>0; i--){swap(&a[0] &a[i]);//将堆顶元素与最后一个元素置换,最后一个元素是第小元素。除最后一个元素外,剩余的序列仍然满足堆性质//循环最后得到有序序列,最后该序列已经不是一个堆了。shiftdown(a 0 i);}}void PrintK(int *a int n){for(int i=0; i<n; i++){printf("%d " a[i]);}printf("\n");}int main(){int a[] = {4,2,5,9,10,1,7,8,3,0};int size = sizeof(a)/sizeof(int);//bubble_sort(a size);//qsort(a 0 size-1);//select_sort(a size);//insert_sort(asize);//heap_sort(asize);PrintK(a size);}

0 0
原创粉丝点击