简单排序算法

来源:互联网 发布:ajax json servlet 编辑:程序博客网 时间:2024/04/29 00:34
package com.shine.sort;
/**
 * 排序算法   <br>
 * @说明:<br>
 *     排序算法分为三种:插入排序、交换排序、选择排序   <br>
 *     1.插入排序:直接插入排序、折半插入排序、希尔排序  <br>
 *     2.交换排序:冒泡排序、快速排序     <br>
 *     3.选择排序: 直接选择排序、堆排序  <br>
 */
public class MySort {


/**
* 直接插入排序<br>
* @描述:<br>
*        1. 直接插入排序是第i趟把第i个元素放的前面已经排好序的序列中去<br>
*        2. 重复上述操作。n个元素共需n-1趟扫描,每趟将一个元素插入到它前面的子序列中 <br>
* @复杂度分析:<br>
*     1.时间复杂度:<br> 
*        最好情况:当数据序列已排序,时间复杂度为o(n) <br>
*        最坏情况:数据序列反序,时间复杂度为o(n*n) <br>
*        随机:o(n*n)  <br>
*     2.空间复杂度:o(1)   <br>    
* @稳定性:稳定    
*/
public static void insertSort(int[] table){
for(int i=1;i<table.length;i++){//n-1趟扫描
int temp=table[i],j;//每趟将table[i]插入到前面排序序列中
for(j=i-1;j>=0&&temp<table[j];j--)
table[j+1]=table[j];//将较大元素向后移动
table[j+1]=temp;//temp到达插入位置
}
}
/**
* 希尔排序 <br>
* @描述: <br>
*      1.将一个数据序列分成若干组,每组由若干相隔一段距离的元素组成,这段距离称为增量,
*        在一组内采用直接插入排序算法进行排序       <br>
*      2.当增量为1时,只有一组,元素是整个序列,再进行一次直接插入排序即可     <br>
* @复杂度分析:
*      1.时间复杂度:时间复杂度比较复杂,具体时间取决于具体增量的序列   <br>
*      2.空间复杂度:o(1)
* @稳定性:不稳定 
*/
public static void shellSort(int[] table){
for(int delta=table.length/2;delta>0;delta/=2)//进行若干趟扫描,控制增量,增量减半
for(int i=delta;i<table.length;i++){//一趟分若干组,每组进行直接插入排序
int temp=table[i],j;
for(j=i-delta;j>=0&&temp<table[j];j-=delta)
table[j+delta] = table[j];
table[j+delta] = temp;
}
}
/**
* 冒泡排序 <br>
* @说明: <br>
*    比较两个相邻元素的关键值,如果反序,则交换。若按升序排序,每一趟将被扫描的数据序列中的最大元素交换到
*    最后位置,就像气泡从水里冒出一样。  <br>
* @复杂度分析:<br>
*    1.时间复杂度分析:o(n)-o(n*n)
*    2.空间复杂度分析:o(1)
* @稳定性:稳定  
*/
public static void bubleSort(int[] table){
boolean exchange = true;
for(int i=1;i<table.length&&exchange;i++){//有交换时才进行下一趟排序
exchange = false;//假定元素没有交换
for(int j=0;j<table.length-i;j++)
if(table[j]>table[j+1]){
int temp = table[j];
table[j] = table[j+1];
table[j+1] = temp;
exchange = true;
}
}
}
/**
* 快速排序算法  <br>
* @说明: <br>
* 在数据序列中选择一个值作为比较的基准值,每趟从数据序列的两端开始交替进行,将小于基准值的元素交换到序列
*      前段,大于基准值的元素交换到序列后端,介于两者之间的位置则称为基准值的最终位置。同时序列被划分成两个子
*      序列,在用同样的方法对两个子序列进行排序,直到子序列长度为1,则完成排序。
* @复杂度分析:  <br>
*      时间复杂度:<br>
*          最好情况:每趟排序将序列分成长度相近的两个子序列。   o(nlog2n)     <br>
*          最坏情况:每趟排序将序列分成长度差异很大的两个子序列   o(n*n)      <br>
*      空间复杂度:<br>
*       最好情况:  o(log2n)
*          最坏情况:  o(n)
* @稳定性:不稳定<br>
*/
   public static void quickSort(int[] table){
  quickSort(table,0,table.length-1);
   }
   private static void quickSort(int[] table,int begin,int end){
  if(begin<end){
  int i=begin,j=end;
  int vot=table[i];//基准值
  while(i!=j){//一趟排序
  while(i<j&&vot<=table[j])
  j--;
  if(i<j)//如果有小元素(当有table[j]<vot的时候,该条件恒成立)
  table[i++]=table[j];//把后面的小元素向前移动
  while(i<j&&table[i]<=vot)
  i++;
  if(i<j)
  table[j--]=table[i];//把大元素向后移动
  }
  table[i]=vot;//基准值到达最终位置
  quickSort(table,begin,j-1);//前段子序列进行排序
  quickSort(table,i+1,end);//后端子序列进行排序
  }
   }
   /**
    * 直接选择排序   <br>
    * @说明:<br>
    * 第一趟从n个元素的数据中选出关键字最小或最大的元素放到最前或最后位置,下一趟再从n-1个元素……。直接选择排序
    *       算法可用顺序表和单链表实现。   <br>
    * @复杂度:   <br>
    *       时间复杂度:o(n*n) <br>
    *       空间复杂度:o(1) <br>
    * @稳定性:不稳定 <br>
    */
   public static void selectSort(int[] table){
  for(int i=0;i<table.length-1;i++){
  int min=i;
  for(int j=i+1;j<table.length;j++)
  if(table[j]<table[min])
  min=j;
  if(min!=i){
  int temp=table[i];
  table[i]=table[min];
  table[min]=temp;
  }
  }
   }
   /**
    * 堆排序
    * @说明: <br>
    * 1.堆:这里的堆不是数据结构里面的堆栈,而是一种数据结构。堆可以视为一颗完全二叉树,完全二叉树的一个优秀的性质是
    *         除了最底层之外,每一层都是满的,这使得堆可以利用数组来表示,每一个节点对应数组中的一个元素。二叉堆一般分
    *         为两种,最小堆和最大堆。<br>
    *   2.最大堆:堆中每个父节点的值都大于等于其孩子节点,这样的堆就是一个最大堆。<br>
    *     最小堆:对中的每个父节点都小于等于其孩子节点,这样的堆就是一个最小堆。 <br>
    *   3.堆排序:堆排序分两个阶段。首先将一个数据序列建成堆序列,根节点值是最小(大)值;然后采用选择排序思路,每趟将
    *     根结点值交换到最后,再将其余值调整成堆,依次重复,直到排序完成。<br>
    * @复杂度:<br>
    * 时间复杂度:o(n*log2n)<br>
    *   空间复杂度:o(1) <br>
    * @稳定性:不稳定
    */
   
