一.排序算法


1.插入排序

1) 直接插入排序:(插入类)

 1 void InsertSort( ElemType R[], int n )
2 {
3 for ( int i = 2; i <= n; i++ )
4 {
5 if ( R[i].key < R[i - 1].key )
6 {
7 R[0] = R[i];
8 for ( int j = i - 1; j > 0 && ( R[0].key < R[j].key ); j-- )
9 R[j + 1] = R[j];
10 R[j + 1] = R[0];
11 }
12 }
13 }

最好情况(顺序有序):

  1)比较次数: $\sum_{i=2}^{n} 1=n-1$

  2)移动次数: 0

最坏情况(逆序有序):

  1)比较次数: $\sum_{i=2}^{n} i=\frac {(n+2)(n-1)}{2}$

  2)移动次数: $\sum_{i=2}^{n} (i+1)=\frac {(n+4)(n-1)}{2}$

2)折半插入排序:(插入类)

 1 void BiInsertSort( ElemType R[], int n )
2 {
3 for ( int i = 2; i <= n; i++ )
4 {
5 R[0] = R[i];
6 int low = 1, high = i - 1;
7 while ( low <= high )
8 {
9 int mid = ( low + high ) / 2;
10 if ( R[0].key < R[m].key ) high = mid - 1;
11 else low = mid + 1;
12 }
13 for ( int j = i - 1; j > high; j-- )
14 R[j + 1] = R[j];
15 R[j + 1] = R[0];
16 }
17 }

3)希尔排序(又称缩小增量排序)(插入类)

 1 // 当dk=1时,即为直接插入排序
2 void ShellSort( ElemType R[], int n )
3 {
4 for ( int dk = n / 2; dk >= 1; dk /= 2 )
5 {
6 for ( int i = dk + 1; i <= n; i++ )
7 {
8 if ( R[i].key < R[i - dk].key )
9 {
10 R[0] = R[i];
11 for ( j = i - dk; j > 0 && ( R[0].key < R[j].key ); j -= dk )
12 R[j + dk] = R[j];
13 R[j + dk] = R[0];
14 }
15 }
16 }
17 }

2.交换排序

1)起泡排序(冒泡排序)(交换类)

 1 void BubbleSort( ElemType R[], int n )
2 {
3 for ( int i = 1; i <= n - 1; i++ )
4 {
5 bool flag = false;
6 for ( int j = n; j > i; j-- )
7 {
8 if (R[j].key < R[j-1].key )
9 {
10 swap( R[j], R[j - 1] );
11 flag = true;
12 }
13 }
14 if ( !flag ) return;
15 }
16 }

2)快速排序:(交换类)

 1 void Partition( ElemType R[], int low, int high );
2
3 // 快排
4 void QuickSort( ElemType R[], int low, int high )
5 {
6 if ( low >= high ) return;
7 int pivotpos = Partition( R, low, high );
8 QuickSort( R, low, pivotpos - 1 );
9 QuickSort( R, pivotpos + 1, high );
10 }
11
12 // 划分
13 void Partition( ElemType R[], int low, int high )
14 {
15 ElemType pivot = R[low];
16 while ( low < high )
17 {
18 while ( low < high && R[high].key >= pivot.key ) high--;
19 R[low] = R[high];
20 while ( low < high && R[low].key <= pivot.key ) low++;
21 R[high] = R[low];
22 }
23 R[low] = pivot;
24 return low;
25 }

3.选择排序

1)简单选择排序(选择类)

 1 void SelectSort( ElemType R[], int n )
2 {
3 for ( int i = 0; i < n - 1; i++ )
4 {
5 int min = i;
6 for ( int j = i + 1; j < n; j++ )
7 {
8 if ( R[j].key < R[min].key ) min = j;
9 }
10 if ( min != i ) swap( R[i], R[min] );
11 }
12 }

2)堆排序(选择类)

 1 void AdjustDown( ElemType R[], int s, int n );
