排序(java)

目录

一.普通排序法

1.冒泡排序(交换排序)

2.直接插入排序

3.选择排序

二.较为高级的排序法

1.希尔排序(属于插入排序)

2.归并排序

3.快速排序(属于交换排序)

4.堆排序(属于选择排序)


一.普通排序法

1.冒泡排序(交换排序)

  在无序区间,通过相邻数的比较,将最大的数冒泡到无序区间的最后,持续这个过程,直到数组整体有序

   时间复杂度:O(n^2)  ,具有稳定性。

动态效果:排序(冒泡排序,选择排序,插入排序,归并排序,快速排序,计数排序,基数排序) - VisuAlgo

代码如下: 

public class BubbleSort {
    // 具有稳定性  时间复杂度O(n^2)
    public void Sort(int[] array){
        for (int i = 0; i < array.length-1; i++) {   //元素n个 ,就循环n-1个 选择
               boolean sorted = true;
            for (int j = 0; j < array.length-i-1; j++) {  // 排序
                if(array[j]>array[j+1]){
                    swap(array,j,j+1);
                    sorted = false;
                }
            }
            if(sorted){
                return;
            }
        }
    }

    private void swap(int[] array, int j, int i) {
        int e = array[i];
        array[i] =array[j];
        array[j]  = e;
    }

2.直接插入排序

 整个区间被分为

1. 有序区间

2. 无序区间

每次选择无序区间的第一个元素,在有序区间内选择合适的位置插入.(具备稳定性 ,时间复杂度:O(n^2)-> 平均)

代码如下:

public class InsertSort {
    public void Sort(int[] array){
        for (int i = 0; i < array.length-1; i++) {
          int e = array[i+1];
          int j ;
          for(j =i;j>=0 && array[j]> e;j--){
              array[j+1] =array[j];
          }
            array[j] = e;
        }

    }
}

3.选择排序

   每一次从无序区间选出最大(或最小)的一个元素,存放在无序区间的最后(或最前),直到全部待排 序的数据元素排完 。
  时间复杂度:O(n^2)  , 不具备稳定性。

代码如下:

 public void selectSort(long[] array) {
        for (int i = 0; i < array.length - 1; i++) {
            int maxIdx = 0;
            for (int j = 1; j < array.length - i; j++) {
                if (array[j] > array[maxIdx]) {
                    maxIdx = j;
                }
            }

            if (maxIdx != array.length - i - 1) {
                 swap(array, maxIdx, array.length - i - 1);
            }
        }
    }

 private void swap(int[] array, int j, int i) {
        int e = array[i];
        array[i] =array[j];
        array[j]  = e;
    }

二.较为高级的排序法

1.希尔排序(属于插入排序)

  时间复杂度:O(n*1.3) ,不具备稳定性。

原理:

  希尔排序法又称缩小增量法。希尔排序法的基本思想是:先选定一个整数(n),把待排序文件中所有记录分成个组,所有距离为 n  的记录分在同一组内,并对每一组内的记录进行排序。然后,取,重复上述分组和 排序的工作。当到达=1 时,所有记录在统一组内排好序。
1. 希尔排序是对直接插入排序的优化。
2. gap > 1 时都是预排序,目的是让数组更接近于有序。当 gap == 1 时,数组已经接近有序的了, 这样就会很快。这样整体而言,可以达到优化的效果。我们实现后可以进行性能测试的对比。
 public void shellSort(long[] array) {
        for (int g = array.length / 2; g > 1; g = g / 2) {
            insertSortWithGap(array, g);
        }

        insertSortWithGap(array, 1);
    }

    private void insertSortWithGap(long[] array, int g) {
        for (int i = 0; i < array.length - g; i++) {
            long key = array[i + g];
            int j;
            for (j = i; j >= 0 && array[j] > key; j = j - g) {
                array[j + g] = array[j];
            }

            array[j + g] = key;
        }
    }

2.归并排序

