七种内部排序算法基本原理及实现

来源:互联网 发布:acdsee mac中文破解版 编辑:程序博客网 时间:2024/05/21 11:14

概述    

按照是否使用外存,排序算法可分为内部排序和外部排序两种。

内部排序有如下几种常用的排序方法:

插入排序

直接插入排序

希尔排序

选择排序

简单选择排序

堆排序

交换排序

冒泡排序

快速排序

归并排序

插入排序

直接插入排序

该算法的基本思想可以描述为:在要排序的一组数中,假设前面(n-1)[n>=2]个数已经是排好了顺序的,现在要把第n个数字插到前面的有序数组中,使得这n个数也是排好顺序的。如此反复循环,直到全部都排好了顺序。

希尔排序

希尔排序又称为缩小增量排序,是直接插入排序的改进和优化。

其基本思想是先将序列分成若干子序列分别进行直接插入排序,待整个序列基本有序时再对整体进行一次直接插入排序。

算法特点是子序列不是简单的“逐段分割”,而是相邻某个“增量”的记录构成一个子序列。一般增量序列的选择直接使用上次的一半,例如整个序列长度为N,则第一次的增量序列可以选择为N/2。并注意,最后一个增量必须是1,这也是结束条件。

选择排序

简单选择排序

简单选择排序的基本思想可以描述为:在要排序的一组数中,选出最小的一个数与第一个位置的数交换;然后在剩下的数中再找出最小的与第二个位置的数交换,如此循环到倒数第二个数和最后一个数比较为止。

堆排序

当且仅当满足以下条件时,关键字序列K1—Kn可以称为堆:树中任一非叶子结点的关键字均不大于(不小于)其左右孩子节点的关键字。

用大顶堆排序的基本思想:

1)       先将输入的数字序列初始化成为大顶堆;

2)       将堆顶(也肯定是序列里最大的关键字)R[1]和序列最后一个关键字R[n]交换,由此得到新的无需区R[1]..R[n],而R[n]显然已经是有序区;

3)       调整R[1]..R[n]为有序堆,再将其堆顶与最末的元素交换,循环执行,直至所有元素都执行过排序为止。

交换排序

冒泡排序

冒泡算法的运作如下(从后往前):

1)       比较相邻元素,如果第一个比第二个大,就交换他们;

2)       对每一对相邻元素做如此操作,从开始第一对到结尾最后一对。执行完之后,最后一个元素应该是最大的数;

3)       针对所有的元素重复以上操作,除了最后一个;

4)       持续每次对越来越少的元素重复之前步骤,直到没有任何一对数字要比较;

快速排序

快速排序采用了分治的策略解决问题,分治法的核心思想是:将问题分解成若干个规模更小但结构与原问题相似的子问题。递归的解决这些子问题,最终将子问题的解组合成为原问题的解。

设当前待排序的无序区为R[low…high],利用分治法可以将快速排序的基本思想描述为:

1)       在数列中随机选取一个记录作为基准pivot(一般直接选取第一个),以此基准将当前序列划分为左右两个较小的子区间Rl和Rr,并使左区间中记录都小于pivot,右区间中值都大于pivot。此时pivot已经处在了正确的位置上,所以无需再次参加后续的排序。

2)       通过递归方法对左区间和右区间再次进行划分;

3)       递归返回时,序列已经成为有序,排序结束。

这里注意两点:

一般pivot会直接选择第一个记录,但随机选取的方法能够更好的照顾到算法对所有类型数列的时间消耗,对各种类型数列可以提高排序的效率;不论pivot选择哪里,总会有特殊情况导致算法耗时达到O(n2)的级别。

由于普遍认为20以内的数组排序,直接插入排序的效率是最高的,所以当数组长度小于20时,可以直接采用直接插入排序进行排序,而不是再次执行递归。

归并排序

归并排序是将两个(或以上)有序表合并成一个新的有序表,即把待排序的序列分成若干个有序的子序列,再把有序的子序列合并成整体有序的排序过程。

归并排序是建立在归并操作基础上的算法,该算法是采用分治法的一个典型应用。

归并排序的算法描述如下:

1)       申请空间,申请的大小应是两个已经有序的序列的长度之和,用来存放合并后的序列;

2)       设定两个指针,最初位置分别是两个已经排序序列的起始位置;

3)       比较两个指针指向的元素,选择相对小的放入合并后的空间,指针顺势移动到下一个元素;

4)       重复步骤3,直至某一个指针超出序列尾;

5)       将另一个序列剩下的所有元素直接复制到合并空间中;

代码实现

结合以上算法原理,采用C语言在Linux平台(ubuntu 14.04)上简单实现了这些算法。

sort.h头文件,约定了要排序数组的大小和数组元素数值的上限。

