zoukankan      html  css  js  c++  java
  • C++/C实现各种排序算法(持续更新)--冒泡排序,选择排序,归并排序

    2018 3 17

    今日总结一下C++中的排序算法:

    1冒泡排序

    它重复地走访过要排序的数列,一次比较两个元素,如果他们的顺序错误就把他们交换过来。走访数列的工作是重复地进行直到没有再需要交换,也就是说该数列已经排序完成。
    这个算法的名字由来是因为越大的元素会经由交换慢慢“浮”到数列的顶端。(来源百度百科)
    C++实现:
     1 #include "stdafx.h"
     2 #include <iostream>
     3 using namespace std;
     4 int ha[] = {1,7,4,2,6,5,8,3};
     5 
     6 template <typename T>
     7 void Bubble_Sort(T *pDst,const int nLen)
     8 {
     9     int cycle;
    10     //外层循环,控制遍历的次数(N-1(N为待排序的数组大小))
    11     for (cycle=0; cycle<(nLen-1) ; cycle++)
    12     {
    13         //内层循环,每次遍历到前一次最大值之前为止
    14         for (int i=0; i < (nLen - 1-cycle); i++)
    15         {
    16             if (pDst[i] > pDst[i + 1])
    17             {
    18                 T tTemp = pDst[i];
    19                 pDst[i] = pDst[i + 1];
    20                 pDst[i + 1] = tTemp;
    21             }
    22         }
    23     }
    24 }
    25 
    26 int main()
    27 {
    28     //冒泡
    29     
    30     Bubble_Sort<int>(ha,8);
    31     for (int i = 0; i < 8; i++)
    32     {
    33         printf("%d-",ha[i]);
    34      getchar();
    35     }
    36   return 0;
    37 }

     2 选择排序

      工作原理是每一次从待排序的数据元素中选出最小(或最大)的一个元素,存放在序列的起始位置,直到全部待排序的数据元素排完。 选择排序是不稳定的排序方法(比如序列[5, 5, 3]第一次就将第一个[5]与[3]交换,导致第一个5挪动到第二个5后面)。

    C++实现:

     1 //升序
     2 template <typename T>
     3 void Select_Sort(T *pDst, const int nLen)
     4 {
     5     T tTemp;
     6     
     7 //遍历nLen次,每次找到最小的值,交换
     8     for (int i = 0; i < nLen; i++)
     9     {
    10         for (int j = i; j < nLen; j++)
    11         {
    12             if (pDst[j] <pDst[i])
    13             {
    14                  tTemp=pDst[i];
    15                  pDst[i] = pDst[j];
    16                  pDst[j] = tTemp;
    17 
    18             }
    19             else
    20                 continue;
    21         }
    22     }
    23 
    24 }
    25 int main()
    26 {
    27     //冒泡
    28     
    29     //Bubble_Sort<int>(ha,8);
    30     Select_Sort<int>(ha,8);
    31     for (int i = 0; i < 8; i++)
    32     {
    33         printf("%d-",ha[i]);
    34     }
    35     return 0;
    36 }

     3 归并排序

    将两个有序(同一种序)的数组合并为一个有序数组

    (1)二路归并。二路归并的最好情况时间复杂度为:O(Min{sizof(a),sizeof(b)})

     1 // ConsoleApplication4.cpp : 定义控制台应用程序的入口点。
     2 //
     3 
     4 #include "stdafx.h"
     5 #include "atlstr.h"
     6 #include <iostream>
     7 #include <vector>
     8 using namespace std;
     9 //////
    10 //二路归并排序。将两个表,合并成一个表的过程称为二路归并
    11 //如:对两个y有序的数组 进行二路归并
    12 const int a[] = {1,2,3};
    13 const int b[] = {1,2,3,4,5,6,7};
    14 
    15 int* Merger_Sort(const int *a,const int *b,int nLen1,int nLen2)
    16 {
    17     int *pDst = new int[nLen1+nLen2];
    18     int k = 0;
    19     int i = 0;
    20     int j = 0;
    21     while (i < nLen1&&j < nLen2)
    22     {
    23         if (a[i] <= b[j])
    24         {
    25             pDst[k] = a[i];
    26             i++;
    27         }
    28         else
    29         {
    30             pDst[k] = b[j];
    31             j++;
    32         }
    33         k++;
    34     }
    35     while (i < nLen1)
    36     {
    37         pDst[k] = a[i];
    38         i++;
    39         k++;
    40     }
    41     while (j < nLen2)
    42     {
    43         pDst[k] = b[j];
    44         j++;
    45         k++;
    46     }
    47     return pDst;
    48 }
    49 
    50 int main()
    51 {
    52     int *p = NULL;
    53     p = Merger_Sort(a,b,3,7);
    54     for (int i = 0; i <10; i++)
    55     {
    56         cout << p[i];
    57     }
    58     delete[] p;
    59 
    60     getchar();
    61     return 0;
    62 }
    View Code

     (2) 普通归并排序 ;将二路归并扩展到一般情况,将一个序列分为N组,每组都是一个有序的数组,对两两之间进行归并

      1 // ConsoleApplication7.cpp : 定义控制台应用程序的入口点。
      2 //
      3 
      4 #include "stdafx.h"
      5 //二路归并的前提是两个结构的元素已经是有序的(同样的顺序)
      6 int a[] = { 1,3,4,5,6 };
      7 int b[] = { 2,3,8,9,10,18 };
      8 void Two_MergeSort(int *pA1, int *pA2, int nA1Len, int nA2Len, int *pOut)
      9 {
     10     int i = 0; int j = 0;
     11     int nDstPos = 0;
     12     while (i < nA1Len&&j < nA2Len)
     13     {
     14         if (pA1[i] > pA2[j])
     15         {
     16             //找到同一顺序的元素中较小的放入pOut中
     17             pOut[nDstPos++] = pA2[j++];
     18         }
     19         else
     20             pOut[nDstPos++] = pA1[i++];
     21     }
     22     while (i < nA1Len)
     23     {
     24         pOut[nDstPos++] = pA1[i++];
     25     }
     26     while (j<nA2Len)
     27     {
     28         pOut[nDstPos++] = pA2[j++];
     29     }
     30 }
     31 
     32 //输入的Pos指的是坐标,可以比较一下与二路归并的区别
     33 void General_Two_MergeSort(int *pA, int nStartPos, int nMidPos, int nEndPos, int *pOut)
     34 {
     35     int i = nStartPos;
     36     int j = nMidPos + 1;
     37     int k = nEndPos;
     38     int nDstPos = nStartPos;
     39     printf("对区间[%d,%d]和区间[%d,%d]进行排序
    ", nStartPos, nMidPos, nMidPos + 1, nEndPos);
     40     while (i <= nMidPos&&j <= nEndPos)
     41     {
     42         if (pA[i] > pA[j])
     43         {
     44             pOut[nDstPos++] = pA[j++];
     45         }
     46         else
     47         {
     48             pOut[nDstPos++] = pA[i++];
     49         }
     50     }
     51     while (i <= nMidPos)
     52     {
     53         pOut[nDstPos++] = pA[i++];
     54     }
     55     while (j <= nEndPos)
     56     {
     57         pOut[nDstPos++] = pA[j++];
     58     }
     59     for (int n = nStartPos; n <= nEndPos; n++)
     60     {
     61         pA[n] = pOut[n];
     62     }
     63     static int nCount = 0;
     64     printf("第%d次调用
    ",++nCount);
     65     //printf("参数分别是:StartPos:%d,MidPos:%d,EndPos:%d
    ", nStartPos,nMidPos,nEndPos);
     66     //printf("当前排序的成员有%d个,分别是:
    ",nEndPos-nStartPos+1);
     67     for (int n = nStartPos; n <= nEndPos; n++)
     68     {
     69         printf("%d ",pOut[n]);
     70     }
     71     printf("
    ");
     72     printf("
    ");
     73     printf("
    ");
     74 }
     75 
     76 
     77 //推广到更普通的归并排序
     78 //归并排序的核心是将一串数字中的数字分成两组,先对分成的每一组进行深度归并,最后再对初始的两组进行归并
     79 void Merge_Sort(int *pA, int nLow, int nHigh, int *pOut)
     80 {
     81     if (nLow < nHigh)
     82     {
     83         int nMid = (nLow + nHigh) / 2;
     84         //左边递归,直到只含有一个元素
     85         Merge_Sort(pA, nLow, nMid, pOut);
     86         //右边递归,直到只含有一个元素
     87         Merge_Sort(pA, nMid + 1, nHigh, pOut);
     88         //对两个元素进行递归排序
     89         General_Two_MergeSort(pA, nLow, nMid, nHigh, pOut);
     90     }
     91 
     92 
     93 }
     94 
     95 
     96 int main()
     97 {
     98     int c[7] = { 0 };
     99     int Dst[] = { 1,3,5,7,9,11,13 };
    100     //Two_MergeSort(a,b,5,6,c);
    101     Merge_Sort(Dst, 0, 6, c);
    102     int i = 0;
    103     while (i < 7)
    104     {
    105         printf("%d ", c[i++]);
    106     }
    107 
    108 
    109     getchar();
    110     return 0;
    111 }
    View Code
    除特殊说明外,其余所有文章均属原创。未经允许,请勿进行转载或者其他操作 有问题欢迎留言交流
  • 相关阅读:
    virturalbox安装CentOS桥接网卡
    解决:Error:java: 无效的源发行版: 12
    maven下载失败,镜像配置,idea的maven下载配置
    linux压缩和解压缩命令
    Unable to allocate 130176KB bitmaps for parallel garbage collection for the requested 4165632KB heap.
    Docker,Linux,Kubernetes,postgres常用的命令行(持续更新)
    dropwizard问题记录1:如何进行mvn package打包,如何在项目目录下运行
    线程的并发工具类
    学信网改绑手机号码,但是忘记了老号码怎么办?利用node.js + puppeteer 跑脚本实现改绑手机号
    javascript事件循环与js执行机制
  • 原文地址:https://www.cnblogs.com/LiuBingBlogs/p/8591028.html
Copyright © 2011-2022 走看看