请给出java几种排序方法

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了请给出java几种排序方法相关的知识,希望对你有一定的参考价值。

请给出java几种排序方法

java常见的排序分为:
1 插入类排序
主要就是对于一个已经有序的序列中,插入一个新的记录。它包括:直接插入排序,折半插入排序和希尔排序
2 交换类排序
这类排序的核心就是每次比较都要“交换”,在每一趟排序都会两两发生一系列的“交换”排序,但是每一趟排序都会让一个记录排序到它的最终位置上。它包括:起泡排序,快速排序
3 选择类排序
每一趟排序都从一系列数据中选择一个最大或最小的记录,将它放置到第一个或最后一个为位置交换,只有在选择后才交换,比起交换类排序,减少了交换记录的时间。属于它的排序:简单选择排序,堆排序
4 归并类排序
将两个或两个以上的有序序列合并成一个新的序列
5 基数排序
主要基于多个关键字排序的。
下面针对上面所述的算法,讲解一些常用的java代码写的算法
二 插入类排序之直接插入排序
直接插入排序,一般对于已经有序的队列排序效果好。
基本思想:每趟将一个待排序的关键字按照大小插入到已经排序好的位置上。
算法思路,从后往前先找到要插入的位置,如果小于则就交换,将元素向后移动,将要插入数据插入该位置即可。时间复杂度为O(n2),空间复杂度为O(1)
package sort.algorithm;
public class DirectInsertSort
public static void main(String[] args)
// TODO Auto-generated method stub
int data[] = 2, 6, 10, 3, 9, 80, 1, 16, 27, 20 ;
int temp, j;
for (int i = 1; i < data.length; i++)
temp = data[i];
j = i - 1;
// 每次比较都是对于已经有序的
while (j >= 0 && data[j] > temp)
data[j + 1] = data[j];
j--;

data[j + 1] = temp;

// 输出排序好的数据
for (int k = 0; k < data.length; k++)
System.out.print(data[k] + " ");



三 插入类排序之折半插入排序(二分法排序)
条件:在一个已经有序的队列中,插入一个新的元素
折半插入排序记录的比较次数与初始序列无关
思想:折半插入就是首先将队列中取最小位置low和最大位置high,然后算出中间位置mid
将中间位置mid与待插入的数据data进行比较,
如果mid大于data,则就表示插入的数据在mid的左边,high=mid-1;
如果mid小于data,则就表示插入的数据在mid的右边,low=mid+1
最后整体进行右移操作。
时间复杂度O(n2),空间复杂度O(1)

package sort.algorithm;
//折半插入排序
public class HalfInsertSort
public static void main(String[] args)
int data[] = 2, 6, 10, 3, 9, 80, 1, 16, 27, 20 ;
// 存放临时要插入的元素数据
int temp;
int low, mid, high;
for (int i = 1; i < data.length; i++)
temp = data[i];
// 在待插入排序的序号之前进行折半插入
low = 0;
high = i - 1;
while (low <= high)
mid = (low + high) / 2;
if (temp < data[mid])
high = mid - 1;
else
// low=high的时候也就是找到了要插入的位置,
// 此时进入循环中,将low加1,则就是要插入的位置了
low = mid + 1;

// 找到了要插入的位置,从该位置一直到插入数据的位置之间数据向后移动
for (int j = i; j >= low + 1; j--)
data[j] = data[j - 1];
// low已经代表了要插入的位置了
data[low] = temp;

for (int k = 0; k < data.length; k++)
System.out.print(data[k] + " ");




四 插入类排序之希尔排序
希尔排序,也叫缩小增量排序,目的就是尽可能的减少交换次数,每一个组内最后都是有序的。
将待续按照某一种规则分为几个子序列,不断缩小规则,最后用一个直接插入排序合成
空间复杂度为O(1),时间复杂度为O(nlog2n)
算法先将要排序的一组数按某个增量d(n/2,n为要排序数的个数)分成若干组,每组中记录的下标相差d.对每组中全部元素进行直接插入排序,然后再用一个较小的增量(d/2)对它进行分组,在每组中再进行直接插入排序。当增量减到1时,进行直接插入排序后,排序完成。

