您的位置:首页 > 编程语言 > Java开发

java中各种常用排序实现(直接插入排序、直接选择排序、堆排序、冒泡排序、快速排序和归并排序)

2014-08-28 23:19 986 查看

package com.sort;

import java.io.BufferedReader;

import java.io.InputStreamReader;

/**

 * 各种排序,包含插入排序、选择排序、交换排序和归并排序

 * 插入排序:直接插入排序和希尔排序

 * 选择排序:直接选择排序和堆排序

 * 交换排序:冒泡排序和快速排序

 * 归并排序:

 * @author msk

 *

 */

public class Sort {

 public static void main(String[] args) {

  

  BufferedReader br;

  int i;

  try {

   Object[] a = {5,4,3,2,1};

   br = new BufferedReader(new InputStreamReader(System.in));

   while(true){

    i = select(br);    

     switch(i){

     case 1:

      insertSort(a);

      break;

     case 2:

      selectSort(a);

      break;

     case 3:

      heapSort(a);

      break;

     case 4:

      bubbleSort(a);

      break;

     case 5:

      quickSort(a);

      break;

     case 6:

      mergeSort(a);

      break;

     case 7:

       System.out.println("退出程序!");

       System.exit(1);

     default:

       System.out.println("输入出错,退出程序!");

       System.exit(1);

     }

    }

  } catch (Exception e) {

   System.out.println("操作异常!" + e);

  }

 }

 

 public static int select(BufferedReader f){  

  System.out.println("\n输入编号选择排序方式:");

  System.out.println("1:进行直接插入排序;");

  System.out.println("2:进行直接选择排序;");

  System.out.println("3:堆排序;");

  System.out.println("4:冒泡排序;");

  System.out.println("5:快速排序;");

  System.out.println("6:归并排序;");

  System.out.println("7:退出运行。\n");

  System.out.print("请输入您的选择:");

  try {

   String s = f.readLine();

   int n = Integer.parseInt(s);

   while(n < 0 || n > 7){    

    System.out.println("输入数字有误!重输:");

    s = f.readLine();

    n = Integer.parseInt(s);

   }

   System.out.println();

   return n;

  } catch (Exception e) {

   System.out.println("操作异常!" + e);

   return 0;

  } 

 }

 

 /***************直接插入排序*****************/

 public static void insertSort(Object[] a){  //时间复杂度为O(n^2),空间复杂度为O(1),稳定排序

  

  for(int i = 1; i < a.length; i ++){

   for(int j = i; j > 0; j --){

    if(((Comparable)a[j]).compareTo(a[j - 1]) < 0){     

     Object temp = a[j];

     a[j] = a[j - 1];

     a[j - 1] = temp;

    }

   }

  }

  System.out.println("直接插入排序结果为:");

  for(int i = 0; i < a.length; i ++)

   System.out.print(a[i] + " ");

  System.out.println();

  System.out.println("它的时间复杂度:平均情况为O(n^2),最好情况为O(n),最坏情况为O(n^2)");

  System.out.println("空间复杂度为O(1)");

  System.out.println("属于稳定排序");

 }

 

 /********************直接选择排序**************************/

 public static void selectSort(Object[] a){  //时间复杂度为O(n^2),空间复杂度为,不稳定排序

  

  for(int i = 0; i < a.length; i ++){

   for(int j = i + 1; j < a.length; j ++){

    if(((Comparable)a[i]).compareTo(a[j]) > 0){    

     Object temp = a[i];

     a[i] = a[j];

     a[j] = temp;

    }

   }

  }

  System.out.println("直接选择排序结果为:");

  for(int i = 0; i < a.length; i ++)

   System.out.print(a[i] + " ");

  System.out.println();

  System.out.println("它的时间复杂度:平均情况为O(n^2),最好情况为O(n^2),最坏情况为O(n^2)");

  System.out.println("空间复杂度为O(1)");

  System.out.println("属于不稳定排序");

 }

 

 /********************堆排序开始*********************/

 public static void sift(Object[] a, int n, int i){  //对a[i]进行筛运算,称为构成堆的过程

  

  Object x = a[i]; //把待筛结点的值暂存于x中

  int j = 2 * i + 1; //a[j]是a[i]的左孩子

  while(j <= n - 1){ //当a[i]的左孩子不为空时执行循环   

   if(j < n - 1 && ((Comparable)a[j]).compareTo(a[j + 1]) < 0)

    j ++; //若存在右孩子并排序码较大,则把j修改为右孩子的下标

   if(((Comparable)x).compareTo(a[j]) < 0){    

    a[i] = a[j]; //把a[j]调到双亲位置

    i = j;j = 2 * i + 1; //修改i和j的值,以便继续向下筛

   }

   else break;  //查找到x的最终位置为i,退出循环

  }

  a[i] = x;

 }

 

 public static void heapSort(Object[] a){ //利用堆排序的方法对数组a中的n个元素进行排序,时间复杂度为O(n^2),O(nlog2n),空间复杂度为O(1)  

  for(int i = a.length / 2 - 1; i >= 0; i --)

   sift(a, a.length, i);

  for(int i = 1; i <= a.length - 1; i ++){  //进行n-1次循环完成堆排序

   //将树根结点的值同当前区间内最后一个结点的值对换

   Object x = a[0];

   a[0] = a[a.length - i];

   a[a.length - i] = x;

   //筛a[0]结点,得到前n-1个结点的堆

   sift(a,a.length - i,0);

  }

  System.out.println("堆排序结果为:");

  for(int i = 0; i < a.length; i ++)

   System.out.print(a[i] + " ");

  System.out.println();

  System.out.println("它的时间复杂度:平均情况为O(nlogn),最好情况为O(nlogn),最坏情况为O(nlogn)");

  System.out.println("空间复杂度为O(1)");

  System.out.println("属于不稳定排序");

 }

