8种排序算法总结

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/tanliqing2010/article/details/79641840

复杂度总结

这里写图片描述

一、冒泡排序

1、基本思想

  1. 比较相邻的两个元素,前面元素比后面大,就交换两个元素,一轮下来就可以得出最后一个元素就是最大的元素。

2、动态图

这里写图片描述

3、代码

/*************************************************************************
    > File Name: BubbleSort.java
    > Author: 
    > Mail: 
    > Created Time: Wed 21 Mar 2018 04:33:15 PM CST
 ************************************************************************/
import java.util.Arrays;
public class BubbleSort{
    public void sort(int[] arr){
        int length = arr.length;
        int tmp;
        for(int i = 0 ; i < length ; i++){
            for(int j = 1 ; j < length-1-i;j++){
                if (arr[j]>arr[j+1]){
                    tmp = arr[j];
                    arr[j] = arr[j+1];
                    arr[j+1] = tmp;
                }
            }
        }
    }
    public static void main(String[] args){
        int[] arr = {1,10 ,30,2,3,9,8,7,16};
        BubbleSort sort =new BubbleSort();
        sort.sort(arr);
        System.out.println(Arrays.toString(arr));
    }
}

二、选择排序

1、基本思想

  1. 把数据分为有序区和无序去
  2. 在无序区找到最小元素,然后放在有序区的末尾
  3. 需要标记无序区中最小元素的下标

2、动态图

这里写图片描述

3、代码

/*************************************************************************
    > File Name: SelectSort.java
    > Author: 
    > Mail: 
    > Created Time: Wed 21 Mar 2018 05:11:39 PM CST
 ************************************************************************/
import java.util.Arrays;
public class SelectSort{
    public void sort(int[] arr){
        int len = arr.length;
        int k ;
        for(int i = 0 ; i < len -1 ; i++){
            k = i;
            for(int j = i+1 ; j < len ;j++){
                if (arr[k] > arr[j]){
                    k = j;
                }
            }
            swap(arr , i , k);
        }
    }
    public void swap(int[] arr , int i ,int j){
        if ( i == j ) return;
        int temp = arr[i];
        arr[i] = arr[j];
        arr[j] = temp;
    }
    public static void main(String[] args){
        int[] arr = {5,1,4,6,30,20,10,38};
        SelectSort sort = new SelectSort();
        sort.sort(arr);
        System.out.println(Arrays.toString(arr));
    }
}

三、插入排序

1、基本思想

  1. 认为第一个元素是已经排序好的,认为是一个有序区,之后的元素认为是一个无序区
  2. 取出无序区的第一个元素,从后向前与有序区元素进行比较,找到正确的位置就插入到该位置

2、动态图

这里写图片描述

3、代码

/*************************************************************************
    > File Name: InsertSort.java
    > Author: 
    > Mail: 
    > Created Time: Wed 21 Mar 2018 05:37:09 PM CST
 ************************************************************************/
import java.util.Arrays;
public class InsertSort{
    public void sort(int[] arr){
        int current ;
        for(int i = 1 ; i < arr.length ; i++){
            // 记录无序区的第一个元素,
            current = arr[i];
            int j = i -1;
            // 1、从后往前循环有序区,找到current的位置
            // 2、无序区需要做移动 , 其中i位置就是一个空位了
            while(j >= 0 && arr[j] > current){
                // 前面的元素往后移动
                arr[j+1] = arr[j]
                j--;
            }
            // 上面的while循环执行了j--操作
            arr[j+1] = current;
        }
    }
    public static void main(String[] args){
        int[] arr = {2 ,1 ,4 ,6,3,40,32,12};
        InsertSort sort = new InsertSort();
        sort.sort(arr);
        System.out.println(Arrays.toString(arr));
    }
}

四、希尔排序

1、基本思想

2、动态图

这里写图片描述

3、代码

五、归并排序

1、基本思想

  1. 两个连续有序区间的合并动作
  2. 切分成足够小
  3. 递归思想

2、动态图

这里写图片描述

3、代码

/*************************************************************************
    > File Name: MergeSort.java
    > Author: 
    > Mail: 
    > Created Time: Thu 22 Mar 2018 10:51:33 AM CST
 ************************************************************************/
import java.util.Arrays;
public class MergeSort{
    public void sort(int[] arr){
        int[] auxArr = new int[arr.length];
        mergeSort(arr , auxArr , 0 , arr.length - 1);
    }

