JAVA 排序算法整理总结,看了这个保你理解

    排序目录
    ------1.冒泡排序
    ------2.选择排序
    ------3.直接插入排序
    ------4.希尔排序
    ------5.快速排序
    ------6.堆排序
    ------7.归并排序

一、冒泡排序法

public class Bubble{
    public static void main(String[] args){
        int a[] = {3,1,10,8,100,89,181,120};

        bubbleSort(a);

        //排序后输出
        for(int i = 0;i < a.length;i++){
            System.out.print(a[i]+" ");
        }

    }
    public static void bubbleSort(int arr[]){
        int len = arr.length;
         //冒泡排序两层循环,第一次是表明排序的次数,应该是长度减1次
        //第二次是表示进行比较的两个数,终止条件是长度减1减i
        for(int i = 0;i < len-1;i++){
            for(int j = 0;j < len-1-i;j++){
                if(arr[j] > arr[j+1]){
                    int temp = arr[j];
                    arr[j] = arr[j+1];
                    arr[j+1] = temp;
                }
            }
        }

    }



}

思想:
每次取一个数,不断与其他数进行比较,交换;依次循环。

辅助空间o(1)
稳定性:稳定

时间复杂度 :最好:o(n), 最坏:o(n*n),平均:o(n*n)

备注:n小时较好

二、选择排序

public class selectSort{
    public static void main(String[] args){
        int a[] = {21,1,12,9};

        System.out.println(" ");
        selSort(a);
        //排序后输出
        for(int i = 0;i<a.length;i++){
            System.out.print(a[i]+" ");
        }
    }
    public static void selSort(int arr[]){
        int i,j;
        int len = arr.length;
        for(i = 0;i < len;i++){
            int min = arr[i];
            int flag = i;//最小值的下标
            for(j = i+1;j < len;j++){
                if(arr[j] < min){//找出最小数
                    min = arr[j];
                    flag = j;
                }
            }
            arr[flag] = arr[i];
            arr[i] = min;
        }
    }
}

思想:
与冒泡的区别,只比较不交换。定义一个临时标量存储当前最小,并设置标记位。

辅助空间o(1)
稳定性:不稳定

时间复杂度:最好:o(n*n),最坏:o(n*n), 平均:o(n*n)

备注:n小时较好

三、直接插入排序

public class Insert {
    public static void main(String[] args){
        int a[] = {2,1,90,5};

        //排序后进行输出打印
        insertSort(a);
        for (int i = 0;i < a.length;i++){
            System.out.print(a[i]+" ");
        }

    }
    public static void insertSort(int array[]){
        for(int i = 1;i < array.length;i++){    //待插入元素,从1位置开始递增
            int temp = array[i];
            int j; 
            for (j = i-1;j >= 0;j--){ 
//将插入元素之前的元素与之比较,小则右移否则跳出, 注意这里是>=
                if (array[j] > temp){
                    array[j+1] = array[j];  
                }
                else
                    break; //跳出用break,因为前面都是有序的,一旦小于都小于
            }
            array[j+1] = temp;   
        }
    }

}

思想:
两层循环,第一层表示的是待插入的元素,第二层表示的是待插入之前的元素;依次进行比较,右移,找到合适的位置放入待插入元素。

辅助空间o(1)
稳定性:稳定

时间复杂度 :最好:o(n),最坏:o(n*n), 平均:o(n*n)

备注:大部分已有序时较好

四、希尔排序,缩小增量排序

public class Test{
    public static void main(String[] args){
        int a[] = {2,12,1,0,9};

        shellSort(a);
        //排序后输出
        for(int i = 0;i < a.length;i++){
            System.out.print(a[i]+" ");
        }
    }
    public static void shellSort(int arr[]){
        int i,j;
        int len = arr.length;
        int temp;
        int h;      //步长因子
//第一层循环,步长因子的递减
        for (h = len/2;h>0;h=h/2){  
//第二层循环,就是按照直接插入排序的思路了
            for(i = h;i<len;i++){
                temp = arr[i];
//第三层循环,注意初始条件(可认为,直接插入是h=1的情况)
                for(j = i-h;j>=0;j-=h){
                    if(arr[j]>temp){
                        arr[j+h] = arr[j];
                    }
                    else
                        break;
                }
                arr[j+h] = temp;
            }
        }
    }
}

思想:
希尔排序建立在直接插入排序的基础上,直接插入可看作是希尔排序中步长因子为1 的特殊情况;
三层循环,第一层首先确定步长因子,后两层就是直接插入的思路,将增量1 改为步长h即可。