 /********************堆排序结束*********************/

 

 /********************冒泡排序*********************/

 public static void bubbleSort(Object[] a){  

  for(int i = 1; i < a.length;i ++){

   for(int j = a.length - 1; j >=i; j --){    

    if(((Comparable)a[j]).compareTo(a[j - 1]) < 0){     

     Object x = a[j];

     a[j] = a[j - 1];

     a[j - 1] = x;

    }

   }  

  }

  System.out.println("冒泡排序结果为:");

  for(int i = 0; i < a.length; i ++)

   System.out.print(a[i] + " ");

  System.out.println();

  System.out.println("它的时间复杂度:平均情况为O(n^2),最好情况为O(n),最坏情况为O(n^2)");

  System.out.println("空间复杂度为O(1)");

  System.out.println("属于稳定排序");

 }

 

 /********************快速排序开始***************************/

 public static int partition(Object[] a,int s, int t){ // 进行快速排序中完成一次划分排序的算法描述  

  int i = s,j = t;

  Object x = a[i ++];

  while(i <= j){   

   //从前向后顺序查找一个大于基准值需向后半区间交换的元素

   while(i <= j && ((Comparable)a[i]).compareTo(x) <= 0) i ++;

   //从后向前顺序查找一个小于基准值需向前半区间交换的元素

   while(j >= i && ((Comparable)a[j]).compareTo(x) >= 0) j --;

   //当条件成立时交换a[i]和a[j]的值

   if(i < j){    

    Object temp = a[i];

    a[i] = a[j];

    a[j] = temp;

    i ++; j --;

   }

  }

  a[s] = a[j]; a[j] = x; //交换a[s]和a[j]的值,得到前后两个子区间

  return j;

 }

  

 public static void quickRecursion(Object[] a, int s, int t){ //通过调用partition算法进行快速排序的递归算法描述  

  int j = partition(a, s, t);

  if(s < j - 1) quickRecursion(a, s, j - 1); //在左区间内超过一个元素时递归排序左区间

  if(t > j + 1) quickRecursion(a, j + 1, t); //在右区间超过一个元素时递归排序右区间

 }

 

 public static void quickSort(Object[] a){

  //对数组a[0]到a[n - 1]进行快速排序

  quickRecursion(a, 0, a.length - 1);

  System.out.println("快速排序结果为:");

  for(int i = 0; i < a.length; i ++)

   System.out.print(a[i] + " ");

  System.out.println();

  System.out.println("它的时间复杂度:平均情况为O(nlogn),最好情况为O(nlogn),最坏情况为O(n^2)");

  System.out.println("空间复杂度为O(nlogn)");

  System.out.println("属于不稳定排序");

 }

 /*************************快速排序结束*************************/

 

 /***********************归并排序开始************************/

 public static void twoMerge(Object[] a, Object[] r, int s, int m, int t){ //二路归并算法描述

  //把相邻有序表a[s]~a[m]和a[m+1]~a[t]归并为一个有序表r[s]~r[t]

  int i,j,k;

  //分别给指示每个有序表元素位置的指针赋初值

  i = s;

  j = m + 1;

  k = s;

  //两个有序表中同时存在未归并元素时的处理过程

  while(i <= m && j <= t)   

   if(((Comparable)a[i]).compareTo(a[j]) <= 0){

    r[k] = a[i];

    i ++; k ++;    

   }

   else{

    r[k] = a[j];

    j ++; k ++;

   }

  //对第一个有序表中可能存在的未归并元素进行处理

  while(i <= m){

   r[k] = a[i];

   i ++; k++;

  } 

  //对第二个有序表中可能存在的未归并元素进行处理

  while(j <= t){

   r[k] = a[j];

   j ++; k ++;

  }

 }

 

 public static void mergePass(Object[] a, Object[] r, int n, int len){  //进行一趟二路归并的算法描述

  //把数组a
中每个长度为len的有序表两两归并到数组r


  int p = 0;  //p为每一对待合并表的第一个元素的下标,初值为0

  while(p + 2 * len - 1 <= n - 1){ //两两归并长度为len的有序表

   twoMerge(a, r, p, p + len - 1, p + 2 * len - 1);

   p += 2 * len;  

  }

  if(p + len - 1 < n - 1)  //归并最后两个长度不等的有序表

   twoMerge(a, r, p, p + len - 1, n - 1);

  else      //把剩下的最后一个有序表复制到r中

   for(int i = p; i <= n - 1; i ++) 

    r[i] = a[i];

 }

 

 public static void mergeSort(Object[] a){

  //采用归并排序的方法对数组a中的n个记录进行排序

  Object[] r = new Object[a.length];

  int len = 1;

  while(len < a.length){

   //从a归并到r中,得到每个有序表的长度为2*len

   mergePass(a, r, a.length, len);

   //修改len的值为r中的每个有序表的长度

   len *= 2;

   //从r归并到a中,得到每个有序表的长度为2*len

   mergePass(r, a, a.length, len);

   //修改len的值为a中的每个有序表的长度

   len *= 2;

  }

  System.out.println("归并排序结果为:");

  for(int i = 0; i < a.length; i ++)

   System.out.print(a[i] + " ");

  System.out.println();

  System.out.println("它的时间复杂度:平均情况为O(nlogn),最好情况为O(nlogn),最坏情况为O(n^2)");

  System.out.println("空间复杂度为O(1)");

  System.out.println("属于稳定排序");

 }

 /***********************归并排序结束************************/

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  java
相关文章推荐