package sort.algorithm;
public class ShellSort
public static void main(String[] args)
int a[] = 1, 54, 6, 3, 78, 34, 12, 45, 56, 100 ;
double d1 = a.length;
int temp = 0;
while (true)

//利用这个在将组内倍数减小
//这里依次为5,3,2,1
d1 = Math.ceil(d1 / 2);
//d为增量每个分组之间索引的增量
int d = (int) d1;
//每个分组内部排序
for (int x = 0; x < d; x++)

//组内利用直接插入排序
for (int i = x + d; i < a.length; i += d)
int j = i - d;
temp = a[i];
for (; j >= 0 && temp < a[j]; j -= d)
a[j + d] = a[j];

a[j + d] = temp;



if (d == 1)
break;

for (int i = 0; i < a.length; i++)
System.out.print(a[i]+" ");



五 交换类排序之冒泡排序
交换类排序核心就是每次比较都要进行交换
冒泡排序:是一种交换排序
每一趟比较相邻的元素,较若大小不同则就会发生交换,每一趟排序都能将一个元素放到它最终的位置!每一趟就进行比较。
时间复杂度O(n2),空间复杂度O(1)

package sort.algorithm;
//冒泡排序:是一种交换排序
public class BubbleSort
// 按照递增顺序排序
public static void main(String[] args)
// TODO Auto-generated method stub
int data[] = 2, 6, 10, 3, 9, 80, 1, 16, 27, 20, 13, 100, 37, 16 ;
int temp = 0;
// 排序的比较趟数,每一趟都会将剩余最大数放在最后面
for (int i = 0; i < data.length - 1; i++)
// 每一趟从开始进行比较,将该元素与其余的元素进行比较
for (int j = 0; j < data.length - 1; j++)
if (data[j] > data[j + 1])
temp = data[j];
data[j] = data[j + 1];
data[j + 1] = temp;



for (int i = 0; i < data.length; i++)
System.out.print(data[i] + " ");

参考技术A 排序算法复习(Java实现)(一): 插入,冒泡,选择,Shell,快速排序
为了便于管理,先引入个基础类:
package algorithms;

/**
* @author yovn
*
*/
public abstract class Sorter<E extends Comparable<E>>

public abstract void sort(E[] array,int from ,int len);

public final void sort(E[] array)

sort(array,0,array.length);

protected final void swap(E[] array,int from ,int to)

E tmp=array[from];
array[from]=array[to];
array[to]=tmp;


一 插入排序
该算法在数据规模小的时候十分高效,该算法每次插入第K+1到前K个有序数组中一个合适位置,K从0开始到N-1,从而完成排序:
package algorithms;
/**
* @author yovn
*/
public class InsertSorter<E extends Comparable<E>> extends Sorter<E>

/* (non-Javadoc)
* @see algorithms.Sorter#sort(E[], int, int)
*/
public void sort(E[] array, int from, int len)
E tmp=null;
for(int i=from+1;i<from+len;i++)

tmp=array[i];
int j=i;
for(;j>from;j--)

if(tmp.compareTo(array[j-1])<0)

array[j]=array[j-1];

else break;

array[j]=tmp;




二 冒泡排序
这可能是最简单的排序算法了,算法思想是每次从数组末端开始比较相邻两元素,把第i小的冒泡到数组的第i个位置。i从0一直到N-1从而完成排序。(当然也可以从数组开始端开始比较相邻两元素,把第i大的冒泡到数组的第N-i个位置。i从0一直到N-1从而完成排序。)

package algorithms;

/**
* @author yovn
*
*/
public class BubbleSorter<E extends Comparable<E>> extends Sorter<E>

private static boolean DWON=true;

public final void bubble_down(E[] array, int from, int len)

for(int i=from;i<from+len;i++)

for(int j=from+len-1;j>i;j--)

if(array[j].compareTo(array[j-1])<0)

swap(array,j-1,j);