/*************************************************************************    > File Name: sort.h    > Author: Wujl    > Mail: wujl_0351@163.com     > Created Time: 2014年08月28日 星期四 15时01分15秒 ************************************************************************/#ifndef SORT_H#define SORT_H#define ARR_LEN 20/*The length of the array which should be sorted*/#define MAX_NUM ARR_LEN * 10/*The number in this array should be limited. For example, array length is 10, the number in this array is in [0, 99]*/#endif

sort.c文件,实现了以上七种排序算法。
/*************************************************************************    > File Name: sort.c    > Author: Wujl    > Mail: wujl_0351@163.com     > Created Time: 2014年08月28日 星期四 15时01分44秒 ************************************************************************/#include <stdio.h>#include <stdlib.h>#include "sort.h"/*Create an array which length=ARR_LEN randomlly, this will be sort here.*/void gen_rand_arr(int *arr, const int arr_len){int i = 0;for(; i < arr_len; i++){*(arr + i) = rand() % MAX_NUM;}}/*Create an array which is sorted to test sort algorithm time.*/void gen_sorted_arr(int *arr, const int arr_len){int i = 0;for(; i < arr_len; i++){*(arr + i) = i;}}void gen_dis_sorted_arr(int *arr, const int arr_len){int i = 0;for(; i < arr_len; i++){*(arr + i) = MAX_NUM - i;}}void print_arr(int *arr, const int arr_len){int i = 0;for(; i < arr_len; i++){printf("0x%04x\t", *(arr + i));}printf("\n");}/*Array dest and src has same length, and this function copy data from src to dest.*/void copy_arr(int *dest, int *src, const int arr_len){int i = 0;while(i < arr_len){*(dest + i) = *(src + i);i++;}}/*I just set a rule here: from small number to big number is the sorted array in my program.*/int is_sorted_arr(int *arr, const int arr_len){int i = 0;for(; i < arr_len - 1; i++){if(*(arr + i) > *(arr + i + 1)){return -1;}}return 0;}void swap(int *num1, int *num2){int temp = *num1;*num1 = *num2;*num2 = temp;}void direct_insert_sort(int *arr, const int arr_len){int i = 0, j = 0, temp = 0;for(i = 1; i < arr_len; i++){for(j = i - 1; j >= 0; j--){if(*(arr + j) > *(arr + j + 1)){swap(arr + j, arr + j + 1);}else{break;}}}}void hash_sort(int *arr, const int arr_len){int delta = arr_len / 2;int i = 0, j = 0, temp = 0;for(delta = arr_len / 2; delta >= 1; delta /= 2){for(i = delta; i < arr_len; i++){for(j = i - delta; j >= 0 && *(arr + j) > *(arr + j + delta); j -= delta){swap(arr + j, arr + j + delta);}}}}void select_sort(int *arr, const int arr_len){int i = 0, j = 0;int min_idx = 0;for(i = 0; i < arr_len; i++){min_idx = i;for(j = i + 1; j < arr_len; j++){if(*(arr + min_idx) > *(arr + j)){min_idx = j;}}swap(arr + i, arr + min_idx);}}void quick_sort(int *arr, const int l, const int r){if(l < r){int i = l, j = r, x = *(arr + l);while(i < j){while(i < j && *(arr + j) > x){j--;}if(i < j){*(arr + i) = *(arr + j);i++;}while(i < j && *(arr + i) < x){i++;}if(i < j){*(arr + j) = *(arr + i);j--;}}*(arr + i) = x;quick_sort(arr, l, i - 1);quick_sort(arr, i + 1, r);}}void bubble_sort(int *arr, const int arr_len){int i, j;for(i = arr_len - 1; i > 1; i--){for(j = 0; j < i; j++){if(*(arr + j) > *(arr + j + 1)){swap(arr + j, arr + j + 1);}}}}/*============================Heap sort start===============================*/void adjust_add(int *, int);void create_heap(int *arr, const int arr_len){int i = 1;for(; i < arr_len; i++){adjust_add(arr, i);}}void adjust_add(int *arr, int idx){int father_idx = (idx - 1) / 2;while(father_idx >= 0){if(*(arr + father_idx) < *(arr + idx)){swap(arr + father_idx, arr + idx);idx = father_idx;father_idx = (idx - 1) / 2;}else{break;}}}void adjust_del(int *arr, int end_idx){int father_idx = 0;int max_child_idx = father_idx * 2 + 1;while(max_child_idx <= end_idx){if((max_child_idx + 1) <= end_idx && *(arr + max_child_idx) < *(arr + max_child_idx + 1))max_child_idx++;if(*(arr + father_idx) > *(arr + max_child_idx)){break;}else{swap(arr + father_idx, arr + max_child_idx);father_idx = max_child_idx;max_child_idx = max_child_idx * 2 + 1;}}}void heap_sort(int *arr, const int arr_len){create_heap(arr, arr_len);int end_idx = arr_len - 1;while(end_idx > 0){swap(arr, arr + end_idx);end_idx--;adjust_del(arr, end_idx);}}/*========================Heap sort end============================================*//*========================Merge sort start==========================================*/void merge_array(int *arr, int first, int mid, int last, int *temp){int i = first, j = mid + 1, 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 + i + first) = *(temp + i);}}void merge_sort_step(int *arr, int first, int last, int *temp){if(first < last){int mid = (first + last) / 2;merge_sort_step(arr, first, mid, temp);merge_sort_step(arr, mid + 1, last, temp);merge_array(arr, first, mid, last, temp);}}void merge_sort(int *arr, const int arr_len){int *temp = (int *)malloc(arr_len * sizeof(int));if(NULL == temp){return ;}merge_sort_step(arr, 0, arr_len - 1, temp);free(temp);temp = NULL;}

