排序
1.直接插入排序
名称: 直接插入排序
分类: 插入排序类
平均时间复杂度:O(n^2)
最好情况: O(n)
最坏情况: O(n^2)
辅助空间: O(1)
稳定性: 稳定
1 /** 2 * @brief 插入排序 3 * 4 * @param list 待排序列 5 * @param list_size 待排序列大小 6 */ 7 void insert_sort(int *list, int list_size) 8 { 9 int i, j; // 用于循环 10 int temp; // 用于暂存待插入值 11 for(i = 1; i < list_size; ++i) 12 { 13 if(*(list + i) < *(list + i - 1)) 14 { 15 temp = *(list + i); 16 for(j = i - 1; j >= 0 && temp < *(list + j); --j) 17 { 18 *(list + j + 1) = *(list + j); 19 } 20 *(list + j + 1) = temp; 21 } 22 } 23 }
2.希尔排序
名称: 希尔排序
分类: 插入排序类
平均时间复杂度:O(nlogn)-O(n^2)
最好情况: O(n^1.3)
最坏情况: O(n^2)
辅助空间: O(1)
稳定性: 不稳定
1 /** 2 * @brief 希尔排序 3 * 4 * @param list 待排序列 5 * @param list_size 待排序列大小 6 * @param gaps 间距序列 7 * @param gaps_size 间距序列大小 8 */ 9 void shell_sort(int *list, int list_size, int *gaps, int gaps_size) 10 { 11 int i; // 用于循环 12 for(i = 0; i < gaps_size; ++i) 13 { 14 shell_insert(list, list_size, *(gaps + i)); 15 } 16 }
1 /** 2 * @brief 希尔插入 3 * 4 * @param list 待排序列 5 * @param list_size 待排序列大小 6 * @param gap 间距 7 */ 8 void shell_insert(int *list, int list_size, int gap) 9 { 10 int i, j; // 用于循环 11 int temp; // 用于暂存待插入值 12 for(i = gap; i < list_size; ++i) 13 { 14 temp = *(list + i); 15 for(j = i - gap; j >= 0 && temp < *(list + j); j -= gap) 16 { 17 *(list + j + gap) = *(list + j); 18 } 19 *(list + j + gap) = temp; 20 } 21 }
3.简单选择排序
名称: 简单选择排序
分类: 选择排序类
平均时间复杂度:O(n^2)
最好情况: O(n^2)
最坏情况: O(n^2)
辅助空间: O(1)
稳定性: 不稳定
1 /** 2 * @brief 简单选择排序 3 * 4 * @param list 待排序列 5 * @param list_size 待排序列大小 6 */ 7 void select_sort(int *list, int list_size) 8 { 9 int i, j; // 用于循环 10 int min_index; // 用于指向最小值 11 for(i = 0; i < list_size - 1; ++i) // 最后一个不用处理 12 { 13 // 寻找最小值 14 min_index = i; 15 for(j = i + 1; j < list_size; ++j) 16 { 17 if(*(list + j) < *(list + min_index)) 18 { 19 min_index = j; 20 } 21 } 22 23 if(i != min_index) 24 { 25 swap(*(list + i), *(list + min_index)); // 当前值与最小值交换 26 } 27 } 28 }
4.堆排序
名称: 堆排序
分类: 选择排序类
平均时间复杂度:O(nlogn)
最好情况: O(nlogn)
最坏情况: O(nlogn)
辅助空间: O(1)
稳定性: 不稳定
1 /** 2 * @brief 堆排序 3 * 4 * @param list 待排序列 5 * @param list_size 待排序列大小 6 */ 7 void heap_sort(int *list, int list_size) 8 { 9 int i; // 用于循环 10 // 创建大根堆 11 for(i = 1; i < list_size; ++i) 12 { 13 up_heap(list, list_size, i); // 自当前节点向上调整 14 } 15 16 // 调整 17 for(i = list_size - 1; i > 0; --i) 18 { 19 swap(*list, *(list + i)); // 根结点与尾结点交换 20 down_heap(list, i, 0); // 自根节点向下调整 21 } 22 }
1 /** 2 * @brief 节点向上调整 3 * 4 * @param list 待调整序列 5 * @param list_size 序列大小 6 * @param index 待上整节点位置 7 */ 8 void up_heap(int *list, int list_size, int index) 9 { 10 int parent_index = (index - 1) / 2; // 父节点位置 11 if(parent_index >= 0 && *(list + index) > *(list + parent_index)) // 大于父节点值,需上调 12 { 13 swap(*(list + index), *(list + parent_index)); // 交换 14 up_heap(list, list_size, parent_index); // 调整父节点 15 } 16 }
1 /** 2 * @brief 节点向下调整 3 * 4 * @param list 待调整序列 5 * @param list_size 子序列大小 6 * @param index 待下调节点位置 7 */ 8 void down_heap(int * list, int list_size, int index) 9 { 10 int lchild_index = 2 * index + 1; // 左子节点位置 11 int rchild_index = 2 * index + 2; // 右子节点位置 12 int max_child_index; // 值较大子节点位置 13 if(lchild_index < list_size) // 有左子节点 14 { 15 max_child_index = lchild_index; 16 if(rchild_index < list_size && * (list + rchild_index) > * (list + lchild_index)) // 有右子节点,且右节点值大于左子节点值 17 { 18 max_child_index = rchild_index; 19 } 20 if(*(list + index) < *(list + max_child_index)) 21 { 22 swap(*(list + index), *(list + max_child_index)); // 结点值与子节点中的较大值交换 23 down_heap(list, list_size, max_child_index); // 继续向下调整 24 } 25 } 26 }
5.冒泡排序
名称: 冒泡排序
分类: 交换排序类
平均时间复杂度:O(n^2)
最好情况: O(n)
最坏情况: O(n^2)
辅助空间: O(1)
稳定性: 稳定
1 /** 2 * @brief 冒泡排序 3 * 4 * @param list 待排序列 5 * @param list_size 待排序列大小 6 */ 7 void bubble_sort(int *list, int list_size) 8 { 9 int i, j; // 用于循环 10 for(i = 0; i < list_size - 1; ++i) // 只剩一个数时不用处理 11 { 12 for(j = 0; j < list_size - 1 - i; ++j) // 已有序部分(长度为i)不用处理 13 { 14 if(*(list + j) > *(list + j + 1)) // 相邻逆序 15 { 16 swap(*(list + j), *(list + j + 1)); 17 } 18 } 19 } 20 }
6.快速排序
名称: 快速排序
分类: 交换排序类
平均时间复杂度:O(nlogn)
最好情况: O(nlogn)
最坏情况: O(n^2)
辅助空间: O(1)
稳定性: 不稳定
1 /** 2 * @brief 快速排序 3 * 4 * @param list 待排序列 5 * @param list_size 待排序列大小 6 */ 7 void quick_sort(int *list, int list_size) 8 { 9 q_sort(list, 0, list_size - 1); 10 }
1 /** 2 * @brief 子序列快速排序 3 * 4 * @param list 待排序列 5 * @param low 待排子序列起始位置 6 * @param high 待排子序列终止位置 7 */ 8 void q_sort(int *list, int low, int high) 9 { 10 int pivot_index; // 用于指向枢轴 11 if(low < high) 12 { 13 pivot_index = partition(list, low, high); // 划分 14 q_sort(list, low, pivot_index - 1); // 低子序列 15 q_sort(list, pivot_index + 1, high); // 高子序列 16 } 17 }
1 /** 2 * @brief 分区函数 3 * 4 * @param list 待排序列 5 * @param low 待分区子序列起始位置 6 * @param high 待分区子序列结束位置 7 * 8 * @return 枢轴位置 9 */ 10 int partition(int *list, int low, int high) 11 { 12 int pivot = *(list + low); // 字序列的第一个值作为枢轴 13 while(low < high) 14 { 15 while(low < high && pivot <= *(list + high)) 16 { 17 --high; 18 } 19 *(list + low) = *(list + high); 20 while(low < high && pivot >= *(list + low)) 21 { 22 ++low; 23 } 24 *(list + high) = *(list + low); 25 } 26 *(list + low) = pivot; 27 return low; 28 }
7.归并排序
名称: 归并排序
分类: 归并排序类
平均时间复杂度:O(nlogn)
最好情况: O(nlogn)
最坏情况: O(nlogn)
辅助空间: O(n)
稳定性: 稳定
1 /** 2 * @brief 归并排序 3 * 4 * @param list 待排序列 5 * @param list_size 待排序列大小 6 */ 7 void merge_sort(int *list, int list_size) 8 { 9 if(list_size > 1) 10 { 11 // 均分为两个部分 12 int *list1 = list; 13 int list1_size = list_size / 2; 14 int *list2 = list + list1_size; 15 int list2_size = list_size - list1_size; 16 17 // 分别归并排序 18 merge_sort(list1, list1_size); 19 merge_sort(list2, list2_size); 20 21 // 归并 22 merge(list1, list1_size, list2, list2_size); 23 } 24 }
1 /** 2 * @brief 归并两个有序序列 3 * 4 * @param list1 有序序列1 5 * @param list1_size 有序序列1的大小 6 * @param list2 有序序列2 7 * @param list2_size 有序序列2的大小 8 */ 9 void merge(int *list1, int list1_size, int *list2, int list2_size) 10 { 11 int i, j, k; // 用于循环 12 i = j = k = 0; // 初始化 13 int *temp_list = (int *)malloc((list1_size + list2_size) * sizeof(int)); // 用于暂存归并结果 14 while(i < list1_size && j < list2_size) // 循环直到有一个序列处理完 15 { 16 // 较小数据放入结果序列 17 *(temp_list + k++) = *(list1 + i) <= *(list2 + j) ? *(list1 + i++) : *(list2 + j++); 18 } 19 while(i < list1_size) // 若序列1还没处理完,将其剩余部分放入结果序列 20 { 21 *(temp_list + k++) = *(list1 + i++); 22 } 23 while(j < list2_size) // 若序列2还没处理完,将其剩余部分放入结果序列 24 { 25 *(temp_list + k++) = *(list2 + j++); 26 } 27 // 结果序列放回原始序列 28 for(int t = 0; t < list1_size + list2_size; ++t) 29 { 30 *(list1 + t) = *(temp_list + t); 31 } 32 free(temp_list); 33 }
相关函数
1 /** 2 * @brief 交换两个整数的值 3 * 4 * param a 待交换的第一个整数 5 * param b 待交换的第二个整数 6 */ 7 inline void swap(int &a, int &b) 8 { 9 int temp = a; 10 a = b; 11 b = temp; 12 }
1 /** 2 * @brief 打印序列 3 * 4 * @param list 待打印序列 5 * @param list_size 待打印序列大小 6 */ 7 inline void print_list(int *list, int list_size) 8 { 9 if(list_size >= 1) 10 { 11 printf("%d", *list); 12 } 13 for(int i = 1; i < list_size; ++i) 14 { 15 printf(" %d", *(list + i)); 16 } 17 printf("\n"); 18 }
测试
1 /** 2 * @brief 测试函数 3 */ 4 void main() 5 { 6 // 测试数据 7 int a1[1] = {1}; 8 int a2[2] = {2, 1}; 9 int a3[9] = {3, 7, 2, 6, 4, 8, 5, 9, 1}; 10 11 void (*sort)(int *, int); // 函数指针 12 13 // 排序方式 14 sort = &insert_sort; // 插入排序 15 //sort = &select_sort; // 简单选择排序 16 //sort = &heap_sort; // 堆排序 17 //sort = &bubble_sort; // 冒泡排序 18 //sort = &quick_sort; // 快速排序 19 //sort = &merge_sort; // 归并排序 20 21 // 排序和输出 22 sort(a1, 1); print_list(a1, 1); 23 sort(a2, 2); print_list(a2, 2); 24 sort(a3, 9); print_list(a3, 9); 25 26 //// 希尔排序 27 //int gaps[3] = {3, 2, 1}; 28 //shell_sort(a1, 1, gaps, 3); print_list(a1, 1); 29 //shell_sort(a2, 2, gaps, 3); print_list(a2, 2); 30 //shell_sort(a3, 9, gaps, 3); print_list(a3, 9); 31 32 system("pause"); 33 }
posted on 2014-06-01 10:50 amur-leopard 阅读(162) 评论(0) 收藏 举报
浙公网安备 33010602011771号