public final void bubble_up(E[] array, int from, int len)

for(int i=from+len-1;i>=from;i--)

for(int j=from;j<i;j++)

if(array[j].compareTo(array[j+1])>0)

swap(array,j,j+1);




@Override
public void sort(E[] array, int from, int len)

if(DWON)

bubble_down(array,from,len);

else

bubble_up(array,from,len);




三,选择排序
选择排序相对于冒泡来说,它不是每次发现逆序都交换,而是在找到全局第i小的时候记下该元素位置,最后跟第i个元素交换,从而保证数组最终的有序。
相对与插入排序来说,选择排序每次选出的都是全局第i小的,不会调整前i个元素了。
package algorithms;
/**
* @author yovn
*
*/
public class SelectSorter<E extends Comparable<E>> extends Sorter<E>

/* (non-Javadoc)
* @see algorithms.Sorter#sort(E[], int, int)
*/
@Override
public void sort(E[] array, int from, int len)
for(int i=0;i<len;i++)

int smallest=i;
int j=i+from;
for(;j<from+len;j++)

if(array[j].compareTo(array[smallest])<0)

smallest=j;


swap(array,i,smallest);






四 Shell排序
Shell排序可以理解为插入排序的变种,它充分利用了插入排序的两个特点:
1)当数据规模小的时候非常高效
2)当给定数据已经有序时的时间代价为O(N)
所以,Shell排序每次把数据分成若个小块,来使用插入排序,而且之后在这若个小块排好序的情况下把它们合成大一点的小块,继续使用插入排序,不停的合并小块,知道最后成一个块,并使用插入排序。

这里每次分成若干小块是通过“增量” 来控制的,开始时增量交大,接近N/2,从而使得分割出来接近N/2个小块,逐渐的减小“增量“最终到减小到1。

一直较好的增量序列是2^k-1,2^(k-1)-1,.....7,3,1,这样可使Shell排序时间复杂度达到O(N^1.5)
所以我在实现Shell排序的时候采用该增量序列
package algorithms;

/**
* @author yovn
*/
public class ShellSorter<E extends Comparable<E>> extends Sorter<E>

/* (non-Javadoc)
* Our delta value choose 2^k-1,2^(k-1)-1,.7,3,1.
* complexity is O(n^1.5)
* @see algorithms.Sorter#sort(E[], int, int)
*/
@Override
public void sort(E[] array, int from, int len)

//1.calculate the first delta value;
int value=1;
while((value+1)*2<len)

value=(value+1)*2-1;



for(int delta=value;delta>=1;delta=(delta+1)/2-1)

for(int i=0;i<delta;i++)

modify_insert_sort(array,from+i,len-i,delta);





private final void modify_insert_sort(E[] array, int from, int len,int delta)
if(len<=1)return;
E tmp=null;
for(int i=from+delta;i<from+len;i+=delta)

tmp=array[i];
int j=i;
for(;j>from;j-=delta)

if(tmp.compareTo(array[j-delta])<0)

array[j]=array[j-delta];

else break;

array[j]=tmp;




五 快速排序
快速排序是目前使用可能最广泛的排序算法了。
一般分如下步骤:
1)选择一个枢纽元素(有很对选法,我的实现里采用去中间元素的简单方法)
2)使用该枢纽元素分割数组,使得比该元素小的元素在它的左边,比它大的在右边。并把枢纽元素放在合适的位置。
3)根据枢纽元素最后确定的位置,把数组分成三部分,左边的,右边的,枢纽元素自己,对左边的,右边的分别递归调用快速排序算法即可。
快速排序的核心在于分割算法,也可以说是最有技巧的部分。
package algorithms;

/**
* @author yovn
*
*/
public class QuickSorter<E extends Comparable<E>> extends Sorter<E>

/* (non-Javadoc)
* @see algorithms.Sorter#sort(E[], int, int)
*/
@Override
public void sort(E[] array, int from, int len)
q_sort(array,from,from+len-1);