test.c文件,对sort.c文件中的各个函数进行了单元测试,并对各个排序算法进行简单的排序测试。
/*************************************************************************    > File Name: test.c    > Author: Wujl    > Mail: wujl_0351@163.com     > Created Time: 2014年08月28日 星期四 15时02分34秒 ************************************************************************/#include <stdio.h>#include <time.h>#include "sort.h"void test_gen_arr(){int arr[ARR_LEN];printf("Random array will be generated now:\n");gen_rand_arr(arr, ARR_LEN);print_arr(arr, ARR_LEN);printf("\nSorted array generated now.\n");gen_sorted_arr(arr, ARR_LEN);print_arr(arr, ARR_LEN);printf("\nDis_sorted array generated now.\n");gen_dis_sorted_arr(arr, ARR_LEN);print_arr(arr, ARR_LEN);}void test_copy_arr(){int arr[ARR_LEN];printf("Random array will be generated now:\n");gen_rand_arr(arr, ARR_LEN);print_arr(arr, ARR_LEN);int dest[ARR_LEN];copy_arr(dest, arr, ARR_LEN);printf("Copied array is:\n");print_arr(dest, ARR_LEN);}void test_is_sorted_arr(){int arr[ARR_LEN];printf("Random array will be generated now:\n");gen_rand_arr(arr, ARR_LEN);print_arr(arr, ARR_LEN);int is_sorted = is_sorted_arr(arr, ARR_LEN);if(0 == is_sorted){printf("This is a sorted array.\n");}else{printf("Not a sorted array!\n");}printf("\nSorted array generated now.\n");gen_sorted_arr(arr, ARR_LEN);print_arr(arr, ARR_LEN); is_sorted = is_sorted_arr(arr, ARR_LEN);if(0 == is_sorted){printf("This is a sorted array.\n");}else{printf("Not a sorted array!\n");}printf("\nDis_sorted array generated now.\n");gen_dis_sorted_arr(arr, ARR_LEN);print_arr(arr, ARR_LEN);is_sorted = is_sorted_arr(arr, ARR_LEN);if(0 == is_sorted){printf("This is a sorted array.\n");}else{printf("Not a sorted array!\n");}}void test_direct_insert_sort(void){int arr[ARR_LEN];gen_rand_arr(arr, ARR_LEN);printf("Array is:\n");print_arr(arr, ARR_LEN);direct_insert_sort(arr, ARR_LEN);printf("After direct insert sorting, array is:\n");print_arr(arr, ARR_LEN);if(0 == is_sorted_arr(arr, ARR_LEN)){printf("This is a sorted array.\n");}else{printf("!!!After direct insert sort, not sorted!!!\n");}}void test_hash_sort(void){int arr[ARR_LEN];gen_rand_arr(arr, ARR_LEN);printf("Array is:\n");print_arr(arr, ARR_LEN);hash_sort(arr, ARR_LEN);printf("After hash sort, array is:\n");print_arr(arr, ARR_LEN);if(0 == is_sorted_arr(arr, ARR_LEN)){printf("This is a sorted array.\n");}else{printf("!!!After direct insert sort, not sorted!!!\n");}}void test_select_sort(void){int arr[ARR_LEN];gen_rand_arr(arr, ARR_LEN);printf("Array is:\n");print_arr(arr, ARR_LEN);select_sort(arr, ARR_LEN);printf("After select sort, array is:\n");print_arr(arr, ARR_LEN);if(0 == is_sorted_arr(arr, ARR_LEN)){printf("This is a sorted array.\n");}else{printf("!!!After direct insert sort, not sorted!!!\n");}}void test_quick_sort(void){int arr[ARR_LEN];gen_rand_arr(arr, ARR_LEN);printf("Array is:\n");print_arr(arr, ARR_LEN);quick_sort(arr, 0, ARR_LEN - 1);printf("After quick_sort, array is:\n");print_arr(arr, ARR_LEN);if(0 == is_sorted_arr(arr, ARR_LEN)){printf("This is a sorted array.\n");}else{printf("!!!After direct insert sort, not sorted!!!\n");}}void test_bubble_sort(void){int arr[ARR_LEN];gen_rand_arr(arr, ARR_LEN);printf("Array is:\n");print_arr(arr, ARR_LEN);bubble_sort(arr, ARR_LEN);printf("After bubble sort, array is:\n");print_arr(arr, ARR_LEN);if(0 == is_sorted_arr(arr, ARR_LEN)){printf("This is a sorted array.\n");}else{printf("!!!After bubble sort, not sorted!!!\n");}}void test_heap_sort(void){//int arr[10] = {//57, 68, 59, 52, 73, 64, 26, 89, 96, 34//};//heap_sort(arr, 10);//print_arr(arr, 10);int arr[ARR_LEN];gen_rand_arr(arr, ARR_LEN);printf("Array is:\n");print_arr(arr, ARR_LEN);heap_sort(arr, ARR_LEN);printf("After heap sort, array is:\n");print_arr(arr, ARR_LEN);if(0 == is_sorted_arr(arr, ARR_LEN)){printf("This is a sorted array.\n");}else{printf("!!!After heap sort, not sorted!!!\n");}}void test_merge_sort(void){int arr[ARR_LEN];gen_rand_arr(arr, ARR_LEN);printf("Array is:\n");print_arr(arr, ARR_LEN);merge_sort(arr, ARR_LEN);printf("After merge sort, array is:\n");print_arr(arr, ARR_LEN);if(0 == is_sorted_arr(arr, ARR_LEN)){printf("This is a sorted array.\n");}else{printf("!!!After merge sort, not sorted!!!\n");}}int main(int argc, unsigned char **argv){srand((unsigned char)time(NULL));//test_gen_arr();//test_copy_arr();//test_is_sorted_arr();//test_direct_insert_sort();//test_hash_sort();//test_select_sort();//test_quick_sort();//test_bubble_sort();//test_heap_sort();test_merge_sort();return 0;}

