排序算法--java实现

之前总结过常见排序算法的时间复杂度、空间复杂度、是否稳定等特性,现将代码补上。

代码:

/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package javaapplication20;

import java.util.Arrays;

/**
 *
 * @author cdxxs
 */
public class JavaApplication20 {

    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) {
        // TODO code application logic here
        int[] arr ={30, 2, 10, -10, 23, 15};
        JavaApplication20 demo = new JavaApplication20();
        
        System.out.println(Arrays.toString(arr));
        //demo.bubblesort(arr);
        //demo.bubblesort1(arr);
        //demo.selectsort(arr);
        //demo.insertsort1(arr);
        //demo.insertsort2(arr);
        //demo.mergesort(arr, 0, arr.length-1);
        //demo.quicksort(arr, 0, arr.length-1);
        //demo.shellsort1(arr);
        //demo.shellsort2(arr);
        
        System.out.println(Arrays.toString(arr));
    }
    
    //交换
    public void swap(int[] arr, int i, int j){
        int tmp = arr[i];
        arr[i] = arr[j];
        arr[j] = tmp;
    }
    
    //冒泡排序O(n^2) 最好O(n) 空间复杂度O(n) 稳定
    public void bubblesort(int[] arr){
        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])
                    swap(arr, j, j+1);
    }
    
    //冒泡排序优化,设置标志位,如果经过一次冒泡排序没有交换元素,那么直接返回,如果交换了,那么继续冒泡排序
    public void bubblesort1(int[] arr){
        int flag = 0;
        
        for(int i = 0; i < arr.length; i++){
            for(int j = 0; j < arr.length-1; j++){
                if(arr[j] > arr[j+1]){
                    swap(arr, j, j+1);
                    flag = 1;//表示已经交换了
                }
            }
            
            //如果flag==0,说明已经排好序了,那么直接返回
            if(flag == 0)
                return ;
            
            flag = 0;
        }
    }
    
    //选择排序O(n^2) O(1) 不稳定:2 2 2 1
    public void selectsort(int[] arr){
        for(int i = 0; i < arr.length-1; i++)
            for(int j = i+1; j < arr.length; j++)
                if(arr[i] > arr[j])
                    swap(arr, i, j);
    }
    
    //插入排序O(n^2) 最好O(n)排好序 空间O(1) 稳定
    public void insertsort1(int [] arr){
        //第一个元素是有序序列,从第二个数字开始,对每个数字进行插排,从后向前遍历排序序列,插入合适的位置
        for(int i = 1; i < arr.length; i++){
            int tmp = arr[i];
            int j = i-1;
            
            while(j >= 0 && arr[j] > tmp){
                arr[j+1] = arr[j];
                j--;
            }
            
            arr[j+1] = tmp;
        }
    }
    
    //插入排序优化
    public void insertsort2(int[] arr){
        for(int i = 1; i < arr.length; i++){
            for(int j = i-1; j >= 0; j--){
                if(arr[j] > arr[j+1])
                    swap(arr, j, j+1);
                else
                    break;
            }
        }
    }
    
    //希尔排序 O(nlogn) O(1) 不稳定:5 1 1 2,tag = 2
    public void shellsort1(int[] arr){
        int gap = arr.length;
        
        while(gap > 1){
            gap = gap/3+1;
            
            for(int i = gap; i < arr.length; i++){
                int tmp = arr[i];
                int j = i-gap;
                
                while(j >= 0 && arr[j] > tmp){
                    arr[j+gap] = arr[j];
                    j -= gap;
                }
                
                arr[j+gap] = tmp;
            }
        }
    }
    
    //希尔排序优化
    public void shellsort2(int[] arr){
        int gap = arr.length;
        
        while(gap > 1){
            gap = gap/3+1;
            
            for(int i = gap; i < arr.length; i++){
                for(int j = i-gap; j >= 0; j -= gap){
                    if(arr[j] > arr[j+gap])
                        swap(arr, i, j+gap);
                    else 
                        break;
                }
            }
        }
    }
    
    //快速排序 O(nlogn)最好,每次划分都能均匀地划分成两份 O(n^2)最差,对应已经排好序的序列 空间复杂度是O(logn)~O(n),和具体的划分方式有关 不稳定:4 3 3 3 1
    public void quicksort(int[] arr, int start, int end){
        if(arr == null || start < 0 || end >= arr.length || start > end)
            throw new IllegalArgumentException("illegal parameters");
        
        int key = arr[start];
        int i = start;
        int j = end;
        
        while(i < j){
            //j从后向前遍历,找比其小的数字
            while(i < j && arr[j] >= key)
                j--;
            
            //i从前向后遍历,找比其大的数字
            while(i < j && arr[i] <= key)
                i++;
            
            if(i == j)
            {
                swap(arr, i, start);//找到了key的位置
                break;
            }
            
            swap(arr, i, j);
        }
        
        //如果左边还有待排序数字,递归进行快速排序
        if(start < i)
            quicksort(arr, start, i-1);
        //如果右边还有待排序数字,递归进行快速排序
        if(i < end)
            quicksort(arr, i+1, end);
    }
    
    //归并排序 O(nlogn) O(n)空间复杂度 稳定
    public void mergesort(int[] arr, int start, int end){
        if(arr == null || start < 0 || end >= arr.length || start > end)
            throw new IllegalArgumentException("illegal parameters");
        
        if(start < end){
            int mid = (start+end)/2;
            
            mergesort(arr, start, mid);
            mergesort(arr, mid+1, end);
            
            merge(arr, start, mid, end);//将数组合并
        }
    }
    
    //合并两个数组
    public void merge(int[] arr, int start, int mid, int end){
        int[] tmp = new int[end-start+1];//定义临时数组,存储排好序的数组
        int i = start, j = mid+1, k = 0;//定义三个变量,分别用于遍历前半个数组,后半个数组,以及临时数组
        
        while(i <= mid && j <= end){
            if(arr[i] < arr[j])
                tmp[k++] = arr[i++];
            else
                tmp[k++] = arr[j++];
        }
        
        //如果i还没遍历结束
        while(i <= mid)
            tmp[k++] = arr[i++];
        while(j <= end)
            tmp[k++] = arr[j++];
        
        //重构数组
        for(i = 0; i < tmp.length; i++)
            arr[i+start] = tmp[i];
    }
}

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值