【algorithm】排序算法

来源:互联网 发布:东华软件薛向东 编辑:程序博客网 时间:2024/05/21 20:22

交换排序

  • |–冒泡排序
    • |–快速排序
  • 插入排序
    • |–直接插入排序
    • |–希尔排序
  • 选择排序
    • |–简单选择排序
    • |–堆排序
  • 归并排序
  • 基数排序

这里写图片描述

稳定排序:假设在待排序的文件中,存在了两个或两个以上的记录具有相同的关键字,在某种排序算法排序后,若这些相同关键字的元素的相对次序依然不变,则这种排序方法是稳定的。

  • 稳定:冒泡、插入、归并、基数
  • 不稳定:选择、快速、希尔、堆
public static void main(String[] args) {    int[] arr = {3,9,7,6,8,4,5,10,2,1};    for (int i : arr) {        System.out.print(i+" ");    }    System.out.println();    //bubbleSort(arr);    //quickSort(arr, 0, arr.length-1);    //insertSort(arr);    //shellSort(arr);    //selectSort(arr);    heapSort(arr, arr.length);    //int[] merge = new int[10];    //mergeSort(arr, merge, 0, arr.length-1);    //basketSort(arr);    for (int i : arr) {        System.out.print(i+" ");    }    System.out.println();}public static void swap(int[] arr,int i,int j){    int temp = arr[i];    arr[i] = arr[j];    arr[j] = temp;}

冒泡

/*冒泡排序最好时间复杂度 o(n),最坏时间复杂度o(n^2),平均o(n^2),稳定*/public static void bubbleSort(int[] arr){    if (arr == null || arr.length == 0) {        return;    }    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);            }        }    }}

每趟排序结果:

 start : 3 9 7 6 8 4 5 10 2 1 process: 3 7 6 8 4 5 9 2 1 10 process: 3 6 7 4 5 8 2 1 9 10 process: 3 6 4 5 7 2 1 8 9 10 process: 3 4 5 6 2 1 7 8 9 10 process: 3 4 5 2 1 6 7 8 9 10 process: 3 4 2 1 5 6 7 8 9 10 process: 3 2 1 4 5 6 7 8 9 10 process: 2 1 3 4 5 6 7 8 9 10 process: 1 2 3 4 5 6 7 8 9 10   end  : 1 2 3 4 5 6 7 8 9 10 

快排

