排序 之 快排、归并、插入 - <时间复杂度>----掌握思想和过程

 

  俗话说天下武功无坚不破,唯快不破。对于算法当然也是要使用时间最短、占用空间最小的算法来实现了。

  注意:我代码里面打的备注仅供参考,建议不要背模板(因为没有固定的模板),可以写一个数列按着代码跑两圈或者把代码改一下输出每次排序后的结果。

 总之,师傅领进门,修行在个人。奋斗把!骚年!

 

冒泡排序、选择排序:(不稳定,时间复杂度 O(n^2))

 1 #include "cstdio"
 2 #include "iostream"
 3 using namespace std;
 4 
 5 void bubble_sort (int *a, int n) {
 6     int t;
 7     for (int i = 0; i < n - 1; ++i) {
 8         for (int j = 0; j < n - i - 1; ++j) {
 9             if (a[j] > a[j + 1]) {
10                 t = a[j];
11                 a[j] = a[j + 1];
12                 a[j + 1] = t;
13             }
14         }
15     }
16 }
17 
18 int main () {
19     int n, a[999];
20     cin >> n;
21     for (int i = 0; i < n; ++i)
22         cin >> a[i];
23     bubble_sort (a, n);
24     for (int i = 0; i < n; ++i)
25         cout << a[i] << " ";
26     cout << endl;
27     return 0;
28 }
bubble sort
 1 #include "cstdio"
 2 #include "iostream"
 3 using namespace std;
 4 
 5 void selection_sort (int *a, int n) {
 6     int t;
 7     for (int i = 0; i < n; ++i) {
 8         for (int j = i; j < n; ++j) {
 9             if (a[i] > a[j]) {
10                 t = a[j];
11                 a[j] = a[i];
12                 a[i] = t;
13             }
14         }
15     }
16 }
17 
18 int main () {
19     int n, a[999];
20     cin >> n;
21     for (int i = 0; i < n; ++i)
22         cin >> a[i];
23     selection_sort (a, n);
24     for (int i = 0; i < n; ++i)
25         cout << a[i] << " ";
26     cout << endl;
27     return 0;
28 }
selection sort

  如果说冒泡和选择排序都没有弄明白的话,那你对于排序可以只记个C++STL中的sort函数和头文件就行了。

  #include <algorithm>

  sort (要排序数组的首地址, 要排序一共的个数);

  //  默认是升序,如果想要降序的话,写一个compare函数   bool compare(int a, int b) { return a > b;}

  // a < b;升序   a > b;降序

 1 #include <iostream>
 2 #include <algorithm>
 3 using namespace std;
 4 
 5 int cmp(int a, int b) {
 6     return a > b;
 7 }
 8 
 9 int main () {
10     int a[] = {1, 2, 3, 2, 1};
11     // sort (a, a+5, [](int a, int b){return a > b;});
12     // 这是闭包的格式, 适合函数体较短的时候使用。
13     
14     sort (a, a+5, cmp);
15     
16     for (int i = 0; i < 5; ++i) {
17         cout << a[i] << " ";
18     }
19     cout << endl;
20     return 0;
21 }
C++ STL sort

   sort排结构体(可以使用pair更方便)

 1 #include <iostream>
 2 #include <algorithm>
 3 #include <cstdio>
 4 using namespace std;
 5 
 6 struct node {
 7     int x, y;
 8 }t[10];
 9 
10 bool cmp (const node a, const node b) {
11     if (a.x > b.x) {
12         return 1;
13     } else if (a.x==b.x && a.y<b.y) {
14         return 1;
15     } else {
16         return 0;
17     }
18 }
19 
20 int main () {
21     t[0].x = 1;
22     t[0].y = 2;
23     
24     t[1].x = 1;
25     t[1].y = 1;
26     
27     t[2].x = 1;
28     t[2].y = 3;
29     
30     t[3].x = 2;
31     t[3].y = 3;
32     
33     t[4].x = 3;
34     t[4].y = 2;
35     
36     t[5].x = 2;
37     t[5].y = 1;
38     
39     sort (t, t+5, cmp);
40     for (int i = 0; i < 6; ++i) {
41         cout << t[i].x <<  ' ' << t[i].y << endl;
42     }
43     return 0;
44 }
45 
46 
47 
48 
49 /*
50 3 2
51 2 3
52 1 1
53 1 2
54 1 3
55 2 1
56 */
sort排结构体数组

 