2
3 void HeapSort( ElemType R[], int n )
4 {
5 for ( int i = n / 2; i > 0; i-- )
6 void AdjustDown( R, i, n );
7 for ( int i = n; i > 1; i-- )
8 {
9 swap( R[i], R[1] );
10 AdjustDown( R, 1, i - 1 );
11 }
12 }
13
14 // 向下调整
15 void AdjustDown( ElemType R[], int s, int n )
16 {
17 R[0] = R[s];
18 for ( int i = 2 * s; i <= n; i *= 2 )
19 {
20 if ( i < n&&R[i].key < R[i + 1].key ) i++;
21 if (R[0].key >=R[i].key ) break;
22 else
23 {
24 R[s] = R[i]; s = i;
25 }
26 }
27 R[s] = R[0];
28 }
29
30 // 向上调整
31 void AdjustUp( ElemType R[], int s )
32 {
33 R[0] = R[s];
34 int p = s / 2;
35 while ( p > 0 && R[p].key < R[0].key )
36 {
37 R[s] = R[p];
38 s = p;
39 p /= 2;
40 }
41 R[s] = R[0];
42 }

4.归并排序(归并类)

 1 void Merge( ElemType R[], int low, int mid, int high );
2
3 void MergeSort( ElemType R[], int low, int high )
4 {
5 if ( low >= high ) return;
6 int mid = ( low + high ) / 2;
7 MergeSort( R, low, mid );
8 MergeSort( R, mid + 1, high );
9 Merge( R, low, mid, high );
10 }
11
12 ElemType B[MAXSIZE];
13 void Merge( ElemType R[], int low, int mid, int high )
14 {
15 int i,j,k;
16 for ( i = low; i <= high; i++ )
17 B[i] = R[i];
18 i = k = low, j = mid + 1;
19 while ( i <= mid && j <= high )
20 {
21 if ( B[i].key <= B[j].key )
22 R[k++] = B[i++];
23 else
24 R[k++] = B[j++];
25 }
26 while ( i <= mid ) R[k++] = B[i++];
27 while ( j <= high ) R[k++] = B[j++];
28 }

二.综合题(算法)

1.设顺序表用数组R[]表示,表中存储在数组下标1~m+n的范围内,前m个元素递增有序,后n个元素递增有序,设计一个算法,使得整个顺序表有序

 1 void InsertSort( ElemType R[], int m, int n )
2 {
3 for ( int i = m + 1; i <= m + n; i++ )
4 {
5 if ( R[i].key < R[i - 1].key )
6 {
7 R[0] = R[i];
8 for ( int j = i - 1; j > 0 && ( R[0].key < R[j].key ); j-- )
9 R[j + 1] = R[j];
10 R[j + 1] = R[0];
11 }
12 }
13 }

2.计数排序:对表进行排序并将结果放到另一个新的表中,要求表中所有关键码互不相同

 1 void CountSort( ElemType A[], ElemType B[], int n )
2 {
3 for ( int i = 0; i < n; i++ )
4 {
5 int cnt = 0;
6 for ( int j = 0; j < n; j++ )
7 if ( A[i].key > A[j].key )cnt++;
8 B[cnt] = A[i];
9 }
10 }

3.双向冒泡排序

 1 // 思想:第一趟通过交换把最大的放最后,第二趟通过交换把最小的放最前,反复进行
2 void BubbleSort( ElemType A[], int n )
3 {
4 int low = 0, high = n - 1, i;
5 bool flag = true;
6 while ( low < high && flag )
7 {
8 flag = false;
9 for (i = low; i < high; i++ )
10 {
11 if (A[i]>A[i+1] )
12 {
13 swap( A[i], A[i + 1] ); flag = true;
14 }
15 }
16 high--;
17 for ( i = high; i > low; i-- )
18 {
19 if ( A[i] < A[i - 1] )
20 {
21 swap( A[i], A[i - 1] ); flag = true;
22 }
23 }
24 low++;
25 }
26 }

4.单链表的简单选择排序(假设不带表头结点)

 1 void SelectSort( LinkList& L )
