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



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[n]中每个长度为len的有序表两两归并到数组r[n]中
  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("属于稳定排序");
 }
 /***********************归并排序结束************************/
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值