一.排序算法


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. Secure CRT修改文件夹的颜色

    secureCRT有一个很大的问题是,如果设置Emulation Terminal 为Linux模式,则ls的时候,目录的蓝色跟背景的黑色非常接近,很难看清楚,修改办法 option->Glob ...

  2. 【DevExpress】1、SearchLookUpEdit详解

    一.属性的基本介绍: 绑定数据源: lookUpEdit.Properties.ValueMember = 实际要用的字段;   //相当于Editvalue lookUpEdit.Propertie ...

  3. 8.solr学习速成之FacetPivot

    什么是Facet.pivot  Facet.pivot就是按照多个维度进行分组查询,是Facet的加强,在实际运用中经常用到,一个典型的例子就是商品目录树 NamedList解释: NamedList ...

  4. PCA主成分分析 ICA独立成分分析 LDA线性判别分析 SVD性质

    机器学习(8) -- 降维 核心思想:将数据沿方差最大方向投影,数据更易于区分 简而言之:PCA算法其表现形式是降维,同时也是一种特征融合算法. 对于正交属性空间(对2维空间即为直角坐标系)中的样本点 ...

  5. pandas分组和聚合

    Pandas分组与聚合 分组 (groupby) 对数据集进行分组,然后对每组进行统计分析 SQL能够对数据进行过滤,分组聚合 pandas能利用groupby进行更加复杂的分组运算 分组运算过程:s ...

  6. VMWARE三种网络配置

    由于linux目前很热门,越来越多的人在学习linux,但是买一台服务放家里来学习,实在是很浪费.那么如何解决这个问题?虚拟机软件是很好的选择,常用的虚拟机软件有vmware workstations ...

  7. JavaScript 18岁生日快乐

    12月4日是JS的18岁生日,18年前这个日子JavaScript由Netscape和Sun联合宣布推出.那个星期,Ruby也将推出其第一个版本. 今天Netscape和Sun都已经不在了,但是JS还 ...

  8. AngularJS学习(二)——Angular应用的解析

    本节描述AngularJS应用程序的三个组成部分,并解释它们如何映射到模型-视图-控制器设计模式 模板(Template) 模板是您用HTML和CSS编写的文件,展现应用的视图.您可给HTML添加新的 ...

  9. SkyBox

    [SkyBox] Skyboxes 本质是一个Material,这个Meterial的shader必须设置为ShaderFX/Skybox. SkyBox可以被绑定到摄像机或设置一个全局的SkyBox ...

  10. Linux 安装(重装)mysql

    1 新建存放mysql相关文件的文件夹 mkdir -p /export/servers/mysql //存放mysql相关的几个rpm文件 2 查看原有mysql 并卸载 rpm -qa | gre ...