常用排序算法
来源:互联网 发布:安卓软件 知乎 编辑:程序博客网 时间:2024/06/06 08:25
常用的排序算法的时间复杂度和空间复杂度
排序法
最差时间分析平均时间复杂度稳定度空间复杂度冒泡排序O(n2)O(n2)稳定O(1)快速排序O(n2)O(n*log2n)不稳定O(log2n)~O(n)选择排序O(n2)O(n2)稳定O(1)二叉树排序O(n2)O(n*log2n)不一顶O(n)插入排序
O(n2)O(n2)稳定O(1)堆排序O(n*log2n)O(n*log2n)不稳定O(1)希尔排序OO不稳定O(1)以上都是常用的基于比较排序方法,时间复杂度的下限是O(n*logn),可以用决策树证明。
【1】选择排序,插入排序,冒泡排序
三种比较简单,而且复杂度都是O(n^2) 的方法
1 //选择排序
2 template <class T>
3 void SelectSort(T A[], int n)
4 {
5 int small;
6 for (int i=0; i<n-1; i++) { //执行n-1趟
7 small=i; //先假定待排序序列中第一个元素为最小
8 for (int j=i+1;j<n;j++) //每趟扫描待排序序列n-i-1次
9 if (A[j]<A[small]) small=j; //如果扫描到一个比最小值元素还小的,则记下其下标
10 Swap(A[i],A[small]); //最小元素与待排序序列中第一个元素交换
11 }
12 }
13 // ==========================================================
14 //直接插入排序
15 template <class T>
16 void InsertSort(T A[], int n)
17 {
18 for(int i=1; i<n; i++){ //执行n-1趟
19 int j=i;
20 T temp=A[i]; //待插入元素存入临时变量
21 while (j>0 && temp<A[j-1]){ //从后往前查找插入位置
22 A[j]=A[j-1]; j--; //A[j-1]元素后移,j指针前移
23 }
24 A[j]=temp; //待插入元素存入找到的插入位置
25 }
26 } // ==========================================================
27 //冒泡排序
28 template <class T>
29 void BubbleSort(T A[], int n)
30 {
31 int i,j,last;
32 i=n-1;
33 while (i>0){ //最多进行n-1趟
34 last=0; //进入循环就将last置成0
35 for (j=0; j<i; j++) //从上往下进行相邻元素的两两比较
36 if (A[j+1]<A[j]){
37 Swap(A[j],A[j+1]); //由于后者小,故交换
38 last=j; //有交换就将last置成j
39 }
40 i=last; //如果一趟排序中没有交换元素,则last为0
41 }
42 } // ==========================================================
2 template <class T>
3 void SelectSort(T A[], int n)
4 {
5 int small;
6 for (int i=0; i<n-1; i++) { //执行n-1趟
7 small=i; //先假定待排序序列中第一个元素为最小
8 for (int j=i+1;j<n;j++) //每趟扫描待排序序列n-i-1次
9 if (A[j]<A[small]) small=j; //如果扫描到一个比最小值元素还小的,则记下其下标
10 Swap(A[i],A[small]); //最小元素与待排序序列中第一个元素交换
11 }
12 }
13 // ==========================================================
14 //直接插入排序
15 template <class T>
16 void InsertSort(T A[], int n)
17 {
18 for(int i=1; i<n; i++){ //执行n-1趟
19 int j=i;
20 T temp=A[i]; //待插入元素存入临时变量
21 while (j>0 && temp<A[j-1]){ //从后往前查找插入位置
22 A[j]=A[j-1]; j--; //A[j-1]元素后移,j指针前移
23 }
24 A[j]=temp; //待插入元素存入找到的插入位置
25 }
26 } // ==========================================================
27 //冒泡排序
28 template <class T>
29 void BubbleSort(T A[], int n)
30 {
31 int i,j,last;
32 i=n-1;
33 while (i>0){ //最多进行n-1趟
34 last=0; //进入循环就将last置成0
35 for (j=0; j<i; j++) //从上往下进行相邻元素的两两比较
36 if (A[j+1]<A[j]){
37 Swap(A[j],A[j+1]); //由于后者小,故交换
38 last=j; //有交换就将last置成j
39 }
40 i=last; //如果一趟排序中没有交换元素,则last为0
41 }
42 } // ==========================================================
【2】快排
1 template< class T>
2 void QuickSort(T A[],int low,int high)
3 {
4 if (low >= high) return;
5
6 //划分过程:取一个基准值,将数组分成两段
7 int mid = (low+high)/2;
8 int pivot = A[mid];
9 swap(A[low],A[mid]);
10
11 int pl = low +1, pr = high;
12 while(pl < pr) {
13 while (A[pl] <= pivot) pl++;
14 while (A[pr] > pivot) pr--;
15
16 if(pl < pr) swap(A[pl],A[pr]);
17 }
18 A[low] = A[pr];
19 A[pr] = pivot;
20
21 //递归过程:对两段分别进行快排
22 QuickSort(A,low,pr-1);
23 QuickSort(A,pr+1,high);
24 }
2 void QuickSort(T A[],int low,int high)
3 {
4 if (low >= high) return;
5
6 //划分过程:取一个基准值,将数组分成两段
7 int mid = (low+high)/2;
8 int pivot = A[mid];
9 swap(A[low],A[mid]);
10
11 int pl = low +1, pr = high;
12 while(pl < pr) {
13 while (A[pl] <= pivot) pl++;
14 while (A[pr] > pivot) pr--;
15
16 if(pl < pr) swap(A[pl],A[pr]);
17 }
18 A[low] = A[pr];
19 A[pr] = pivot;
20
21 //递归过程:对两段分别进行快排
22 QuickSort(A,low,pr-1);
23 QuickSort(A,pr+1,high);
24 }
简洁的Python版本
1 def qsort(L):
2 if not L: return []
3 return qsort([x for x in L[1:] if x< L[0]]) + L[0:1] + \
4 qsort([x for x in L[1:] if x>=L[0]])
2 if not L: return []
3 return qsort([x for x in L[1:] if x< L[0]]) + L[0:1] + \
4 qsort([x for x in L[1:] if x>=L[0]])
【3】归并排序
1 template <class T> 2 void Merge(T A[],int i1,int j1,int i2,int j2) 3 { 4 // i1,j1是子序列1的下、上界,i1,j2是子序列2的下、上界 5 T *Temp=new T[j2-i1+1]; //分配能存放两个子序列的临时数组 6 int i=i1,j=i2,k=0; //i,j是两个子序列的游动指针,k是Temp的游动指针 7 while (i<=j1&&j<=j2) //若两个子序列都不空,则循环 8 if (A[i]<=A[j]) Temp[k++]=A[i++]; //将A[i]和A[j]中较小的存入Temp[k] 9 else Temp[k++]=A[j++];10 while (i<=j1) Temp[k++]=A[i++]; //若第一个子序列中还有剩余的就存入Temp11 while (j<=j2) Temp[k++]=A[j++]; //若第二个子序列中还有剩余的就存入Temp12 for (i=0; i<k; i++) A[i1++]=Temp[i]; //将临时数组中的元素倒回A13 delete [] Temp;14 }15 16 template <class T>17 void MergeSort(T A[], int n)18 {19 int i1,j1,i2,j2; //i1,j1是子序列1的下、上界,i2,j2是子序列2的下、上界20 int size=1; //子序列中元素个数,初始化为1。21 while (size<n) {22 i1=0;23 while (i1+size<n) { //若i1+size<n,则说明存在两个子序列,需再两两合并24 i2=i1+size; //确定子序列2的下界25 j1=i2-1; //确定子序列1的上界26 if (i2+size-1>n-1)27 j2=n-1; //若第2个子序列中不足size个元素,则置子序列2的上界j2=n-128 else 29 j2=i2+size-1; //否则有size个,置j2=i2+size-130 Merge(A,i1,j1,i2,j2); //合并相邻两个子序列31 i1=j2+1; //确定下一次合并第一个子序列的下界32 }33 size*=2; //元素个数扩大一倍34 }35 }
【堆排序】
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
# heapSort.py
import
random
def
buildHeap(li):
for
i
in
xrange
(
len
(li)
/
2
-
1
,
-
1
,
-
1
):
ajustHeap(li,i,
len
(li))
def
ajustHeap(li,n,end):
if
2
*
n
+
1
< end
and
li[n] < li[
2
*
n
+
1
] :
li[n],li[
2
*
n
+
1
]
=
li[
2
*
n
+
1
],li[n]
ajustHeap(li,
2
*
n
+
1
,end)
if
2
*
n
+
2
< end
and
li[n] < li[
2
*
n
+
2
] :
li[n],li[
2
*
n
+
2
]
=
li[
2
*
n
+
2
],li[n]
ajustHeap(li,
2
*
n
+
2
,end)
def
heapSort(li):
buildHeap(li)
for
i
in
xrange
(
len
(li)
-
1
,
0
,
-
1
):
li[i],li[
0
]
=
li[
0
],li[i]
ajustHeap(li,
0
, i)
return
li
if
__name__
=
=
'__main__'
:
a
=
[random.randint(
1
,
100
)
for
i
in
range
(
20
)]
print
heapSort(a)
0 0
- 常用排序算法--冒泡排序
- 常用排序算法--插入排序
- 常用排序算法--希尔排序
- 常用排序算法--堆排序
- 常用排序算法--归并排序
- 常用排序算法--快速排序
- 常用排序算法--冒泡排序
- 常用排序算法--快速排序
- 常用排序算法-快速排序
- 常用排序算法-冒泡排序
- 常用排序算法-归并排序
- 常用排序算法-希尔排序
- 常用排序算法-冒泡排序
- C++常用排序算法
- C++常用排序算法
- 常用排序算法
- 常用排序算法
- 常用的排序算法
- C++中的explicit关键字
- OpenCV图像处理车牌检测与定位应用
- JAVA多个文件压缩
- 安装内核文档
- Android App接入微信开放平台注意事项
- 常用排序算法
- 【数据结构】二叉树的遍历
- Telnet英文全称
- 第十周项目四(1)——大奖赛计分
- 解决Qt5屏幕翻转问题
- 猜数字游戏
- 数据结构实验之栈二:一般算术表达式转换成后缀式
- 理解C++复杂声明
- c#试验九4678合集