您的位置:首页 > 编程语言 > Java开发

JAVA基本算法------冒泡、插入、快速排序

2018-01-29 17:49 274 查看

一、冒泡排序

1.原理

冒泡排序顾名思义就是整个过程像气泡一样往上升,单向冒泡排序的基本思想是(假设由小到大排序):对于给定n个记录,从第一个记录开始依次对相邻的两个记录进行比较,当前面的记录大于后面的记录时,交换位置,进行一轮比较和换位后,n个记录的最大记录将位于第n位,然后对前(n-1)个记录进行第二轮比较;重复该过程,直到记录剩下一个为止。

2.示例

{2,9,1,5,4,6,8,3,0}

第一趟比较

2,9,1,5,4,6,8,3,0     2和9比较,不换位置

2,9,1,5,4,6,8,3,0   ---->2,1,9,5,4,6,8,3,0 
   9和1比较换位置

2,1,9,5,4,6,8,3,0
 ----->2,1,5,9,4,6,8,3,0     9和5比较换位置

2,1,5,9,4,6,8,3,0
 ------>2,1,5,4,9,6,8,3,0     9和4比较换位置

2,1,5,4,9,6,8,3,0
 ------->2,1,5,4,6,9,8,3,0    9和6交换位置

2,1,5,4,6,9,8,3,0
 -------->2,1,5,4,6,8,9,3,0   9和8交换位置

2,1,5,4,6,8,9,3,0
 -------->2,1,5,4,6,8,3,9,0   9和3交换位置

2,1,5,4,6,8,3,9,0
--------->2,1,5,4,6,8,3,0,9   0和9交换位置

一共比较了8次(相当于循环比较了8次)

以此类推第二趟、第三趟。。。。都是这样  用 a[i] 与 a[i+1]比较 ,如果a[i]>a[i+1] 交换值,然后用交换值之后的a[i+1]跟后面的数继续比较直至结尾

3.代码实现

 public class DataStru
4000
ctAndMath {

    public static void main(String[] args) {

        System.out.println(Arrays.toString(Test.BSort()));

//结果  [0, 1, 2, 3, 4, 5, 6, 8, 9]

    }

}

class Test{

    //冒泡排序

    public static int[] BSort(){

        int[] arr={2,9,1,5,4,6,8,3,0};

        for (int i=0 ;i<arr.length-1;i++){ //如上示例的总循环次数,也就是第一趟、第二趟。。。总趟数N-1次

            for (int j=0;j<arr.length-i-1;j++){//如上示例的每趟里面的比较次数N-i-1次

                swap(arr, j);

            }

        }

     return arr;

    }

public static void swap(int[] arr, int j) {//交换时提取出来的方法

    if(arr[j]>arr[j+1]){

        int tmp=arr[j+1];

        arr[j+1]=arr[j];

        arr[j]=tmp;

    }

}

二、插入排序

1.原理

直接插入排序的基本操作是将一个记录插入到已经排好的有序表中,从而得到一个新的、记录数增1的有序表。对于给定的一组记录,初始时假定第一个记录自成一个有序序列,其余记录为无序序列。接着从第二个记录开始,按照记录的大小依次将当前处理的记录插入到其之前的有序序列中,直到最后一个记录插到有序序列中为止。

2.示例

{2,9,1,5,4,6,8,3,0}

从索引位i=1开始,i=0作为基准位置,从1开始插入

开始 2  [9,1,5,4,6,8,3,0]

第一次插入  2 9 [1,5,4,6,8,3,0]
 2和9比较(比较一次),插入到2的右边

第二次插入  1 2 9 [5,4,6,8,3,0]  1和[2,9] 两个数比较(比较两次),只能插入到最左边

第三次插入   1 2 5 9 [ 4,6,8,3,0]  5和[ 1,2,9 ] 三个数比较(比较二次),插入2的右边

以此类推 从  i=1的位置取出数与前面 i-1>=0 (i-1>=0意味着已插入排好序的数组中进行逐个对比大小)的数进行循环对比,此类算法比冒泡更加快一些,比较次数少一些

3.代码实现

public class DataStructAndMath {

    public static void main(String[] args) {

        System.out.println(Arrays.toString(Test.ISort()));

//结果  [0, 1, 2, 3, 4, 5, 6, 8, 9]

    }

}

class Test{