    public void mergeSort(int[] arr, int[] auxArr , int low , int high){
        int divideIndex = 0;
        if(low < high){
            divideIndex = (low + high) /  2 ;
            mergeSort(arr , auxArr , low , divideIndex);
            mergeSort(arr , auxArr , divideIndex + 1 , high);
            merge(arr , auxArr , low , divideIndex , high);
        }
    }  
    public void merge(int[] arr , int[] auxArr , int low , int divideIndex , int high){
        int i = low ;
        int j = divideIndex + 1;
        int k = 0;
       // 左右两边都是有序的,合并,放置在临时数组中
        while(i <= divideIndex && j <= high){
            if (arr[i] > arr[j]){
                auxArr[k++] = arr[j++];
            }else{
                auxArr[k++] = arr[i++];
            }
        }
        // 左边还有数据多
        while(i <= divideIndex){
            auxArr[k++] = arr[i++];
        }
        // 右边还有数据多
        while( j <= high ){
            auxArr[k++] = arr[j++];
        }
        // 把临时数组中的放回原数组中
        for(k=0 ,i=low ; i<=high;i++,k++){
            arr[i] = auxArr[k];
        }
    }
    public static void main(String[] args){
        int[] arr =  {94,12,34,76,26,9,0,37,55,76,37,5,68,83,90,37,12,65,76,49};
        MergeSort sort = new MergeSort();
        sort.sort(arr);
        System.out.println(Arrays.toString(arr));
    }
}

六、快速排序

1、基本思想

  1. 选取一个基准值
  2. 比基准值小的放在左边,大的放在右边
  3. 递归

2、动态图

这里写图片描述

3、代码

/*************************************************************************
    > File Name: QuickSort.java
    > Author: 
    > Mail: 
    > Created Time: Thu 22 Mar 2018 04:10:22 PM CST
 ************************************************************************/
import java.util.Arrays;
public class QuickSort{

    public void quickSort(int[] arr){
        sort(arr , 0  , arr.length - 1);
    }

    public void  sort(int[] arr , int low , int high){

         int index;
         if(low < high){
             index = partition(arr , low ,high);
             sort(arr , low , index -1);
             sort(arr , index + 1 , high);
         }
    }

    public int partition(int[] arr , int i ,int j){
        // 保存基准值,留出空位
        int key = arr[i];
        // 两个指针不能有交集
        while(i < j){
            // j指针往前走
            while(i < j && arr[j] >=key){
                j--;
            }
            if(i < j){
                // j所在位置元素不满足条件,那么就放到前面,现在的空位就是j了
                arr[i] = arr[j];
                i++;
            }
            // i指针往后走
            while(i< j && arr[i] <= key){
                i++;
            }
            if(i < j){
                // 
                arr[j] = arr[i];
                j--;
            }
        }
        arr[i] = key;
        return i;
    }

    public static void main(String[] args){
        int[] arr = {3, 4 , 20 ,1,5, 6,15,40,32};
        QuickSort sort = new QuickSort();
        sort.quickSort(arr);
        System.out.println(Arrays.toString(arr));
    }
}

七、堆排序

1、基本思想

  1. 把数组看成是一颗完全二叉树
  2. 最大堆: 父节点总是比子节点大;建堆的过程就是从树的中间开始调整树的结构
  3. 交换首尾元素,从树顶调整树的结构

2、动态图

这里写图片描述

3、代码

/*************************************************************************
    > File Name: HeapSort.java
    > Author: 
    > Mail: 
    > Created Time: Fri 23 Mar 2018 10:50:37 AM CST
 ************************************************************************/
import java.util.Arrays;
public class HeapSort{
    public void sort(int[] arr){
        int tmp ;
        int len = arr.length;
        buildHeap(arr);
        for(int i = 0 ; i < len ; i++){
            //交换第一个元素接最后一个元素 
            tmp = arr[0];
            arr[0] = arr[len - 1 - i];
            arr[len - 1 -i ] = tmp;
            // 因为已经构建好了堆,现在只是调整了一个元素,那么从该元素的位置在进行微调即可
            adjustHeap(arr , 0 , len -1 - i);
        }
    }
    public void buildHeap(int[] arr){
        int pos = (arr.length - 1) / 2;
        // 构建堆,需要从下面往上面进行调整
        for(int j = pos ; j>=0 ; j--){
            adjustHeap(arr , j , arr.length -1 );
        }
    }

    /**
     * pos 待调整节点的索引
     * length 待调整堆节点的数量
     */
    public void adjustHeap(int[] arr , int pos , int length){

        // 初始化左孩子节点索引
        int  i = pos * 2 + 1;
        int tmp;
        // 只要存在左孩子节点,就一直循环
        while(i < length){   
            // 保存父节点,留出空位
            tmp = arr[pos];
            // 如果存在右孩子节点,且比左节点大
            if( i+1 < length && arr[i+1] > arr[i] ){
                i++;
            }
            // 与最大孩子节点进行比较,如果大,就交换一下
            if(arr[i] > arr[pos]){
                arr[pos] = arr[i];
                arr[i] = tmp;
            }else{
                // 这里就是没有做交换,那么就不会在去孩子节点了
                break;
            }
            // 因为交换了,那么孩子节点就存在不满足的情况了,需要更新父节点和孩子节点索引
            pos = i;
            i = 2 * pos + 1;
        }
    }
    public static void main(String[] args){ 
        int[] arr = {10 ,3 ,4,2,30, 20 ,11 ,28 , 18} ;
        HeapSort sort = new HeapSort();
        sort.sort(arr);
        System.out.println(Arrays.toString(arr));
    }
}

八、 桶排序

1、基本思想

2、动态图

3、代码

猜你喜欢

转载自blog.csdn.net/tanliqing2010/article/details/79641840