排序算法 java版本

冒泡排序

package com.test;

/**
 * 冒泡排序
 *
 * 时间复杂度为:o(n`2)  空间复杂度为o(1)
 *
 * 最好最坏复杂度都是o(n`2)
 *
 * 说明:
 * 对当前还未排序的所有数,自上而下对相邻的两个数依次进行比较和调整,
 * 让较大的数日后面移动 , 让较小的数往前面移动
 *
 * 算法比较稳定 为两两比较 不存在跳跃
 *
 * Created by abing on 2015/11/26.
 */
public class SuanFaBubble {

    public static void main(String[] args){
        int[] a = {1,2,6,5,4,3,23,43,123,432};
        sort(a);
    }


    public static void sort(int[] arr){

        int tmp = 0;
        for ( int i = 0 ; i < arr.length - 1 ; i++ ){
            for (int j = 0 ; j < arr.length - 1 - i ; j++){
                if (arr[j] > arr[j+1]){
                    tmp = arr[j];
                    arr[j] = arr[j+1];
                    arr[j+1] = tmp;
                }
            }
        }

        for (int a : arr){
            System.out.print(a + " ");
        }

    }
}


基数排序

package com.test;

import java.util.ArrayList;
import java.util.List;

/**
 * 基数排序
 *
 * 时间复杂度为o(n+k)
 * 最好最坏都同样
 *
 * 说明:
 * 将全部待比较数值(正整数)统一为一样的数位长度,数位较短的数前面补零。
 * 而后,从最低位开始,依次进行一次排序。
 * 这样从最低位排序一直到最高位排序完成之后,数列就变成一个有序序列
 *
 * Created by abing on 2015/11/26.
 */
public class SuanFaCount {

    public static void main(String[] args){

        int[] array ={1,3,6,2,5,87,54,32,21,22,33,44,11};
        sort(array);
        for (int a : array){
            System.out.print(a + " ");
        }
    }

    public static void sort(int[] array){
        //首先肯定排序的趟数;
        int max=array[0];
        for(int i=1;i<array.length;i++){
            if(array[i]>max){
                max=array[i];
            }
        }
        int time=0;
        //判断位数;
        while(max>0){
            max/=10;
            time++;
        }

        //创建10个队列;
        List<ArrayList> queue=new ArrayList<ArrayList>();
        for(int i=0;i<10;i++){
            ArrayList<Integer>queue1=new ArrayList<Integer>();
            queue.add(queue1);
        }

        //进行time次分配和收集;
        for(int i=0;i<time;i++){
            //分配数组元素;
            for(int j=0;j<array.length;j++){
                //获得数字的第time+1位数;
                int x=array[j]%(int)Math.pow(10,i+1)/(int)Math.pow(10, i);
                ArrayList<Integer>queue2=queue.get(x);
                queue2.add(array[j]);
                queue.set(x, queue2);
            }
            int count=0;//元素计数器;
            //收集队列元素;
            for(int k=0;k<10;k++){
                while(queue.get(k).size()>0){
                    ArrayList<Integer>queue3=queue.get(k);
                    array[count]=queue3.get(0);
                    queue3.remove(0);
                    count++;
                }
            }
        }
    }
}

快速排序

package com.test;

/**
 * 快速排序
 *
 * 时间复杂度为o(nlogn) 空间复杂度为o(logn)
 *
 * 最坏O(n^2) 当划分不均匀时候 逆序and排好序都是最坏状况
     最好O(n) 当划分均匀
     partition的时间复杂度: O(n)一共须要logn次partition
 *
 *说明:
 * 选择一个基准元素,一般选择第一个元素或者最后一个元素,经过一趟扫描,将待排序列分红两部分,
 * 一部分比基准元素小,一部分大于等于基准元素,此时基准元素在其排好序后的正确位置,而后再用一样的方法递归地排序划分的两部分。
 *
 * Created by abing on 2015/11/26.
 */
public class SuanFaFast {

    public static void main(String[] args){
        int[] aa = {1,4,6,2,5,8,21,43,22,44,33};

        quick(aa);

        for (int a : aa){
            System.out.print(a + " ");
        }
    }

    public static void quick(int[] arr){
        if (arr.length > 0){
            quickSort(arr , 0 ,arr.length - 1);
        }
    }

    public static void quickSort(int[] arr , int low , int high){
        if (low < high){
            int middle = getMiddle(arr , low ,high);    //将list一份为二
            quickSort(arr , low , middle - 1);          //对低字表进行递归排序
            quickSort(arr , middle + 1 , high);         //对高字表进行递归排序
        }
    }