    //插入排序

    public static int[] ISort(){

        int[] arr={2,9,1,5,4,6,8,3,0};

       for (int i=1 ;i<arr.length;i++){   //从第一个索引位开始循环插入,直至最后一个数

            int j=i-1;     //定义  插入数据索引位   前面的 数据的索引位 

            int innode=arr[i];  //给定插入数据的值

            while (j>=0 && innode<arr[j]){   //插入的值小于前面的值,交换位置,并且j--,继续往下循环比较

                arr[j+1]=arr[j];   

                j--;

            }

            arr[j+1]=innode;    //直到没有比插入元素更小的时候,把innode插入到数组中

        }

       return arr;

    }

}


三、快速排序(面试问得最多的)

1.原理

快速排序之所比较快,因为相比冒泡排序,每次交换是跳跃式的。每次排序的时候设置一个基准点,将小于等于基准点的数全部放到基准点的左边,将大于等于基准点的数全部放到基准点的右边。这样在每次交换的时候就不会像冒泡排序一样每次只能在相邻的数之间进行交换,交换的距离就大的多了。因此总的比较和交换次数就少了,速度自然就提高了。当然在最坏的情况下,仍可能是相邻的两个数进行了交换。因此快速排序的最差时间复杂度和冒泡排序是一样的都是O(N2),它的平均时间复杂度为O(NlogN)。其实快速排序是基于一种叫做“二分”的思想

2,9,1,5,4,6,8,3,0

2.示例

以下是个特殊例子

数组下表索引
 左边从i开始 ,右边从j开始

以2位基准值来做,从右往左遍历寻找比2小的值,找到后停止,开始从左边遍历寻找比2大的值,找到后停止

第一次交换
    2,【9】,1,5,4,6,8,3,【0】   -----交换----> 2, 【0】,1,5,4,6,3,【9】

第二次交换
    2,0,1,5,4,6,3,9  -------无法交换--->  2,0,1,【5】,4,6,3,9  ,此时右边没有找到比2小的值,所以到 i=j时不能再遍历了,2<5不满足交换基准值的条件,无法交换

此时我们的基准值则交换5前面满足条件(x<2)的数===>
[1] ,0 ,[2] ,5, 4,6,3,9

2左边的
1,0调用函数递归方法完成排序 

2右边的5,4,6,3,9
同样调用递归方法

再举个普通例子

6
1 2 7 9 3 4 5 10 8


还是按照上面的方法做

第一次
: 6 1 2 【7】 9 3 4 【5】10 8 ----交换----> 6 1 2 [ 5 ] 9 3 4 [7] 10 8


第二次:
6 1 2 5 【9】 3 【4】 7 10 8 ----交换-----> 6 1 2 5 [4] 3 [9] 7 10 8


第三次的时候左右两边碰头,i=j不再遍历,正好
3满足条件小于基准数6 交换得到


3
1 2 5 4 【6】 9 7 10 8


左边 3 1 2 5 4  按照 3为基准数 递归一下

右边 9 7 10 8 按照9为基准数递归一下

3.代码实现

public class DataStructAndMath {

    public static void main(String[] args) {

        int[] arr={2,9,1,5,4,6,8,3,0};

         Test.QuikSort(arr,0,arr.length-1 );

       // Test.sort(arr,0,arr.length-1);

        System.out.println(Arrays.toString(arr));

    }

}  

  public static v
9692
oid QuikSort(int[] arr,int low,int high){

      int i,j,index,tmp;

        if(low>high){

            return;

        }

        i=low;

        j=high;

        index=arr[low];

        while (i<j){

            while (index<=arr[j]&&i<j){ //从右往左以此查找,发现比基准值大的数j--,小的数停止

                j--;

            }

            while (index>=arr[i] && i<j){//从左往右以此查找,发现比基准值小的数i++,大的数停止

                i++;

            }

            //上述过程进行交换

            if(i<j){

                tmp=arr[i];

                arr[i]=arr[j];

                arr[j]=tmp;

            }

        }

        //原有基准点跟现有基准点进行移位

        arr[low]=arr[i];

        arr[i]=index;

        //递归左半边排序

        QuikSort(arr,low,j-1);

        //递归右半边排序

        QuikSort(arr,j+1,high);

    }
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  java 基础算法 排序