amur-leopard

导航

排序

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)    收藏  举报