2 {
3 LinkList h, p, s, pre, r;
4 h = L;
5 while ( h )
6 {
7 p = s = h; pre = r = NULL;
8 // 找最大结点s
9 while ( p )
10 {
11 if (p->data>s->data )
12 {
13 s = p; r = pre;
14 }
15 pre = p;
16 p = p->next;
17 }
18 // 脱链
19 if ( s == h ) h = h->next;
20 else r->next = s->next;
21 // 头插法
22 s->next = L; L = s;
23 }
24 }

5.顺序表中有n个不同整数(下标1~n),设计算法把所有奇数移动到偶数前面(时,空都最少)

 1 void Move( ElemType A[], int n )
2 {
3 int low = 1, high = n;
4 while ( low < high )
5 {
6 while ( low < high&&A[low] % 2 ) low++;
7 while ( low < high && A[high] % 2 == 0 ) high--;
8 if ( low < high )
9 {
10 swap( A[low], A[high] );
11 low++; high--;
12 }
13 }
14 }

6.在顺序表中找出第k小的元素(时空最少)

 1 // 思想:划分
2 int Partition( ElemType R[], int low, int high )
3 {
4 int pivot = R[low];
5 while ( low < high )
6 {
7 while ( low < high && R[high].key >= pivot.key ) high--;
8 R[low] = R[high];
9 while ( low < high&& R[low].key <= pivot.key ) low++;
10 R[high] = R[low];
11 }
12 R[low] = pivot;
13 return low;
14 }
15
16 ElemType Kth_elem( ElemType R[], int low, int high, int k )
17 {
18 int pivotpos = Partition( R, low, high );
19 if ( pivotpos == k ) return R[pivotpos];
20 else if ( pivotpos > k ) return Kth_elem( R, low, pivotpos - 1, k );
21 else return Kth_elem( R, pivotpos + 1, high, k );
22 }

7.n个正整数构成的集合A,将其划分为两个不相交的子集$A1,A2$,元素个数分别是n1和n2.A1和A2中元素之和分别为S1和S2.设计一个时空高效算法,使|n1-n2|最小且|s1-s1|最大.(下标从1开始)

 1 int Partition( ElemType R[], int low, int high )
2 {
3 int pivot = R[low];
4 while ( low < high )
5 {
6 while ( low < high && R[high].key >= pivot.key ) high--;
7 R[low] = R[high];
8 while ( low < high&& R[low].key <= pivot.key ) low++;
9 R[high] = R[low];
10 }
11 R[low] = pivot;
12 return low;
13 }
14
15 int SetPartition( ElemType R[], int n, int low, int high )
16 {
17 int k = n / 2, s1, s2, i;
18 int pivotpos = Partition( R, low, high );
19 if ( pivotpos == k )
20 {
21 s1 = s2 = 0;
22 for ( i = 1; i <= k; i++ ) s1 += R[i];
23 for ( j = k + 1; j <= n; j++ ) s2 += R[j];
24 return s2 - s1;
25 }
26 else if ( pivotpos > k )
27 return SetPartition( R, n, low, pivotpos - 1 );
28 else return SetPartition( R, n, pivotpos + 1, high );
29 }