基础快排1----选择左右两边为基准排序:(不稳定,时间复杂度 最理想 O(nlogn) 最差时间O(n^2))

 1 #include <bits/stdc++.h>//万能头文件
 2 using namespace std;
 3 
 4 void quick_sort (int a[], int l, int r) {
 5     if (l >= r) return ;
 6     int i = l, j = r;
 7     int key = a[l];
 8     while (i < j) {    ///这里不能带等号,,死循环
 9         while (i < j && a[j] >= key) {//<=是找有相同数字的时候
10             j --;    //选的左边作为key,所以就从右边开始.
11         }
12         a[i] = a[j];    //找到一个该交换的时候退出交换。
13         while (i < j && a[i] <= key) { //<=是找有相同数字的时候
14             i ++;
15         }
16         a[j] = a[i];    //同上
17     }
18     a[i] = key;
19     quick_sort (a, l, i - 1);////应该可以交换位置,因为这两个是等效的,
20     quick_sort (a, i + 1, r);////就是排序上次key两的的值
21 }
22 
23 int main () {
24     int n;
25     int a[999];
26     scanf ("%d", &n);
27     for (int i = 0; i < n; ++i)
28     {
29         scanf ("%d", &a[i]);
30     }
31     quick_sort (a, 0, n - 1);
32     for (int i = 0; i < n; ++i)
33     {
34         printf("%d ", a[i]);
35     }
36     printf("\n");
37     return 0;
38 }
Quick_sort_by_left
 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 
 4 void quick_sort (int a[], int l, int r) {
 5     if (l >= r) return ;
 6     int i = l, j = r;
 7     int key = a[r];
 8     while (i < j) {    ///这里不能带等号,,死循环
 9         while (i < j && a[i] <= key) {//<=是找有相同数字的时候
10             i ++;    //选的右边作为key,所以就从左边开始.
11         }
12         a[j] = a[i];    //找到一个该交换的时候退出交换。
13         while (i < j && a[j] >= key) { //<=是找有相同数字的时候
14             j --;
15         }
16         a[i] = a[j];    //同上
17     }
18     a[j] = key;//-----先替换的a[j],所以在这里补上.
19     quick_sort (a, l, i - 1);////可以交换位置,是等效的
20     quick_sort (a, i + 1, r);////就是排序上次key两的的值
21 }
22 
23 int main () {
24     int n;
25     int a[999];
26     scanf ("%d", &n);
27     for (int i = 0; i < n; ++i)
28     {
29         scanf ("%d", &a[i]);
30     }
31     quick_sort (a, 0, n - 1);
32     for (int i = 0; i < n; ++i)
33     {
34         printf("%d ", a[i]);
35     }
36     printf("\n");
37     return 0;
38 }
Quick_sort_by_right

  注意:快排函数最后递归的时候可以按j也可以按i,因为最后满足 i == j; 理解代码里面等号的取舍!

 

基础快排2----选择任意数字为基准排序:(不稳定,时间复杂度 最理想 O(nlogn) 最差时间O(n^2))

 1 #include <cstdio>
 2 #include <iostream>
 3 using namespace std;
 4 
 5 void quick_sort (int *a, int l, int r) {
 6     int i = l, j = r, key = a[l + (r - l) / 2];
 7     //int key = a[r]; 
 8     //从数列里面任意找一个key就行
 9     int t;
10     while (i < j) {
11         while (i < r && a[i] < key)    i ++;
12         //不能写成a[i] <= key,会跳过一些数字,导致不能排序
13         while (j > l && a[j] > key)    j --;
14         //这两个while可以交换位置,以左右为基准的快排不能交换
15         if (i <= j) {
16             t = a[i];
17             a[i] = a[j];
18             a[j] = t;
19 
20             i ++;
21             j --;
22         }
23     }
24     if (i < r)    quick_sort (a, i, r);
25     if (j > l)    quick_sort (a, l, j);
26 }
27 
28 int main () {
29     int n;
30     int a[999];
31     cin >> n;
32     for (int i = 0; i < n; ++i)
33         cin >> a[i];
34     quick_sort (a, 0, n - 1);
35     for (int i = 0; i < n; ++i)
36         cout << a[i] << " ";
37     cout << endl;
38     return 0;
39 }
40 
41 Quick_sort_anyone
Quick_sort_by_anyone

   简述:快速排序是对冒泡排序的一种本质改进。它的基本思想是通过一趟扫描后,使得排序序列的长度能大幅度地减少。在冒泡排序中,一次扫描只能确保最大数值的数移到正确位置,而待排序序列的长度可能只减少1。快速排序通过一趟扫描,就能确保某个数(以它为基准点吧)的左边各数都比它小,右边各数都比它大。然后又用同样的方法处理它左右两边的数,直到基准点的左右只有一个元素为止。

***另外一种快排的写法(从蓝桥杯上学习到的,思想都是一样的,只是实现有点不一样)

 1 #include <stdio.h>
 2 
 3 void swap(int a[], int i, int j)
 4 {
 5     int t = a[i];
 6     a[i] = a[j];
 7     a[j] = t;
 8 }
 9 
