1、前提
void X_Sort ( ElementType A[], int N )//A是一个数组,N是数组的个数。
-
大多数情况下,为简单起见,讨论从
小大的整数
排序 -
N是
正
整数 -
只讨论基于
比较
的排序(> = < 有定义) -
只讨论
内部
排序(这里只讨论内存可以装的下的数据量,如果内存装不下,有些数据在磁盘中,则更复杂。) -
稳定
性:任意两个相等的数据,排序前后的相对位置不发生改变 - 没有一种排序是任何情况下都表现最好的
2、冒泡排序
#include<iostream>
using namespace std;
typedef int ElementType;
void Bubble_Sort(ElementType A[], int n)
{
for (int i = n - 1; i >= 0; i--) //一趟冒泡
{
int flag = 0;
for (int j = 0; j < i; j++)
{
if (A[j] > A[j + 1])
{
swap(A[j + 1], A[j]);
flag = 1; //有元素交换时标识发生变化
}
}
if (flag == 0)break; //全程无交换,已经排好序
}
}
int main()
{
int a[] = {4,6,1,8,9,3,7,0};
int len = sizeof(a) / sizeof(a[0]);
Bubble_Sort(a,len);
for (int i = 0; i < len; i++)
cout << a[i] << " ";
cout << endl;
}
时间复杂度:
最好情况(已经有序,遍历一遍):顺序T = O( N )
最坏情况(逆序):逆序T = O( N2 )
3、插入排序
初始状态下只有一个元素,每插入一个元素,将插入的元素与现有的元素从尾到头比较,将比该元素大的元素依次向后移动,并将该元素插入指定的位置。
#include<iostream>
using namespace std;
typedef int ElementType;
void Insertion_Sort(ElementType A[],int n)
{
for (int i = 1; i < n; i++)
{
int tmp = A[i];
int j;
for (j = i; j >0 && A[j-1]>tmp; j--)
A[j] = A[j - 1];
A[j] = tmp;
}
}
int main()
{
int a[] = {4,6,1,8,9,3,7,0};
int len = sizeof(a) / sizeof(a[0]);
Insertion_Sort(a,len);
for (int i = 0; i < len; i++)
cout << a[i] << " ";
cout << endl;
}
最好情况:顺序T = O( N )
最坏情况:逆序T = O( N2 )
4、时间复杂度下界
-
对于下标i<j,如果A[i]>A[j],则称(i,j)是一对
逆序对(inversion)
-
交换2个相邻元素正好消去1个逆序对!
-
插入排序:T(N, I) = O( N+I ),I为逆序对数量
—如果序列基本有序
,则插入排序简单且高效 -
定理:任意N个不同元素组成的序列平均具有
N(N-1)/4
个逆序对。 -
定理:任何仅以交换相邻两元素来排序的算法,其平均时间复杂度为Ω(N2)
-
这意味着:要提高算法效率,我们必须
- 每次消去不止1个逆序对!
- 每次交换相隔较远的2个元素!