排序算法

选择排序

选择排序是一种简单直观的排序算法,基本的思想如下:

首先在未排序的序列中找到最小的元素,存放在排序序列的起始位置;

然后在从剩下的未排序的元素中继续寻找最小的元素,放在已排序序列的末尾;

重复执行第二步,知道所有的元素均有序;

具体的实现代码如下所示:

public void sort(int [] a){
      for(int i=0;i<a.length;i++)
      {
            int min=i;
            for(int j=i+1;j<a.length;j++)
            {
                  if(a[j]<a[min])
                        min=j;
            }
            if(i!=min)
            {
                  int temp=a[i];
                  a[i]=a[min];
                  a[min]=temp;
            }
      }
}

冒泡排序

冒泡排序的基本思想是:比较相邻的元素,如果第一个比后面的大,就交换它们;

对每一对相邻元素做同样的工作,从开始第一对到结尾的最后一对,这一步做完之后,最后的元素会是最大的数,然后针对未排序的序列继续上面的操作,直到所有的元素有序;

具体的实现代码如下所示:


public void sort(int [] a){
      for(int i=1;i<a.length;i++)
      {
            for(int j=0;j<a.length-i;j++)
            {
                  if(a[j]>a[j+1])
                  {
                        int temp=a[j];
                        a[j]=a[j+1];
                        a[j+1]=temp;
                  }
            }
      }
}
     

快速排序

快速排序采用的思想是分治思想,基本的步骤是首先找出一个元素作为基准,然后将所有元素进行分区操作,达到基准左边的元素都不大于基准值,基准右边的元素都不小于基准值,这样的操作称为一次快
排,然后进行递归操作,将基准左边的元素进行快排,将基准右边的元素进行快排,最后达到所有元素有序。

我觉得在编码的时候最主要的操作就是编写一遍快排,也就是将比基准小的都放在左边,反之放在右边。具体的代码如下:

int quicksort(vector<int> &v, int left, int right){
        if(left < right){
                int key = v[left];
                int low = left;
                int high = right;
                while(low < high){
                        while(low < high && v[high] >= key){
                                high--;
                        }
                        v[low] = v[high];
                        while(low < high && v[low] < key){
                                low++;
                        }
                        v[high] = v[low];
                }
                v[low] = key;
                quicksort(v,left,low-1);
                quicksort(v,low+1,right);
        }
}

归并排序

归并排序采用的思想也是分治的思想,主要就是将元素分成两个部分,左边进行归并排序,右边进行归并排序,然后将左右两部分进行合并的操作。

编码的时候主要的部分还是合并的操作,主要的代码如下所示:

public class Merge {
    // 不要在 merge 函数里构造新数组了,因为 merge 函数会被多次调用,影响性能
    // 直接一次性构造一个足够大的数组,简洁,高效
    private static Comparable[] aux;

     public static void sort(Comparable[] a) {
        aux = new Comparable[a.length];
        sort(a, 0, a.length - 1);
    }

    private static void sort(Comparable[] a, int lo, int hi) {
        if (lo >= hi) return;
        int mid = lo + (hi - lo) / 2;
        sort(a, lo, mid);
        sort(a, mid + 1, hi);
        merge(a, lo, mid, hi);
    }

    private static void merge(Comparable[] a, int lo, int mid, int hi) {
        int i = lo, j = mid + 1;
        for (int k = lo; k <= hi; k++)
            aux[k] = a[k];
        for (int k = lo; k <= hi; k++) {
            if      (i > mid)              { a[k] = aux[j++]; }
            else if (j > hi)               { a[k] = aux[i++]; }
            else if (less(aux[j], aux[i])) { a[k] = aux[j++]; }
            else                           { a[k] = aux[i++]; }
        }
    }

    private static boolean less(Comparable v, Comparable w) {
        return v.compareTo(w) < 0;
    }
}
posted @ 2020-08-30 18:56  万物小白  阅读(93)  评论(0编辑  收藏  举报