簡單排序——氣泡排序,插入排序,逆序對
阿新 • • 發佈:2018-11-22
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個元素!