    public static int getMiddle(int[] arr , int low , int high){
        int tmp = arr[low];             //数组的第一个做为中轴
        while (low < high){
            while (low < high && arr[high] >= tmp){
                high--;
            }
            arr[low] = arr[high];       //比中轴小的记录移到低端
            while (low < high && arr[low] <= tmp){
                low++;
            }
            arr[high] = arr[low];       //比中轴大的记录移到高端
        }
        arr[low] = tmp;                 //中轴记录到尾
        return low;                     //返回中轴记录
    }
}

希尔排序

package com.test;

/**
 * 希尔排序
 *
 * 时间复杂度o(n`1.2)
 *
 * 说明:
 * 算法先将要排序的一组数按照某个增量d(n/2 , m为要排序的个数)分为若干组 , 每组中记录的下标相差d,
 * 对每组中所有元素进行直接插入排序。而后再用一个较小的增量(d/2)对它进行分组,在每组中再进行插入排序。
 * 当增量减小到1的时候,进行直接插入排序后。排序完成。
 *
 *
 * Created by abing on 2015/11/26.
 */
public class SuanFaHill {

    public static void main(String[] args){
        int[] arr = {1,8,4,2,6,12,34,21,33,55,11,88,33};
        sort(arr);

    }

    public static void sort(int[] arr){
        double d1 = arr.length;
        int tmp = 0 ;
        while (true) {
            d1 = Math.ceil(d1/2);
            int d = (int) d1;
            for (int x = 0 ; x < d ; x++){
                for (int i = x+d ; i < arr.length ; i+=d){
                    int j = i -d;
                    tmp = arr[i];
                    while (j >=0 && tmp <arr[j]){
                        arr[j+d] = arr[j];
                        j -=d;
                    }
                    arr[j+d] = tmp;
                }
            }
            if (d == 1){
                break;
            }
        }

        for (int a : arr){
            System.out.print(a + " ");
        }

    }
}

插入排序

package com.test;

/**
 * 插入排序
 * 时间复杂度 o(n`2)  控件复杂度 o(1)
 *
 * 最好为n  最坏复杂度为n`2
 *
 * 说明:
 * 从头开始排序  若是后面有比前面小的直接插入其中
 *
 * Created by abing on 2015/11/26.
 */
public class SuanFaInsert {

    public static void main(String[] args){
        int[] a = {1,2,6,5,4,3,23,43,123,432};
        sortWhile(a);
    }

    /**
     * 这一种使用的是两层for循环进行排序
     * @param arr
     */
    public static void sort(int[] arr){

        int tmp = 0;
        for (int i = 0 ; i < arr.length ; i++) {
            for (int j = i-1 ; j >= 0 ; j--){
                if (arr[j+1] < arr[j]){
                    tmp = arr[j+1];
                    arr[j+1] = arr[j];
                    arr[j] = tmp;
                }
            }
        }

        for (int a : arr){
            System.out.print(a + " ");
        }


    }

    /**
     * 本循环与上面的差很少  只不过是使用了while循环
     * @param arr
     */
    public static void sortWhile(int[] arr){

        int tmp = 0;
        for (int i = 1 ; i < arr.length ; i++) {
            int j = i-1;
            while (arr[j+1] < arr[j]){
                tmp = arr[j+1];
                arr[j+1] = arr[j];
                arr[j] = tmp;
                j--;
            }
        }

        for (int a : arr){
            System.out.print(a + " ");
        }


    }
}

归并排序

package com.test;

import java.util.Arrays;

/**
 * 归并排序
 *
 * 时间复杂度为o(nlogn) 空间复杂度为 o(n) + o(logn)
 *
 * 说明:
 * 把两个(或者两个以上)的有序表合并成一个新的有序表 , 把待排序序列分为若干个序列 , 每一个子序列都是有序的
 * 而后再把有序的子序列合并为总体有序序列
 *
 * Created by abing on 2015/11/26.
 */
public class SuanFaMerge {

    public static void main(String[] args){
        int[] data = {1,2,3,5,21,43,65,87,22,33,44,55,99};
        sort(data , 0 , data.length-1);
    }

    public static void sort(int[] data , int left , int right){
        if (left < right){
            int center = (right + left)/2;
            System.out.println("11 : "+left + " " + center + " " + right);
            sort(data, left, center);
            System.out.println("22 : "+left + " " + center + " " + right);
            sort(data, center + 1, right);
            System.out.println("33 : "+left + " " + center + " " + right);
            merge(data , left ,center , right);
        }
    }