 原理 :合并两个有序数组

时间复杂度:O(n* log(n)) , 具备稳定性。

代码如下:

private void RangeSort(long[] array, int from, int to) {
        int size = to - from;
        if (size <= 1) {
            return;
        }

        int mid = from + (size / 2);
        sortRange(array, from, mid);
        sortRange(array, mid, to);

        merge(array, from, mid, to);
    }

    private void merge(long[] array, int from, int mid, int to) {
        int size = to - from;
        int left = from;
        int right = mid;
        int dest = 0;

        long[] other = new long[size];

        while (left < mid && right < to) {
            if (array[left] <= array[right]) {
                other[dest++] = array[left++];
            } else {
                other[dest++] = array[right++];
            }
        }

        while (left < mid) {
            other[dest++] = array[left++];
        }

        while (right < to) {
            other[dest++] = array[right++];
        }

        for (int i = 0; i < size; i++) {
            array[from + i] = other[i];
        }
    }

3.快速排序(属于交换排序)

 原理 - 总览
  
1. 从待排序区间选择一个数,作为基准值 (pivot)
2. Partition: 遍历整个待排序区间,将比基准值小的(可以包含相等的)放到基准值的左边,将比基
准值大的(可以包含相等的)放到基准值的右边;
3. 采用分治思想,对左右两个小区间按照同样的方式处理,直到小区间的长度 == 1 ,代表已经有序, 或者小区间的长度 == 0 ,代表没有数据。
 时间复杂度:O(n*log(n)) ,不具备稳定性

代码如下:

 public void SortQuilk(long[] array,int from,int to){
        if(to-from<=0){
            return;
        }
        int pi = PartitionMethodC(array,from,to);
        SortQuilk(array,from,pi-1);
        SortQuilk(array,pi+1,to);

    }
private int PartitionMethodC(long[] array,int from,int to){
        int s= from;
        long pivot = array[to];
    for (int i = from; i < to; i++) {
        if(array[i] <pivot){
            long t =array[i];
            array[i] = array[s];
            array[s] = t;

            s++;
        }
    }
      array[to]  = array[s];
      array[s] = pivot;
      return s;
}

4.堆排序(属于选择排序)

时间复杂度:O(n*log(n))  ,不具备稳定性。

原理:

    基本原理也是选择排序,只是不在使用遍历的方式查找无序区间的最大的数,而是通过堆来选择无序区间的最大的数。
注意: 排升序要建大堆;排降序要建小堆。

代码如下:


  //  堆排序就是 建堆后 ,将第一个最大的元素和最后一个元素交换,后向下调整后,重复循环
    public void Sort(long[] array){
        createHeap(array);
        for (int i = 0; i < array.length-1; i++) {
            swap(array,0,array.length-1-i);
            shiftDown(array,array.length-1-i,0);
        }
    }
    // 建堆
    public void createHeap(long[] array){
        for(int i = (array.length-2)/2;i>=0;i--){
            shiftDown(array,array.length,i);
        }
    }

    private void shiftDown(long[] array, int size, int index) {
        // TODO: 2022/3/17 向下调整,构建大堆  index > maxIdex
          while(index*2+1<size){
            int maxIdex = index*2+1;
            int right = index*2+2;
            if(right<size && array[right]>array[maxIdex]){
                maxIdex =right;
            }
             if(array[index]<array[maxIdex]){
                 swap(array,index,maxIdex);
             }
             index = maxIdex;
        }
    }

    

动态效果数据结构和算法动态可视化 (Chinese) - VisuAlgoVisuAlgo was conceptualised in 2011 by Dr Steven Halim as a tool to help his students better understand data structures and algorithms, by allowing them to learn the basics on their own and at their own pace. Together with his students from the National University of Singapore, a series of visualizations were developed and consolidated, from simple sorting algorithms to complex graph data structures. Though specifically designed for the use of NUS students taking various data structure and algorithm classes (CS1010/equivalent, CS2040/equivalent, CS3230, CS3233, and CS4234), as advocators of online learning, we hope that curious minds around the world will find these visualizations useful as well.https://visualgo.net/zh

评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值