private final void q_sort(E[] array, int from, int to)
if(to-from<1)return;
int pivot=selectPivot(array,from,to);

pivot=partion(array,from,to,pivot);

q_sort(array,from,pivot-1);
q_sort(array,pivot+1,to);



private int partion(E[] array, int from, int to, int pivot)
E tmp=array[pivot];
array[pivot]=array[to];//now to's position is available

while(from!=to)

while(from<to&&array[from].compareTo(tmp)<=0)from++;
if(from<to)

array[to]=array[from];//now from's position is available
to--;

while(from<to&&array[to].compareTo(tmp)>=0)to--;
if(from<to)

array[from]=array[to];//now to's position is available now
from++;


array[from]=tmp;
return from;


private int selectPivot(E[] array, int from, int to)

return (from+to)/2;


本回答被提问者采纳
参考技术B 冒泡排序用得比较多

最稳定

网上搜搜一大堆
参考技术C 排序? 什么的排序?

java数组排序,java数组排序的几种方法

java数组排序详细讲解

前言:

几种常用的JAVA数组排序方法的整合。

java数组排序 法一:Arrays.sort()

Arrays.sort()排序方法在java中是最简单且最常用的排序方法

  1. int []arr1= {45,34,59,55};
  2. Arrays.sort(arr1);//调用方法排序即可

java数组排序 法二:冒泡排序

简单来说,冒泡排序就是重复地走访过要排序的数列,一次比较两个元素,如果他们的顺序错误就把他们交换过来。走访数列的工作是重复地进行直到没有再需要交换,也就是说该数列已经排序完成。

  1. //array[]为待排序数组,n为数组长度
  2. void BubbleSort(int array[], int n)
  3. {
  4. int i, j, k;
  5. for(i=0; i<n-1; i++)
  6. for(j=0; j<n-1-i; j++)
  7. {
  8. if(array[j]>array[j+1])
  9. {
  10. k=array[j];
  11. array[j]=array[j+1];
  12. array[j+1]=k;
  13. }
  14. }
  15. }

java数组排序 法三:选择排序

先找到最小元素所在位置的索引,然后将该元素与第一位上的元素进行交换。

  1. int arr3[]= {23,12,48,56,45};
  2. for(int i=0;i<arr3.length;i++) {
  3. int tem=i;
  4. //将数组中从i开始的最小的元素所在位置的索引赋值给tem
  5. for(int j=i;j<arr3.length;j++) {
  6. if(arr3[j]<arr3[tem]) {
  7. tem=j;
  8. }
  9. }
  10. //上面获取了数组中从i开始的最小值的位置索引为tem,利用该索引将第i位上的元素与其进行交换
  11. int temp1=arr3[i];
  12. arr3[i]=arr3[tem];
  13. arr3[tem]=temp1;
  14. }

java数组排序 法四:反转排序

将原数组按逆序排列

  1. //将数组第i位上的元素与第arr.length-i-1位上的元素进行交换
  2. int []arr4={23,12,48,56,45};
  3. for(int i=0;i<arr4.length/2;i++) {
  4. int tp=arr4[i];
  5. arr4[i]=arr4[arr4.length-i-1];
  6. arr4[arr4.length-i-1]=tp;
  7. }

java数组排序 法五:直接插入排序

  1. int []arr5={23,12,48,56,45};
  2. for (int i = 1; i < arr5.length; i++) {
  3. for (int j = i; j > 0; j--) {
  4. if (arr5[j - 1] > arr5[j]) {//大的放后面
  5. int tmp = arr5[j - 1];
  6. arr5[j - 1] = arr5[j];
  7. arr5[j] = tmp;
  8. }
  9. }
  10. }

 

java数组定义与使用

以上是关于请给出java几种排序方法的主要内容,如果未能解决你的问题,请参考以下文章

JAVA中有哪几种常用的排序方法?每个排序方法的实现思路是如何的?每个方法的思想是啥??

java数组排序,java数组排序的几种方法

java 数组排序的方法

Java中的几种排序方法

Java实现几种常见排序方法

Java中常见的几种数组排序方法