Makefile文件用于生成可执行目标文件,这里定义为sort.elf。
CC = gcc TARGET = sort.elfSRC = sort.c test.call:$(CC) -o $(TARGET) $(SRC)clean:rm -rf *~ $(TARGET)

经简单测试,该程序可以对随机生成的数组进行排序(默认排列成由小到大的数组)。

改进

今后在进一步加强对各个算法实现的测试的基础上,将对各个算法针对不同长度数组的排序效率进行测试。

0 0
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 给区组织部的介绍信给到社区怎么办 被丈夫和儿子强送精神病院怎么办 练车穿短袖晒的胳膊特别黑怎么办 车子卖了对方迟迟不过户怎么办 成都华西医院就诊卡密码忘了怎么办 资阳办健康证怎么办要预约吗 头发出油厉害怎么办民间小偏方 你帮助别人别人却想着害你怎么办 怀孕接触有辐射的东西回怎么办 苹果手机用久了有点卡怎么办 4s店把我车撞了怎么办 长安之星2代大灯高不聚光怎么办 被电动车撞了人跑了怎么办 车被电动车撞了对方跑了怎么办 房子卖了户口没地方迁怎么办 酷派大神f2开不开机怎么办 酷派手机玩游戏竖屏怎么办 身上起红疙瘩很痒怎么办越挠越多 苹果6s指纹解锁坏了怎么办 案子结了网上追逃的怎么办 贷款买的手机不还了会怎么办 支付宝手机号没用了登陆不了怎么办 支付宝绑定的手机号注销了怎么办 考勤机进水了不能识别指纹怎么办? 网商银行人脸识别失败怎么办 电脑网页上的字变小了怎么办 把光驱换成固态硬盘后不识别怎么办 相机内存卡电脑读不出来怎么办 sd卡在电脑上无法格式化怎么办 内存卡突然读不出来了怎么办 怀孕两个月胎儿死在腹中怎么办 香港公司在大陆卖地皮资金怎么办 结婚证上的身份证号码错了怎么办 身份证快过期了人在外地怎么办 邮政电话银行登录密码忘记了怎么办 如果欠了3w不敢和家里说怎么办 大四学生欠了3w该怎么办 房子付了首付贷款贷不下来怎么办 浙江嵊泗人在金华丢了身份证怎么办 一证5号够了怎么办新卡 微信号被盗实名认证是自己的怎么办