    public static void merge(int[] data , int left , int center , int right){
//        System.out.println(left + " " + center + " " + right);
        int[] tmpArr = new int[data.length];
        int mid = center+1;
        //记录中间数组的索引
        int third = left;
        int tmp = left;
        while (left <= center && mid <= right){
            //从两个数组中取出最小的放入中间数组
            if (data[left] <= data[mid]){
                tmpArr[third++] = data[left++];
            }else {
                tmpArr[third++] = data[mid++];
            }
        }
        //剩余部分依次放入中间数组
        while (mid <= right){
            tmpArr[third++] = data[mid++];
        }
        while (left <= center){
            tmpArr[third++] = data[left++];
        }
        //将中间数组中的内容复制回原数组
        while (tmp <= right){
            data[tmp] = tmpArr[tmp++];
        }
        System.out.println(Arrays.toString(data));


    }
}

选择排序

package com.test;

/**
 * 选择排序  时间复杂度为o(n`2)  空间复杂度为o(1)
 *
 * 没有最好最坏的状况  排序时间都是同样的
 *
 * 说明:
 * 从头开始排序 从后面选择最小的与第一个交换     而后再从后面选择最小的与第二个进行交互
 *
 * 知道交换到倒数第二个与倒数第一个进行交换
 *
 * Created by abing on 2015/11/26.
 */
public class SuanFaSelect {

    public static void main(String[] args){

        int[] arr ={1,4,7,3,22,65,44,22,88,54,76,31,32};
        sort(arr);

    }

    public static void sort(int[] arr){
        for (int i = 0 ; i < arr.length -1 ; i++){
            int min = i;
            int tmp;
            for (int j = i+1 ; j < arr.length ; j++){
                if (arr[j] < arr[min]){
                    min = j;
                }
            }
            if (min != i){
                tmp = arr[min];
                arr[min] = arr[i];
                arr[i] = tmp;
            }
        }
        for (int a : arr){
            System.out.print(a + " ");
        }

    }
}

堆排序

package com.test;

import java.util.Arrays;

/**
 * 堆排序
 *
 * 时间复杂度o(nlogn)  空间复杂度o(1)
 *
 * 没有最好与最坏的区别 时间复杂度都是o(nlogn) 不是很稳定的算法
 *
 * 说明:
 *具备n个元素的序列(h1,h2,...,hn),当且仅当知足(hi>=h2i,hi>=2i+1)或(hi<=h2i,hi<=2i+1)(i=1,2,...,n/2)时称之为堆。
 * 在这里只讨论知足前者条件的堆。由堆的定义能够看出,堆顶元素(即第一个元素)必为最大项(大顶堆)。彻底二叉树能够很直观地表示堆的结构。
 * 堆顶为根,其它为左子树、右子树。初始时把要排序的数的序列看做是一棵顺序存储的二叉树,调整它们的存储序,使之成为一个堆,
 * 这时堆的根节点的数最大。而后将根节点与堆的最后一个节点交换。而后对前面(n-1)个数从新调整使之成为堆。
 * 依此类推,直到只有两个节点的堆,并对它们做交换,最后获得有n个节点的有序序列。
 * 从算法描述来看,堆排序须要两个过程,一是创建堆,二是堆顶与堆的最后一个元素交换位置。
 * 因此堆排序有两个函数组成。一是建堆的渗透函数,二是反复调用渗透函数实现排序的函数。
 *
 *
 * 对于大数据的处理呢,若是对100亿条数据选择Topk数据,选择快速排序好仍是堆排序好?
 * 答案是只能用堆排序。
 * 堆排序只须要维护一个k大小的空间,即在内存开辟k大小的空间。而快速排序须要开辟能存储100亿条数据的空间
 *
 * Created by abing on 2015/11/26.
 */
public class SuanFaStack {

    public static void main(String[] args){
        int[] a = {3,1,4,6,2,43,21,65,22,44,88,11};

        headSort(a);

        for (int i : a){
            System.out.print(i + " ");
        }

    }


    public static void headSort(int[] arr){
        int arrlength = arr.length;
        for (int i = 0 ; i < arrlength - 1 ; i++){
            buildMaxHeap(arr, arrlength - 1 - i);
            swap(arr, 0, arrlength - 1 - i);
            System.out.println(Arrays.toString(arr));
        }
    }

    public static void swap(int[] arr , int i , int j){
        int tmp = arr[i];
        arr[i] = arr[j];
        arr[j] = tmp;
    }

    public static void buildMaxHeap(int[] data , int lastIndex){
        for (int i = (lastIndex-1)/2 ; i >= 0 ; i--){
            int k = i;
            while (k*2 + 1 <= lastIndex){
                int biggerIndex = 2*k + 1;
                if (biggerIndex < lastIndex){
                    if (data[biggerIndex] < data[biggerIndex+1]){
                        biggerIndex++;
                    }
                }

                if (data[k] < data[biggerIndex]){

                    swap(data , k , biggerIndex);
                    k = biggerIndex;
                }else {
                    break;
                }

            }

        }
    }
}
相关文章
相关标签/搜索