辅助空间o(1)
稳定性:不稳定

时间复杂度 : 最好:o(n),最坏:o(n*s),1

public class Quick{
    public static void main(String[] args){
        int a[]={49,38,65,97,76,13,27,4918,23,34,15,35,25,53,51};
        quickSort(a,0,a.length-1);  
        //排序后输出
        for(int i = 0;i < a.length;i++){
            System.out.print(a[i]+" ");
        }
    }

    public static void quickSort(int arr[],int low,int high){
        if(low < high){//这的判决条件不能丢
            int middle = getMiddle(arr,low,high);
            quickSort (arr, low, middle - 1);       //对低字表进行递归排序    
           quickSort (arr,middle + 1, high);       //对高字表进行递归排序    
        }

    }
    public static int getMiddle(int[] arr,int low,int high){
        int temp = arr[low];//将第一个数low作为中轴
        while(low < high){
            while(low < high && arr[high] >= temp){
                high--;
            }
            arr[low] = arr[high];//比中轴小的记录移到低端   

            while(low < high && arr[low] <= temp){
                low++;
            } 
            arr[high] = arr[low];//比中轴大的记录移到高端    
        }
        arr[low] = temp;              //此时temp左边比他小,右边大    
       return low;                   //返回中轴的位置    
    }
}   

思想:
快速排序是重点!!!
整体思路是定义low和high的标志位,每次选取low位置元素,通过getMiddle函数,将其移动到数组中间,保证其左边元素比它小,右边比它大。不断递归,实现排序。

辅助空间o(logn)
稳定性:不稳定

时间复杂度:最好:o(nlogn)、 最坏:o(n*n)、平均:o(nlogn)

备注:n大时较好
六、堆排序

public class Heap{
    public static void main(String[] args){     inta[]={49,38,65,97,76,13,27,49,78,34,12,68,54,56,17,18,23,34,15,35,25,53,51};
        heapSort(a);
        for (int i = 0;i < a.length;i++)
        {
            System.out.print(a[i]+" ");
        }
    }

    public static void heapSort(int arr[]){
        int len = arr.length;
        //循环建堆,这一层表示需要建几次堆
        for(int i = 0;i < len-1;i++){
            buildMaxHeap(arr,len-1-i);//建堆,最后一个元素
            swap(arr,0,len-1-i);//交换堆顶和最后一个元素
        }
    }
    private static void swap(int data[],int i,int j){
        int temp = data[i];
        data[i] = data[j];
        data[j] = temp;
    }

思想:
堆排序首先一个大for循环,表示需要建几次堆,其中调用建堆的函数,调用交换函数(交换第一个元素和最后一个元素);重点是关于建堆函数的实现,首先从最后一个节点的父亲开始,判断是否有孩子,是否有有孩子,并将最大值给了父亲。
辅助空间o(1)
稳定性:不稳定

时间复杂度:最好:o(nlogn),最坏:o(nlogn), 平均:o(nlogn)

备注:n大时较好

七、归并排序

public class Merge{
    public static void main(String[] args){
    int a[]={49,38,65,97,76,13,27,4918,23,34,15,35,25,53,51};
        mergingSort(a);
        for (int i = 0;i < a.length;i++)
        {
            System.out.print(a[i]+" ");
        }
    }

    public static void mergingSort(int arr[]){
        sort(arr,0,arr.length-1);
    }
    public static void sort(int data[],int left,int right){
        if (left<right){
            //找出中间索引
            int center = (left+right)/2;
            //对左边数组进行递归
            sort(data,left,center);
            //对右边数组进行递归
            sort(data,center+1,right);
            //合并
            merge(data,left,center,right);
        }
    }
    public static void merge(int data[],int left,int center,int right){
        int tmpArr[] = new int[data.length];
        int third=left;  
        int mid = center+1;  
        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++];  
        }  

    } 

}

思路:
归并排序分为两部分:首先是归,运用递归的思想,将数组分半在分半,直至每一组都成为一个元素;然后进行并的操作,创建一个新的数组(注意用到的额外的存储空间),将左右两个数组元素分别比较,按顺序放入新数组中,然后将剩余元素放到新数组,最后将新数组中元素复制到原来的数组中。

辅助空间o(n)
稳定性:稳定

时间复杂度:最好:o(nlogn),最坏:o(nlogn),平均:o(nlogn)

备注:n大时较好

简单的总结整理,希望对大家有所帮助如有错误欢迎大家批评指教!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值