今天的工作完成的早,有空写了排序方法:
package infon.util.ds;
import java.util.Random;
/**
* 几种排序算法的比较和选择
* 1. 选取排序方法需要考虑的因素:
* (1) 待排序的元素数目n;
* (2) 元素本身信息量的大小;
* (3) 关键字的结构及其分布情况;
* (4) 语言工具的条件,辅助空间的大小等。
* 2. 小结: (1) 若n较小(n <=50),则可以采用直接插入排序或直接选择排序。由于直接插入排序所需的记录移动操作较直接选择排序多,
* 因而当记录本身信息量较大时,用直接选择排序较好。
* (2)若文件的初始状态已按关键字基本有序,则选用直接插入或冒泡排序为宜。
* (3)若n较大,则应采用时间复杂度为O(nlog2n)的排序方法:快速排序、堆排序或归并排序。
* 快速排序是目前基于比较的内部排序法中被认为是最好的方法。
* (4)在基于比较排序方法中,每次比较两个关键字的大小之后,仅仅出现两种可能的转移,因此可以用一棵二叉树来描述比较判定过程,
* 由此可以证明:当文件的n个关键字随机分布时,任何借助于"比较"的排序算法,至少需要O(nlog2n)的时间。
* (5) 当记录本身信息量较大时,为避免耗费大量时间移动记录,可以用链表作为存储结构。
*
* 效率:从上往下递减
* 排序名称 复杂度
* 冒泡排序 O(N^2)
* 选择排序 O(N^2)
* 插入排序 O(N^2)
* 归并排序
* 希尔排序 O(N*(logN)^2)
* 快速排序 O(N*(logN)^2)
*
* @author infon
*
*/
public class Sort {
/**
* 插入排序(Insertion Sort)
* 1. 基本思想:
* 每次将一个待排序的数据元素,插入到前面已经排好序的数列中的适当位置,使数列依然有序;直到待排序数据元素全部插入完为止。
* 2. 排序过程:
* 【示例】:
* [初始关键字] [49] 38 65 97 76 13 27 49
* J=2(38) [38 49] 65 97 76 13 27 49
* J=3(65) [38 49 65] 97 76 13 27 49
* J=4(97) [38 49 65 97] 76 13 27 49
* J=5(76) [38 49 65 76 97] 13 27 49
* J=6(13) [13 38 49 65 76 97] 27 49
* J=7(27) [13 27 38 49 65 76 97] 49
* J=8(49) [13 27 38 49 49 65 76 97]
*
* @param src
*/
public int[] insertSort(int[] src) {
int in,out;
for(out=1;out<src.length;out++){
int tmp=src[out];
in=out;
while(in>0&&src[in-1]>=tmp){
src[in]=src[in-1];
--in;
}
src[in]=tmp;
}
return src;
}
//----------------------------------------------------------------
/**
* 希尔排序
*/
public int[] shellSort(int[] src) {
int inner, outer;
int temp;
int h = 1; // find initial value of h
while (h <= src.length / 3)
h = h * 3 + 1; // (1, 4, 13, 40, 121, ...)
while (h > 0) // decreasing h, until h=1
{
// h-sort the file
for (outer = h; outer < src.length; outer++) {
temp = src[outer];
inner = outer;
// one subpass (eg 0, 4, 8)
while (inner > h - 1 && src[inner - h] >= temp) {
src[inner] = src[inner - h];
inner -= h;
}
src[inner] = temp;
} // end for
h = (h - 1) / 3; // decrease h
} // end while(h>0)
return src;
} // end shellSort()
// --------------------------------------------------------------
/**
* 选择排序
* 1. 基本思想:
* 每一趟从待排序的数据元素中选出最小(或最大)的一个元素,顺序放在已排好序的数列的最后,直到全部待排序的数据元素排完。
* 2.排序过程: 【示例】:
* 初始关键字 [49 38 65 97 76 13 27 49]
* 第一趟排序后 13 [38 65 97 76 49 2749]
* 第二趟排序后 13 27 [65 97 76 49 38 49]
* 第三趟排序后 13 27 38 [97 76 49 65 49]
* 第四趟排序后 13 27 38 49 [49 97 65 76]
* 第五趟排序后 13 27 38 49 49 [97 97 76]
* 第六趟排序后 13 27 38 49 49 76 [76 97]
* 第七趟排序后 13 27 38 49 49 76 76 [ 97]
* 最后排序结果 13 27 38 49 49 76 76 97
*
* @param src
* @return
*/
public int[] selectSort(int src[]) {
for(int i=0;i<src.length;i++){
int index=i;
for(int j=i+1;j<src.length;j++){
if(src[index]>src[j]){
index=j;
}//~end if
}//~end for2
if(i!=index){
int tmp;
tmp=src[i];
src[i]=src[index];
src[index]=tmp;
}//~end if
}//~end for1
return src;
}
//-----------------------------------------------------------------------------------
/**
*
* 冒泡排序(BubbleSort)
* 1. 基本思想:
* 两两比较待排序数据元素的大小,发现两个数据元素的次序相反时即进行交换,直到没有反序的数据元素为止。
* 2. 排序过程:
* 设想被排序的数组R[1..N]垂直竖立,将每个数据元素看作有重量的气泡,根据轻气泡不能在重气泡之下的原则,
* 从下往上扫描数组R,凡扫描到违反本原则的轻气泡,就使其向上"漂浮",如此反复进行,直至最后任何两个气泡都是轻者在上,重者在下为止。
* 【示例】:
* 49 13 13 13 13 13 13 13
* 38 49 27 27 27 27 27 27
* 65 38 49 38 38 38 38 38
* 97 65 38 49 49 49 49 49
* 76 97 65 49 49 49 49 49
* 13 76 97 65 65 65 65 65
* 27 27 76 97 76 76 76 76
* 49 49 49 76 97 97 97 97
*
* @param src
* @return
*/
public int[] bubbleSort(int[] src){
for(int i=0;i<src.length;i++){
boolean isChange=false; //
for(int j=src.length-1;j>i;j--){
if(src[j]<src[j-1]){
int tmp=src[j];
src[j]=src[j-1];
src[j-1]=tmp;
isChange=true;
}//~end if
}//~end for2
if(!isChange)return src; //本趟排序未发生交换,提前终止算法
}//~end for1
return src;
}//~end bubbleSort()
//------------------------------------------------------------------------------------
/**
* 快速排序(Quick Sort)
* 1. 基本思想: 在当前无序区R[1..H]中任取一个数据元素作为比较的"基准"(不妨记为X),
* 用此基准将当前无序区划分为左右两个较小的无序区:R[1..I-1]和R[I+1..H],且左边的无序子区中数据元素均小于等于基准元素,
* 右边的无序子区中数据元素均大于等于基准元素,而基准X则位于最终排序的位置上,即R[1..I-1]
* ≤X.Key≤R[I+1..H](1≤I≤H),当R[1..I-1]和R[I+1..H]均非空时,分别对它们进行上述的划分过程,
* 直至所有无序子区中的数据元素均已排序为止。
* 2. 排序过程:
* 【示例】:
* 初始关键字 [49 38 65 97 76 13 27 49]
* 第一次交换后 [27 38 65 97 76 13 49 49]
* 第二次交换后 [27 38 49 97 76 13 65 49]
* J向左扫描,位置不变,第三次交换后 [27 38 13 97 76 49 65 49]
* I向右扫描,位置不变,第四次交换后 [27 38 13 49 76 97 65 49]
* J向左扫描 [27 38 13 49 76 97 65 49]
*(一次划分过程)
* 初始关键字 [49 38 65 97 76 13 27 49]
* 一趟排序之后 [27 38 13] 49 [76 97 65 49]
* 二趟排序之后 [13] 27 [38] 49 [49 65]76 [97]
* 三趟排序之后 13 27 38 49 49 [65]76 97
* 最后的排序结果 13 27 38 49 49 65 76 97
*
* 改进后的算法枢轴不再是第一个或者是最后一个,而是取第一个、最后一个及中间一个的中间值
* 如果要排序的基数少于10的话,我们就用插入排序,效果会更理想一些
*
* @param src
* @return
*/
public int[] quickSort(int[] src) {
recQuickSort(src,0, src.length - 1);
return src;
}
private void recQuickSort(int[] src,int left, int right) {
int size = right-left+1;
if(size < 10) // insertion sort if small
insertSort(src);
else {
int pivot = medianOf3(src,left, right);
int index = partition(src,left, right, pivot);
recQuickSort(src,left, index - 1);
recQuickSort(src,index + 1, right);
}
}
private int partition(int []src,int left, int right, int pivot) {
int leftPtr = left - 1; // left (after ++)
int rightPtr = right; // right-1 (after --)
while (true) { // find bigger item
while (src[++leftPtr] < pivot)
; // (nop)
// find smaller item
while (rightPtr > 0 && src[--rightPtr] > pivot)
; // (nop)
if (leftPtr >= rightPtr) // if pointers cross,
break; // partition done
else
// not crossed, so
swap(src,leftPtr, rightPtr); // swap elements
} // end while(true)
swap(src,leftPtr, right); // restore pivot
return leftPtr;
}// ~end method partition
public void swap(int []src,int dex1, int dex2) // swap two elements
{
int temp = src[dex1]; // A into temp
src[dex1] = src[dex2]; // B into A
src[dex2] = temp; // temp into B
} // end swap()
public int medianOf3(int[]src,int left, int right)
{
int center = (left+right)/2;
// order left & center
if( src[left] > src[center] )
swap(src,left, center);
// order left & right
if( src[left] > src[right] )
swap(src,left, right);
// order center & right
if( src[center] > src[right] )
swap(src,center, right);
swap(src,center, right-1); // put pivot on right
return src[right-1]; // return median value
} // end medianOf3()
//--------------------------------------------------------------
// ****************************** end quickSort
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
int[] src = new int[] { 49, 38, 65, 97, 76, 13, 27, 49 };
int[] result=new int[src.length];
Sort sort = new Sort();
result=sort.insertSort(src.clone());
System.out.print("insertSort: ");
print(result);
result = sort.selectSort(src.clone());
System.out.print("selectSort: ");
print(result);
result = sort.quickSort(src.clone());
System.out.print("quickSort: ");
print(result);
result = sort.bubbleSort(src.clone());
System.out.print("bubbleSort: ");
print(result);
result = sort.shellSort(src.clone());
System.out.print("shellSort: ");
print(result);
//测试排序所需要的时间
test(10000);
}
public static void print(int []src){
for (int i = 0; i < src.length; i++) {
if(i==src.length-1){
System.out.println(src[i]);
}else{
System.out.print(src[i] + ",");
}
if(i%10==0&&i!=0)System.out.println();
}
}
/**
*
* @param num
* num为测试数据的数量
*/
public static void test(int num){
long start=System.currentTimeMillis();
Sort sort = new Sort();
int[] src = new int[num];
Random rand=new Random();
for(int i=0;i<src.length;i++){
src[i]=Math.abs(rand.nextInt()%10000);
}
int[] result;
start = System.currentTimeMillis();
result=sort.insertSort(src.clone());
System.out.println("insertSort: " + (System.currentTimeMillis() - start));
start = System.currentTimeMillis();
result = sort.selectSort(src.clone());
System.out.println("selectSort: " + (System.currentTimeMillis() - start));
start = System.currentTimeMillis();
result = sort.bubbleSort(src.clone());
System.out.println("bubbleSort: " + (System.currentTimeMillis() - start));
start = System.currentTimeMillis();
result = sort.shellSort(src.clone());
System.out.println("shellSort: " + (System.currentTimeMillis() - start));
start = System.currentTimeMillis();
result = sort.quickSort(src.clone());
System.out.println("quickSort: " + (System.currentTimeMillis() - start));
}//~end test
}
java集合根据某个时间字段排序
转载本文章为转载内容,我们尊重原作者对文章享有的著作权。如有内容错误或侵权问题,欢迎原作者联系我们进行内容更正或删除文章。
提问和评论都可以,用心的回复会被更多人看到
评论
发布评论
相关文章
-
java stream 某个字段去重排序
java stream 某个字段去重排序
java List 字段 -
java根据表名称获取所有字段
java根据表名称获取所有字段
字段 java sql -
java 根据前端返回的字段名进行查询数据
java 根据前端返回的字段名进行查询数据
List java spring