   public static void heapSort(int[] table){//堆排序
  int n=table.length;
  for(int j=n/2-1;j>=0;j--)//创建最小堆
  sift(table,j,n-1);
  for(int j=n-1;j>0;j--){//每趟将最小值交换到后面,再调整成堆
  int temp=table[0];
  table[0]=table[j];
  table[j]=temp;
  sift(table,0,j-1);
  }
   }
   //将以begin为根的子树调整成最小堆,begin、end是序列下届和上届
   private static void sift(int[] table,int begin,int end){
  int i=begin,j=2*i+1;//i为子树的根,j为i节点的左孩子
  int temp=table[i];//获得第i个元素的值
  while(j<=end){//沿较小值孩子节点向下筛选
  if(j<end&&table[j]>table[j+1])//数组元素比较
  j++; //j为左右孩子的较小者
  if(temp>table[j]){//若父母结点值较大
  table[i]=table[j];//孩子节点中的较小者上移
  i=j; //i,j向下一层
  j=2*i+1;
  }
  else break;
  }
  table[i]=temp;//当前子树的原根值调整后的位置
   }
   /**
    * 归并排序
    * @param args
    */
   //一次归并方法:   m和r分别是两个相邻的两个已排序的子序列的起始下标
   private static void merge(int[] X,int[] Y,int m,int r,int n){//一次归并
  int i=m,j=r,k=m;
  while(i<r&&j<r+n&&j<X.length){//将X中两个相邻子序列归并到Y中
  if(X[i]<X[j])//较小值复制到Y中
  Y[k++]=X[i++];
  else Y[k++]=X[j++];
  while(i<r) //将前一个子序列剩余元素复制到Y中
  Y[k++]=X[i++];
  while(j<r+n&&j<X.length)//将后一个子序列剩余元素复制到Y中
  Y[k++]=X[j++];
  }
   }
   //一趟归并
   private static void mergepass(int[] X,int[] Y,int n){//一趟归并
  int i=0;
  while(i<X.length-2*n+1){
  merge(X,Y,i,i+n,n);
  i+=2*n;
  }
  if(i+n<X.length)
  merge(X,Y,i,i+n,n);//再一次归并
  else
  for(int j=i;j<X.length;j++)//将X剩余元素复制到Y中
  Y[j]=X[j];
   }
   public static void mergeSort(int[] X){ //归并排序
  int[] Y = new int[X.length];
  int n=1;
  while(n<X.length){
  mergepass(X,Y,n);
  n*=2;
  if(n<X.length){
  mergepass(Y,X,n);
  n*=2;
  }
  }
   }
public static void main(String[] args) {
int[] table = {22,11,65,33,21,23,10};
System.out.println("直接插入排序:");
insertSort(table);
for(int x: table)
System.out.print(x+"\t");

System.out.println("\n希尔排序:");
shellSort(table);
for(int x: table)
System.out.print(x+"\t");

System.out.println("\n冒泡排序:");
bubleSort(table);
for(int x: table)
System.out.print(x+"\t");

System.out.println("\n快速排序:");
quickSort(table);
for(int x: table)
System.out.print(x+"\t");

System.out.println("\n直接选择排序:");
selectSort(table);
for(int x: table)
System.out.print(x+"\t");

System.out.println("\n堆排序:");
heapSort(table);
for(int x: table)
System.out.print(x+"\t");

System.out.println("\n归并排序:");
mergeSort(table);
for(int x: table)
System.out.print(x+"\t");


}


}
0 0
原创粉丝点击