10 int partition(int a[], int p, int r)
11 {
12     int i = p;
13     int j = r + 1;
14     int x = a[p];
15     while(1){
16         while(i<r && a[++i]<x);
17         while(a[--j]>x);
18         if(i>=j) break;
19         swap(a,i,j);
20     }
21     swap(a, p, j);
22     return j;
23 }
24 
25 void quicksort(int a[], int p, int r)
26 {
27     if(p<r){
28         int q = partition(a,p,r);
29         quicksort(a,p,q-1);
30         quicksort(a,q+1,r);
31     }
32 }
33     
34 int main()
35 {
36     int i;
37     int a[] = {5,13,6,24,2,8,19,27,6,12,1,17};
38     int N = 12;
39     
40     quicksort(a, 0, N-1);
41     
42     for(i=0; i<N; i++) printf("%d ", a[i]);
43     printf("\n");
44     
45     return 0;
46 }
蓝桥杯 

 

基础快排3----调用stdlib.h中的qsort函数。

  语法:

  #include <stdlib.h>

  void qsort( void *buf, size_t num, size_t size, int (*compare)(const void *, const void *) );

  buf: 要排序片段的首地址。

  num: 要排序片段的个数。

  size:要排序元素占的字节,可以使用sizeof来求。

  compare:如果函数compare 的第一个参数小于第二个参数,返回负值(升序);如果等于返回零值(不变);如果大于返回正值(降序)(函数参数必须为const void *类型)

 1 #include <stdio.h>
 2 #include <stdlib.h>
 3 
 4 int cmp(const void *a, const void *b) {
 5     return *(char*)a - *(char*)b;
 6     // 如果数组是int类型的话,这里的char就是用int
 7     // 下面对应sizeof(int).
 8 }
 9 
10 int main() {
11     char b[] = {"12321"};
12     qsort(b, 5, sizeof(char), cmp);
13     printf("%c", b[0]);
14     for(int i = 1; i < 5; i++)
15         printf(" %c", b[i]);
16     printf("\n");
17     return 0;
18 }
Qsort

 

归并排序:(稳定,时间复杂度 O(nlog n))

 1 #include <stdio.h>//归并排序
 2 #include <stdlib.h>
 3 void merge(int a[],int b[], int f, int mid, int e)
 4 {//合并两个数组
 5     int i = f, j = mid + 1, k = f;
 6     while(i <= mid && j <= e)//注意衔接
 7     {
 8         if(a[i] >= a[j])    //谁大就不把谁装到前面
 9             b[k++] = a[j++];
10         else
11             b[k++] = a[i++];
12     }
13     while(i <= mid)//前半个有剩余
14         b[k++] = a[i++];
15     while(j <= e)//后半个有剩余
16         b[k++] = a[j++];
17     for(i = f; i <= e; i++)    //最后再还给a
18         a[i] = b[i];
19 }
20 void mergesort(int a[], int b[], int f, int e)//内部使用递归
21 {
22     if(f < e)
23     {
24         int mid = (e + f) / 2;
25         mergesort(a, b, f, mid);    //拆分到很小很小
26         mergesort(a, b, mid + 1, e);
27         merge(a, b, f, mid, e);
28     }
29 }
30 int main(){
31     int n;
32     int a[999];
33     int i, b[999];
34     scanf ("%d", &n);
35     for (int i = 0; i < n; ++i)
36         scanf ("%d", &a[i]);
37     mergesort(a, b, 0, n - 1);
38     for(i = 0; i < n; i++)
39         printf("%d ", a[i]);
40     printf("\n");
41     return 0;
42 }
Order_by_merging

 简述:将数组拆分为两组,对于一个数组来说,两个数组要好排的多...依次类推,当分到只要一个元素的时候,我们就认为是有序的,然后再挨个合并相邻的数组。我们可以先递归分解,然后再归并排序。

 

插入排序:

 1 /*
 2  *   > File Name: test.cpp
 3  *   > Author: Ddlm2wxm
 4  *   > Mail: Ddlm2wxm@163.com 
 5  *   > Created Time: 2016年10月20日 星期四 07时35分53秒
 6  *********************************************************/
 7 
 8 #include <iostream>
 9 #include <cstdio>
10 using namespace std;
11 
12 void Insert_sort (int a[], int n) {
13     int i, j;
14     for (i = 1; i < n; ++i) {
15         int t = a[i];
16         for (j = i-1; j >= 0&&t<a[j]; --j)
17             a[j+1] = a[j];
18         a[j+1] = t;
19     }
20 }
21 
22 int main() {
23     int n;
24     int a[999];
25     cin >> n;
26     for (int i = 0;i < n; ++i) {
27         cin >> a[i];
28     }
29     Insert_sort (a, n);
30     for (int i =0;i < n; ++i) {
31         cout << a[i] << " ";
32     }
33     cout << endl;
34     return 0;
35 }
Insert_sort

简述:个人认为插入排序是最简单的,就是从第一个开始,认为第一个数是有序的,然后依次取后面的数字,通过遍历前面的排序好了的数组寻找取到元素的位置。

 

 欢迎码友评论,一起成长。

posted @ 2016-09-12 23:46  Codorld  阅读(504)  评论(0编辑  收藏  举报