[Algorithm]排序的更多相关文章

  1. 30.algorithm排序小结

    如果容器中是类,如果要调用sort则需要重载操作符 "<" 包含头文件 #define _CRT_SECURE_NO_WARNINGS #include <vector ...

  2. <Data Structure and Algorithm>排序算法

    排序稳定:如果两个数相同,对他们进行的排序结果为他们的相对顺序不变.例如A={1,2,1,2,1}这里排序之后是A = {1,1,1,2,2} 稳定就是排序后第一个1就是排序前的第一个1,第二个1就是 ...

  3. CCF真题之数字排序

    201503-2 问题描述 给定n个整数,请统计出每个整数出现的次数,按出现次数从多到少的顺序输出. 输入格式 输入的第一行包含一个整数n,表示给定数字的个数. 第二行包含n个整数,相邻的整数之间用一 ...

  4. 过河(DP)

    问题描述] 在河上有一座独木桥,一只青蛙想沿着独木桥从河的一侧跳到另一侧.在桥上有一些石子,青蛙很讨厌踩在这些石子上.由于桥的长度和青蛙一次跳过的距离都是正整数,我们可以把独木桥上青蛙可能到达的点看成 ...

  5. algorithm -- 选择排序

    选择排序是<导论>第一章课后习题,仿照插入排序,再次运用循环不变式来证明下算法的正确性,C++ 源码: // 交换函数 void swap( int& a, int& b ...

  6. 谷歌的网页排序算法(PageRank Algorithm)

    本文将介绍谷歌的网页排序算法(PageRank Algorithm),以及它如何从250亿份网页中捞到与你的搜索条件匹配的结果.它的匹配效果如此之好,以至于“谷歌”(google)今天已经成为一个被广 ...

  7. 普林斯顿大学算法课 Algorithm Part I Week 3 排序算法复杂度 Sorting Complexity

    计算复杂度(Computational complexity):用于研究解决特定问题X的算法效率的框架 计算模型(Model of computation):可允许的操作(Allowable oper ...

  8. 排序算法 (sorting algorithm)之 冒泡排序(bubble sort)

    http://www.algolist.net/Algorithms/ https://docs.oracle.com/javase/tutorial/collections/algorithms/ ...

  9. <algorithm>里的sort函数对结构体排序

    题目描述 每天第一个到机房的人要把门打开,最后一个离开的人要把门关好.现有一堆杂乱的机房签到.签离记录,请根据记录找出当天开门和关门的人. 输入描述: 每天的记录在第一行给出记录的条目数M (M &g ...

随机推荐

  1. mysql特性及部署规范

    --分支版本,mysql对cpu,内存,io子系统资源利用特点--oracle mysql,mariadb,percona server--部署规范建议,系统安装,mysql安装,其他规范互联网业务为 ...

  2. Dynamics CRM 2011 FetchXml QueryExpression LINQ

    Dynamics CRM 2011支持三种查询语句 FetchXml QueryExpression LINQ 查询 功能 保存 FetchXml 支持QueryExpression的所有功能,额外支 ...

  3. 使用模板创建第一个Web API项目

    软件环境 vs 2015 update3 本节将通过例子讲述创建Web API 项目的方法 第一步,打开vs ,依次通过[文件]菜单,[新建][项目]命令,大致步骤如下图 :   第2步,在弹出对话框 ...

  4. 利用JS 在网页上获取并显示当前日期 星期

    下边的HTML代码,可以取出日期与星期 <html><body><h1><script language=JavaScript>var d, s = & ...

  5. MVC原理图解

    注解: 视图中通过Action方法向控制器请求数据 控制器通过view()方法向视图呈现数据

  6. 14-EasyNetQ之用Future Publish发布预定中事件

    很多商业流程需要事件在未来的时间按照预定时间发布.例如,在初次与客户接触后,可以在未来某个时间去电话回访客户.EasyNetQ可以用它的Future Publish功能帮你实现这个功能.举例:这里我们 ...

  7. 转-使用wifi调试程序

    转自:http://www.cnblogs.com/sunzhenxing19860608/archive/2011/07/14/2106492.html 数据线丢了,不想花钱去买,在网上看了看,an ...

  8. Python代码注释

    1.单行注释使用# # Code 2.多行注释,成对使用'''或""",三个单撇号或三个双引号 “”” Code “”” 3.多行快捷注释 1).增加注释 选中待注释的多 ...

  9. 屌爆的xamarin,一人单挑google/apple/windows

    一个IDE就把3大手机平台全包了: android:自带模拟器xamarin player,速度堪比genymotion. ios:需要一台mac机辅助,一旦配好后可全程脱离,连ios模拟器都给镜像到 ...

  10. python文件处理os模块

    一.os模块概述 Python os模块包含普遍的操作系统功能.如果你希望你的程序能够与平台无关的话,这个模块是尤为重要的.(一语中的) 二.常用方法 1.os.name 输出字符串指示正在使用的平台 ...