zoukankan      html  css  js  c++  java
  • 快速排序,冒泡排序,选择排序比较

     快速排序,冒泡排序,选择排序是比较基础的排序方法,我通过随机生成一个大小1000的数组,然后使用内部类创建线程来比较耗费时间

       首先快速排序算法:
            快速排序算法其实也叫分治法, 其步骤大致可以分为这么几步:
      1. 先从数列中取出一个数作为基准数Num(取得好的话, 是可以减少步骤的)
      2. 分区, 将大于Num的数放在它的右边, 小于或等于它的数放在它的左边
      3. 再对左右区间重复前两操作, 直到各个区间只有一个数为止.

      这里是使用递归方式创建的快速排序

       

     1 public static void kspxSort(int[] a,int low, int hight) {
     2         int start=low;
     3         int end=hight;
     4         int key=a[low];
     5         while(end>start) {
     6             //从end开始和key比较
     7              while(end>start&&a[end]>=key) {
     8                  end--;
     9              }
    10             if(a[end]<=key) {
    11                 int temp = a[end];
    12                 a[end] = a[start];
    13                 a[start] = temp;                    
    14             }
    15              while(end>start&&a[start]<=key) {
    16                  start++;
    17                  
    18              }
    19             if(a[start]>=key) {
    20                 int temp = a[start];
    21                 a[start]=a[end];
    22                 a[end]=temp;
    23             }
    24             
    25             
    26         }
    27         
    28         //递归调用
    29          if(start>low) {kspxSort(a,low,start-1);}
    30          if(end<hight) {kspxSort(a,end+1,hight);}
    31         
    32     }

     然后是冒泡排序

        将要排序的一组数字进行遍历。
    第一次遍历,将相邻的两个数字进行比较,直到这组数字全部比较完成,如果前面比后面的数字大,则进行交换位置,此时可以将最大的数字筛选出来,放到最后的位置上。
    第二次遍历,将相邻的两个数字进行比较,直到这组数字全部比较完成,如果前面比后面的数字大,则进行交换位置,将这组数字里面第二大的数字筛选出来,放到倒数第二的位置上。
    依次进行遍历,交换位置,直到排序完成。

     1     public static void bubbleSort(int[] a) {
     2         int n = a.length;
     3         int temp;
     4         for(int i=0;i<n-1;i++) {
     5             
     6             for(int j=0;j<n-1-i;j++) {
     7                 
     8                 if(a[j]>a[j+1]) {
     9                     temp = a[j];
    10                     a[j] =a[j+1];
    11                     a[j+1] = temp;
    12                 }
    13             }
    14         }        
    15     }

    然后是选择排序

       将要排序的一组数字进行遍历。
    第一次遍历,将第一个位置上的数字与后面的数字进行比较,如果后面的数字比第一个位置上的元素小,则将两个数字的位置进行交换。
    第二次遍历,将第二个位置上的数字与后面的数字进行比较,如果后面的数字比第二个位置上的元素小,则将两个数字的位置进行交换。
    依次进行遍历、位置交换,直到这组数字排序完成。

     1 public static void selectSort(int[] a) {
     2          for(int i=0;i<a.length-1;i++){
     3 
     4                 //假设第一个数据是最小值
     5                 //记录最小值元素的下标
     6                 int min = i;
     7 
     8                 for(int j=i+1;j<a.length;j++){
     9 
    10                     if(a[min]>a[j]){
    11                         //给min重新赋值
    12                         min = j;
    13                     }
    14                 }
    15 
    16                 //交换位置
    17                 if(min != i){
    18                     int temp;
    19                     temp = a[i];
    20                     a[i] = a[min];
    21                     a[min] = temp;
    22                 }
    23 
    24             }
    25     }

    然后再main方法主线程中中创建一个随机数组,大小100000;读者可以创建更大以便获得更好的效果;

    1  int[] arry= new int[100000];    
    2         for(int i=0;i<100000;i++) {
    3             arry[i]= (int)(Math.random()*100000);
    4         }

         使用多线程调用

     1   new Thread() { // 1.继承Thread类
     2                 public void run() { // 2.重写run方法
     3                   long t1 = new Date().getTime();
     4                      kspxSort(arry, 0, arry.length-1);
     5                      long t2 = new Date().getTime();
     6                      System.out.println("快速排序消耗时间:"+(t2-t1));
     7                 }
     8             }.start(); // 4.开启线程
     9         new Thread() {
    10             public void run() {
    11                 long t1 = new Date().getTime();
    12                 bubbleSort(arry);
    13                      long t2 = new Date().getTime();
    14                      System.out.println("冒泡排序消耗时间:"+(t2-t1));
    15             }
    16         }.start();
    17         new Thread() {
    18             public void run() {
    19                  long t1 = new Date().getTime();
    20                  selectSort(arry);
    21                      long t2 = new Date().getTime();
    22                      System.out.println("选择排序消耗时间:"+(t2-t1));
    23             }
    24             
    25         }.start();

    结果如下:

    快速排序消耗时间:33
    选择排序消耗时间:2515
    冒泡排序消耗时间:4227

    相比较之下:快速排序最快,选择排序和冒泡排序相差不大,

    在算法中用 0()函数 表示算法的时间效率与算法所处理的数据元素个数n函数关系的最常用函数是0()函数。
      定义:
      一般情况下,算法中基本操作重复执行的次数是问题规模n的某个函数,用T(n)表示,若有某个辅助函数f(n),使得当n趋近于无穷大时,

    T(n)/f(n)的极限值为不等于零的常数,则称f(n)是T(n)的同数量级函数。记作T(n)=0(f(n)),称0(f(n)) 为算法的渐进时间复杂度,简称时间复杂度

       对比三种算法,具体请看https://cloud.tencent.com/developer/article/1350860

       首先冒泡排序是基于比较和交换的,比如我们要对n个数字排序,冒泡排序需要n-1次遍历,比如我们有10个数字,第一趟循环需要比较9次,第二趟循环需要比较8次,第三趟需要比较7次,以此类推,最后一趟需要1次比较。

    f(10)=9+8+7+......+1 ,可以转为一个等差数列:

    f(n)=(n-1)+(n-2)+(n-3)+......+1= (n-1)*n / 2 = 0.5n^2-0.5n

    当n趋于无穷大时否f(n)=n^2/2

     选择排序类似,但是最坏情况下,选则排序需要交换n-1次,冒泡排序需要交换n^2/2

    快速排序

         快速排序的递推式为:T(n)=max(T(q) + T(n-q-1)) +O(n),q为切分长度,如果每次切分都刚好切分成两半,则 q==n-q-1, T(q)==T(n-q-1) ,则简化为 T(n)=2T(n/2)+O(n)。换一下加法项的位置,T(n)=O(n)+2T(n/2),若 快速排序每次都会以2为低做裂变分解数组,所以最终推出来的渐近复杂度:Ο(nlog2n)

        如内容有问题,恳请大佬们指出,小生定虚心接受,谢谢。

    遇事犹豫不决时,须持虎狼之心,行仁义之事
  • 相关阅读:
    IOS开发中Xcode常用插件安装与管理(转)
    IOS开发中摇一摇是怎么实现的
    IOS中APP开发常用的一些接口
    数据结构——不相交集(并查集)
    数据结构——(最小)堆(完全二叉树)
    JDK1.7 中的HashMap源码分析
    Java中hashCode()方法以及HashMap()中hash()方法
    《Java多线程核心技术》读书摘要
    Java for LeetCode 237 Delete Node in a Linked List
    Java类变量、实例变量的初始化顺序
  • 原文地址:https://www.cnblogs.com/fmlyzp/p/10370470.html
Copyright © 2011-2022 走看看