基于数组的排序算法
来源:互联网 发布:powerdesign mac 编辑:程序博客网 时间:2024/05/21 17:40
常用的基于数组的排序算法代码详解(二)
上次已经对几种排序算法进行了分析,接下来对剩余的几种排序算法进行分析,以及给出测试函数。
int *get_arr(int len){ //srand(time(NULL)); srand(100); int *arr = (int *)malloc(sizeof(int)*len); assert(arr != NULL); for(int i = 0;i < len;i++) { arr[i] = rand(); } return arr;}
5,希尔排序
空间复杂度:O(1) 时间复杂度:O(n^1.35)/O(n^1.5)
思路:将待排序数组按照步长gap进行分组,然后将每组的元素利用直接插入排序的方法进行排序;每次将gap折半减小,循环上述操作;当gap=1时,利用直接插入,完成排序。
static void shell(int *arr,int len,int gap){ int i; int j; int tmp; for(i = gap;i < len;i++) { tmp = arr[i]; for(j = i-gap;j>=0;j = j-gap) { if(tmp > arr[j]) { break; } arr[j+gap] = arr[j]; } arr[j+gap] = tmp; }}void shell_sort(int *arr,int len){ shell(arr,len,3); shell(arr,len,1);}
6,快速排序
空间复杂度:O(logn) 时间复杂度:O(n*logn)
思路:挖坑填数+分治法。从序列当中选择一个基准数,在这里我们选择序列当中第一个数最为基准数,将序列当中的所有数依次遍历,比基准数大的位于其右侧,比基准数小的位于其左侧,重复步骤1.2,直到所有子集当中只有一个元素为止。
//递归形式快速排序int partition(int *arr,int left,int right){ int tmp = arr[left]; while(left < right) { while(arr[right] >= tmp && left < right) { right--; } arr[left] = arr[right]; while(arr[left] <= tmp && left < right) { left++; } arr[right] = arr[left]; } arr[left] = tmp; return left;}void quick(int *arr,int left,int right){ if(left < right) { int base = partition(arr,left,right); quick(arr,left,base-1); quick(arr,base+1,right); }}void quick_sort(int *arr,int len){ quick(arr,0,len-1);}//非递归形式快速排序void quick_sort_stack(int *arr,int len){ int *stack = (int *)malloc(sizeof(int) * len * len); assert(stack != NULL); int top = 0; stack[top++] = 0; stack[top++] = len - 1; int left = 0; int right = 0; int base = 0; while(top != 0) { right = stack[--top]; left = stack[--top]; base = partition(arr,left,right); if(left < base-1) { stack[top++] = left; stack[top++] = base - 1; } if(right > base+1) { stack[top++] = base + 1; stack[top++] = right; } } free(stack);}
7,堆排序
空间复杂度:O(1) 时间复杂度:O(n*logn)
堆:本质是一种数组对象。特别重要的一点性质:任意的叶子节点小于(或大于)它所有的父节点。对此,又分为大顶堆和小顶堆,大顶堆要求节点的元素都要大于其孩子,小顶堆要求节点元素都小于其左右孩子,两者对左右孩子的大小关系不做任何要求。
利用堆排序,就是基于大顶堆或者小顶堆的一种排序方法。
static void heap_adjust(int *arr,int start,int end){ int tmp = arr[start]; for(int i = 2*start+1;i <= end;i = 2*i+1) { if(i < end && arr[i]<arr[i+1]) { i++; } if(tmp > arr[i]) { break; } else if(tmp <arr[i]) { arr[start] = arr[i]; } else //tmp == arr[i] { ; } start = i; } arr[start] = tmp;}void heap_sort(int *arr,int len){ for(int start = len/2-1;start >= 0;start--) { heap_adjust(arr,start,len-1); } swap(&arr[0],&arr[len-1]); for(int k = len-1;k>0;k--) { heap_adjust(arr,0,k-1); swap(&arr[0],&arr[k-1]); }}
8,归并排序
空间复杂度:O(n) 时间复杂度:O(n*logn)
思路:通过序列中各个元素的值,对排序的N个元素进行若干趟的“分配”与“收集”来实现排序。
分配:我们将L[i]中的元素取出,首先确定其个位上的数字,根据该数字分配到与之序号相同的桶中
收集:当序列中所有的元素都分配到对应的桶中,再按照顺序依次将桶中的元素收集形成新的一个待排序列L[ ]对新形成的序列L[]重复执行分配和收集元素中的十位、百位…直到分配完该序列中的最高位,则排序结束。
void meger(int *arr,int len,int gap){ int *buff = (int *)malloc(sizeof(int)*len); int k = 0; int L1 = 0; int H1 = L1+gap-1; int L2 = H1+1; int H2 = L2+gap-1 < len ? L2+gap-1 : len-1; while(L2 < len) { while(L1 <= H1 && L2 <= H2) { if(arr[L1] <= arr[L2]) { buff[k++] = arr[L1++]; } else if(arr[L1] > arr[L2]) { buff[k++] = arr[L2++]; } } while(L1 <= H1) { buff[k++] = arr[L1++]; } while(L2 <= H2) { buff[k++] = arr[L2++]; } L1 = H2+1; H1 = L1+gap-1; L2 = H1+1; H2 = L2+gap-1 < len ? L2+gap-1 : len-1; } while(L1 < len) { buff[k++] = arr[L1++]; } for(int i = 0;i<len;i++) { arr[i] = buff[i]; } free(buff);}void meger_sort(int *arr,int len){ for(int gap = 1;gap < len;gap = gap*2) { meger(arr,len,gap); }}
测试用例:
#include"sort.h"#include<stdio.h>int main(){ int arr[] = {13,34,32,21,13,45,30,56,43,31,11}; int len = sizeof(arr)/sizeof(arr[0]); /*int *arr = get_arr(100000); int len = 100000;*/ //exchange_sort (arr,len); //show(arr,len); //bubble_sort(arr,len); //show(arr,len); //bubble_sort_ex(arr,len); //show(arr,len); //select_sort(arr,len); quick_sort(arr,len); //show(arr,len); quick_sort_stack(arr,len); //shell_sort(arr,len); meger_sort(arr,len); show(arr,len); /*insert_sort_ex(arr,len); show(arr,len);*/ return 0;}
最后,对几种排序算法进行比较:
排序算法的分类
排序算法性能比较
若文章中或代码中存在问题,欢迎指正。
- 基于数组的排序算法
- 基于数组的排序算法
- 并行排序,基于数组的桶算法
- 基于数组的堆排序算法的C语言实现
- 基于数组的直接插入排序算法和代码实现
- 数组的排序算法
- 数组的排序算法
- 数组的排序算法
- 基于比较的排序算法
- 算法 基于比较的排序
- 基于插入的排序算法
- 基于选择的排序算法
- 数组排序的常用算法
- 多维数组排序的算法
- 数组基本的排序算法
- 一种基于归并排序及随机数生成器对一个给定数组进行随机排列的算法
- c语言核心整理之深入数组,熟练常用的基于数组的排序和搜索算法
- 基于数组的二分查找算法
- 关于Android APN的学习
- KafkaConsumer使用详解
- Android 侧滑删除的实现
- 【接口】-MQ VS WebService
- Javascript unit test framework
- 基于数组的排序算法
- windows和linux的动态库环境变量
- ambari+hdp+spark集群本地源搭建详细图解教程
- 最常见的 20 个 jQuery 面试问题及答案
- 使用ajaxFileupload实现多文件批量上传
- 深入理解okio的优化思想
- Java中nextInt()后接nextLine()读取不到数据
- 卢星宇应彼得•斯托扬诺夫夫妇邀请访问保加利亚
- RTP 与RTCP 解释. 含同步时间戳 RTP协议是real-time transport protocol的缩写,被设计来传输流媒体数据,有着广泛的应用,其它相关介绍自己去看RFC,我不打算