/* * 快速排序 * 最好时间复杂度 o(nlog(2)n),最坏时间复杂度o(n^2),平均o(n^2),不稳定 */public static void quickSort(int[] arr,int left,int right){  //左边索引小于右边,则还未排序完成    if (left < right) {    //取中间的元素作为比较基准,小于他的往左边移,大于他的往右边移     int mid = arr[(left+right)/2];    int i = left - 1;    int j = right + 1;    while (true) {      //移动下标,左边的往右移动,右边的向左移动      while(arr[++i] < mid && i < right);      while(arr[--j] > mid && j > left);      if (i >= j) break;      swap(arr, i, j);    }    quickSort(arr, left, i-1);    quickSort(arr, j+1, right);  }}

每趟排序结果:

 start : 3 9 7 6 8 4 5 10 2 1 process: 3 1 7 6 2 4 5 10 8 9 process: 3 1 5 4 2 6 7 10 8 9 process: 3 1 2 4 5 6 7 10 8 9 process: 1 3 2 4 5 6 7 10 8 9 process: 1 2 3 4 5 6 7 10 8 9 process: 1 2 3 4 5 6 7 10 8 9 process: 1 2 3 4 5 6 7 10 8 9 process: 1 2 3 4 5 6 7 8 10 9 process: 1 2 3 4 5 6 7 8 9 10   end  : 1 2 3 4 5 6 7 8 9 10 

插入排序

/* * 直接插入排序 * 最好时间复杂度o(1),最坏时间复杂度o(n^2),平均o(n^2),稳定 */public static void insertSort(int[] arr){  //直接插入排序是将待比较的数值与它的前一个数值进行比较,所以外层循环是从第二个数值开始的  for (int i = 1; i < arr.length; i++) {    if (arr[i] < arr[i-1]) {      //用一个变量来保存当前待比较的数值,因为当一趟比较完成时,我们要将待比较数值置入比它小的数值的后一位       int temp = arr[i];      int j = 0;      for(j = i-1;j >= 0 && temp < arr[j];j--)        arr[j+1] = arr[j];      arr[j+1] = temp;    }  }}

每趟排序结果:

 start : 3 9 7 6 8 4 5 10 2 1 process: 3 9 7 6 8 4 5 10 2 1 process: 3 7 9 6 8 4 5 10 2 1 process: 3 6 7 9 8 4 5 10 2 1 process: 3 6 7 8 9 4 5 10 2 1 process: 3 4 6 7 8 9 5 10 2 1 process: 3 4 5 6 7 8 9 10 2 1 process: 3 4 5 6 7 8 9 10 2 1 process: 2 3 4 5 6 7 8 9 10 1 process: 1 2 3 4 5 6 7 8 9 10   end  : 1 2 3 4 5 6 7 8 9 10 

希尔排序

 /* *  * 希尔排序  * 最好时间复杂度o(n),最坏时间复杂度o(n^2),平均o(n^1.3),不稳定  */    public static void shellSort(int[] arr){        int len = arr.length;        for (int h = len/2; h > 0; h = h / 2) {            for(int i = h; i < len; i++){                for (int j = i-h; j > 0 && arr[j] > arr[j + h]; j -= h) {                    swap(arr, j, j + h);                }            }        }    }

每趟排序之后:

 start : 3 9 7 6 8 4 5 10 2 1 process: 3 5 7 2 1 4 9 10 6 8 process: 3 2 1 4 6 5 7 8 9 10 process: 3 1 2 4 5 6 7 8 9 10   end  : 3 1 2 4 5 6 7 8 9 10 

选择排序

/* * 简单选择排序 * 最好时间复杂度o(n^2),最坏时间复杂度o(n^2),平均o(n^2),不稳定 */public static void selectSort(int[] arr){  int min = 0;  for (int i = 0; i < arr.length; i++) {    min = i;    for (int j = i + 1; j < arr.length; j++) {      if (arr[min] > arr[j]) {        min = j;      }    }    if (min != i) {      swap(arr, min, i);    }  }}

每趟排序之后:

 start : 3 9 7 6 8 4 5 10 2 1 process: 1 9 7 6 8 4 5 10 2 3 process: 1 2 7 6 8 4 5 10 9 3 process: 1 2 3 6 8 4 5 10 9 7 process: 1 2 3 4 8 6 5 10 9 7 process: 1 2 3 4 5 6 8 10 9 7 process: 1 2 3 4 5 6 8 10 9 7 process: 1 2 3 4 5 6 7 10 9 8 process: 1 2 3 4 5 6 7 8 9 10 process: 1 2 3 4 5 6 7 8 9 10 process: 1 2 3 4 5 6 7 8 9 10   end  : 1 2 3 4 5 6 7 8 9 10 

堆排序

/* * 堆排序  */public static void heapSort(int[] arr,int top){  //建一个初始的大根堆  for (int i = arr.length / 2 - 1; i >= 0; i--) {    heapAdjust(arr,i,arr.length);  }  for (int i = 0; i < arr.length; i++) {        System.out.print(arr[i] + "  ");  }  System.out.println();  for (int i = arr.length - 1; i >= arr.length - top; i--){    swap(arr, 0, i);    heapAdjust(arr, 0, i);  }}private static void heapAdjust(int[] arr,int parent,int len){  int temp = arr[parent];  //左结点  int child = 2*parent + 1;  while (child < len) {    //找出两个子结点中较大的一个    if (child + 1 < len && arr[child] < arr[child + 1])       child++;    //如果父节点大于子结点中较大的一个,退出。    if(temp >= arr[child]) break;    //将比子结点大的值赋值给父结点    arr[parent] = arr[child];    parent = child;    child = 2 * parent + 1;  }  arr[parent] = temp;}

每趟排序之后:

 start : 3 9 7 6 8 4 5 10 2 1 initheap:10 9 7 6 8 4 5 3 2 1  process: 9 8 7 6 1 4 5 3 2 10 process: 8 6 7 3 1 4 5 2 9 10 process: 7 6 5 3 1 4 2 8 9 10 process: 6 3 5 2 1 4 7 8 9 10 process: 5 3 4 2 1 6 7 8 9 10 process: 4 3 1 2 5 6 7 8 9 10 process: 3 2 1 4 5 6 7 8 9 10 process: 2 1 3 4 5 6 7 8 9 10 process: 1 2 3 4 5 6 7 8 9 10 process: 1 2 3 4 5 6 7 8 9 10   end  : 1 2 3 4 5 6 7 8 9 10 

归并排序

/* * 归并排序 * 算法规则: * 1.申请空间,使其大小为两个已经排序序列之和,该空间用来存放合并后的序列 * 2.设定两个指针,最初位置分别为两个已经排序序列的起始位置  * 3.比较两个指针所指向的元素,选择相对小的元素放入到合并空间,并移动指针到下一位置  * 4.重复步骤3直到某一指针到达序列尾  * 5.将另一序列剩下的所有元素直接复制到合并序列尾 */public static void mergeSort(int[] arr,int[] merge,int first,int last){  if (first >= last) return;  int mid = (last + first) >> 1;  mergeSort(arr, merge, first, mid);  mergeSort(arr, merge, mid + 1, last);  merger(arr, merge, first,last,mid);}private static void merger(int[] arr, int[] merge, int first, int last,int mid) {  System.out.print("first:"+first+",last:"+last+",mid:"+mid+" : ");  int i = first;  int j = mid+1;  int pos = first;  while( i <= mid || j <= last ){    if( i > mid ){      while( j <= last ) merge[pos++] = arr[j++];      break;    }    if( j > last ){      while( i <= mid ) merge[pos++] = arr[i++];      break;    }    //等于小的    merge[pos++] = arr[i] >= arr[j] ? arr[j++] : arr[i++];  }  for (pos = first; pos <= last; pos++){    arr[pos] = merge[pos];    System.out.print(arr[pos]+" ");  }  System.out.println();}

每趟排序之后:

 start : 3 9 7 6 8 4 5 10 2 1 first:0,last:1,mid:0 : 3 9 process: 3 9 7 6 8 4 5 10 2 1 first:0,last:2,mid:1 : 3 7 9 process: 3 7 9 6 8 4 5 10 2 1 first:3,last:4,mid:3 : 6 8 process: 3 7 9 6 8 4 5 10 2 1 first:0,last:4,mid:2 : 3 6 7 8 9 process: 3 6 7 8 9 4 5 10 2 1 first:5,last:6,mid:5 : 4 5 process: 3 6 7 8 9 4 5 10 2 1 first:5,last:7,mid:6 : 4 5 10 process: 3 6 7 8 9 4 5 10 2 1 first:8,last:9,mid:8 : 1 2 process: 3 6 7 8 9 4 5 10 1 2 first:5,last:9,mid:7 : 1 2 4 5 10 process: 3 6 7 8 9 1 2 4 5 10 first:0,last:9,mid:4 : 1 2 3 4 5 6 7 8 9 10 process: 1 2 3 4 5 6 7 8 9 10   end  : 1 2 3 4 5 6 7 8 9 10 

基数排序

/* * 基数排序(桶排序) */public static void basketSort(int arr[])//arr为待排序数组{  int len=arr.length;  int bask[][]=new int[10][len];  int index[]=new int[10];  int max=Integer.MIN_VALUE;  System.out.println(max);  //找到数组中长度最大的数的长度 max  for(int i=0;i<len;i++){    max=max>(Integer.toString(arr[i]).length())?max:(Integer.toString(arr[i]).length());  }  String str;  //先将长度相同的元素放在一起,并且按照长度进行排序  //然后将长度相同的元素排序。  for(int i=max-1;i>=0;i--){    for(int j=0;j<len;j++){      str="";      //如果数组有的元素的长度小于最大长度,补0      if(Integer.toString(arr[j]).length()<max){        for(int k=0;k<max-Integer.toString(arr[j]).length();k++)          str+="0";      }      str+=Integer.toString(arr[j]);      bask[str.charAt(i)-'0'][index[str.charAt(i)-'0']++]=arr[j];    }    int pos=0;    for(int j=0;j<10;j++)    {      for(int k=0;k<index[j];k++)      {        arr[pos++]=bask[j][k];      }    }    for(int x=0;x<10;x++)      index[x]=0;  }}

每趟排序之后:

 start : 3 9 7 6 8 4 5 10 2 1 process: 10 1 2 3 4 5 6 7 8 9 process: 1 2 3 4 5 6 7 8 9 10   end  : 1 2 3 4 5 6 7 8 9 10 
原创粉丝点击