常见排序算法
冒泡排序
核心思想:将待排序序列从前往后,一次比较相邻元素的值,逆序则交换(如果一次循环中没有发生一次交换则序列有序,结束排序),使较大(或较小)的值逐渐往后移。
public static void bubbleSort(int[] num) {
for(int i=0;i<num.length;i++ )=“” {=“” boolean=“” flag=“false;” for(int=“” j=“0;j<num.length-1-i;j++” if(num[j]=“”>num[j+1]) {
int temp = num[j];
num[j]=num[j+1];
num[j+1]=temp;
}
}
if(!flag){
break;
}
}
}
</num.length;i++>
选择排序
首先在未排序序列中找到最小(大)元素,存放到排序序列的起始位置。
再从剩余未排序元素中继续寻找最小(大)元素,然后放到已排序序列的末尾。重复第二步,直到所有元素均排序完毕。
public static void selectSort(int[] num) {
for(int i=0;i<num.length;i++ )=“” {=“” int=“” index=“i;” for(int=“” j=“i+1;j<num.length;j++” if(num[index]=“”>num[j]) {
index = j;
}
}
if(index!=i) {
int temp = num[index];
num[index]=num[i];
num[i]=temp;
}
}
}
</num.length;i++>
插入排序
将第一待排序序列第一个元素看做一个有序序列,把第二个元素到最后一个元素当成是未排序序列。
从头到尾依次扫描未排序序列,将扫描到的每个元素插入有序序列的适当位置(如果待插入的元素与有序序列中的某个元素相等,则将待插入元素插入到相等元素的后面。)
public static void insertSort(int[] num) {
for(int i = 1;i<num.length;i++) {=“” int=“” temp=“num[i];” index=“i;” for(int=“” j=“i-1;j”>=0;j–) {
if(num[j]>temp) {
num[index]=num[j];
index–;
}
}
num[index]=temp;
}
}
</num.length;i++)>
希尔排序
希尔排序,也称递减增量排序算法,是插入排序的一种更高效的改进版本。但希尔排序是非稳定排序算法。希尔排序是基于插入排序的以下两点性质而提出改进方法的:
插入排序在对几乎已经排好序的数据操作时,效率高,即可以达到线性排序的效率;
但插入排序一般来说是低效的,因为插入排序每次只能将数据移动一位;
希尔排序的基本思想是:先将整个待排序的记录序列分割成为若干子序列分别进行直接插入排序,待整个序列中的记录"基本有序"时,再对全体记录进行依次直接插入排序。
public static void shellSort(int[] num) {
for(int gap = num.length/2;gap>0;gap=gap/2) {
for(int i = gap;i<num.length;i++) {=“” int=“” index=“i;” temp=“num[i];” for(int=“” j=“i-gap;j”>=0;j=j-gap) {
if(num[j]>temp) {
num[index]=num[j];
index-=gap;
}
}
num[index]=temp;
}
}
}
</num.length;i++)>
快速排序
public static void quickSort(int first, int end, int[] num) {
if(first>end) {
return;
}
int temp = num[first] ;
int st = first ;
int en = end;
while(st!=en) {
while(en>st&&num[en]>=temp) {
en–;
}
while(en>st&&num[st]<=temp) {
st++;
}
if(st<en) {=“” int=“” t=“num[st];” num[st]=“num[en];” num[en]=“t;” }=“” num[first]=“num[en];” quicksort(0,st-1,=“” num);=“” quicksort(st+1,end,=“” <=“” pre=“”>
归并排序
public class MergeSort {
public static void merge(int[] a, int start, int mid, int end) {
int[] tmp = new int[end-start+1]; // tmp是汇总2个有序区的临时区域
int i = start; // 第1个有序区的索引
int j = mid + 1; // 第2个有序区的索引
int k = 0; // 临时区域的索引
while(i <= mid && j <= end) {
if (a[i] <= a[j])
tmp[k++] = a[i++];
else
tmp[k++] = a[j++];
}
while(i <= mid)
tmp[k++] = a[i++];
while(j <= end)
tmp[k++] = a[j++];
// 将排序后的元素,全部都整合到数组a中。
for (i = 0; i < k; i++)
a[start + i] = tmp[i];
tmp=null;
}
public static void mergeSortUp2Down(int[] a, int start, int end) {
if(a==null || start >= end)
return ;
int mid = (end + start)/2;
mergeSortUp2Down(a, start, mid); // 递归排序a[start...mid]
mergeSortUp2Down(a, mid+1, end); // 递归排序a[mid+1...end]
// a[start...mid] 和 a[mid...end]是两个有序空间,
// 将它们排序成一个有序空间a[start...end]
merge(a, start, mid, end);
}
public static void mergeGroups(int[] a, int len, int gap) {
int i;
int twolen = 2 * gap; // 两个相邻的子数组的长度
// 将"每2个相邻的子数组" 进行合并排序。
for(i = 0; i+2*gap-1 < len; i+=(2*gap))
merge(a, i, i+gap-1, i+2*gap-1);
// 若 i+gap-1 < len-1,则剩余一个子数组没有配对。
// 将该子数组合并到已排序的数组中。
if ( i+gap-1 < len-1)
merge(a, i, i + gap - 1, len - 1);
}
public static void mergeSortDown2Up(int[] a) {
if (a==null)
return ;
for(int n = 1; n < a.length; n*=2)
mergeGroups(a, a.length, n);
}
public static void main(String[] args) {
int i;
int a[] = {80,30,60,40,20,10,50,70};
System.out.printf("before sort:");
for (i=0; i
堆排序
最大堆进行升序排序的基本思想:
① 初始化堆: 将数列a[1…n]构造成最大堆。
② 交换数据: 将a[1]和a[n]交换,使a[n]是a[1…n]中的最大值;然后将a[1…n-1]重新调整为最大堆。 接着,将a[1]和a[n-1]交换,使a[n-1]是a[1…n-1]中的最大值;然后将a[1…n-2]重新调整为最大值。 依次类推,直到整个数列都是有序的。
public class HeapSort {
public static void maxHeapDown(int[] a, int start, int end) { int c = start; // 当前(current)节点的位置 int l = 2*c + 1; // 左(left)孩子的位置 int tmp = a[c]; // 当前(current)节点的大小 for (; l <= end; c=l,l=2*l+1) { // "l"是左孩子,"l+1"是右孩子 if ( l < end && a[l] < a[l+1]) l++; // 左右两孩子中选择较大者,即m_heap[l+1] if (tmp >= a[l]) break; // 调整结束 else { // 交换值 a[c] = a[l]; a[l]= tmp; } } } public static void heapSortAsc(int[] a, int n) { int i,tmp; // 从(n/2-1) --> 0逐次遍历。遍历之后,得到的数组实际上是一个(最大)二叉堆。 for (i = n / 2 - 1; i >= 0; i--) maxHeapDown(a, i, n-1); // 从最后一个元素开始对序列进行调整,不断的缩小调整的范围直到第一个元素 for (i = n - 1; i > 0; i--) { // 交换a[0]和a[i]。交换后,a[i]是a[0...i]中最大的。 tmp = a[0]; a[0] = a[i]; a[i] = tmp; // 调整a[0...i-1],使得a[0...i-1]仍然是一个最大堆。 // 即,保证a[i-1]是a[0...i-1]中的最大值。 maxHeapDown(a, 0, i-1); } } public static void minHeapDown(int[] a, int start, int end) { int c = start; // 当前(current)节点的位置 int l = 2*c + 1; // 左(left)孩子的位置 int tmp = a[c]; // 当前(current)节点的大小 for (; l <= end; c=l,l=2*l+1) { // "l"是左孩子,"l+1"是右孩子 if ( l < end && a[l] > a[l+1]) l++; // 左右两孩子中选择较小者 if (tmp <= a[l]) break; // 调整结束 else { // 交换值 a[c] = a[l]; a[l]= tmp; } } } public static void heapSortDesc(int[] a, int n) { int i,tmp; // 从(n/2-1) --> 0逐次遍历每。遍历之后,得到的数组实际上是一个最小堆。 for (i = n / 2 - 1; i >= 0; i--) minHeapDown(a, i, n-1); // 从最后一个元素开始对序列进行调整,不断的缩小调整的范围直到第一个元素 for (i = n - 1; i > 0; i--) { // 交换a[0]和a[i]。交换后,a[i]是a[0...i]中最小的。 tmp = a[0]; a[0] = a[i]; a[i] = tmp; // 调整a[0...i-1],使得a[0...i-1]仍然是一个最小堆。 // 即,保证a[i-1]是a[0...i-1]中的最小值。 minHeapDown(a, 0, i-1); } } public static void main(String[] args) { int i; int a[] = {20,30,90,40,70,110,60,10,100,50,80}; System.out.printf("before sort:"); for (i=0; i</pre>
链接:原文
桶排序public class BucketSort {
public static void bucketSort(int[] a, int max) { int[] buckets; if (a==null || max<1) return ; // 创建一个容量为max的数组buckets,并且将buckets中的所有数据都初始化为0。 buckets = new int[max]; // 1. 计数 for(int i = 0; i < a.length; i++) buckets[a[i]]++; // 2. 排序 for (int i = 0, j = 0; i < max; i++) { while( (buckets[i]--) >0 ) { a[j++] = i; } } buckets = null; } public static void main(String[] args) { int i; int a[] = {8,2,3,4,3,6,6,3,9}; System.out.printf("before sort:"); for (i=0; i</pre>
基数排序
public class RadixSort {
private static int getMax(int[] a) {
int max;
max = a[0];
for (int i = 1; i < a.length; i++)
if (a[i] > max)
max = a[i];
return max;
}
private static void countSort(int[] a, int exp) {
//int output[a.length]; // 存储"被排序数据"的临时数组
int[] output = new int[a.length]; // 存储"被排序数据"的临时数组
int[] buckets = new int[10];
// 将数据出现的次数存储在buckets[]中
for (int i = 0; i < a.length; i++)
buckets[ (a[i]/exp)%10 ]++;
// 更改buckets[i]。目的是让更改后的buckets[i]的值,是该数据在output[]中的位置。
for (int i = 1; i < 10; i++)
buckets[i] += buckets[i - 1];
// 将数据存储到临时数组output[]中
for (int i = a.length - 1; i >= 0; i--) {
output[buckets[ (a[i]/exp)%10 ] - 1] = a[i];
buckets[ (a[i]/exp)%10 ]--;
}
// 将排序好的数据赋值给a[]
for (int i = 0; i < a.length; i++)
a[i] = output[i];
output = null;
buckets = null;
}
public static void radixSort(int[] a) {
int exp; // 指数。当对数组按各位进行排序时,exp=1;按十位进行排序时,exp=10;...
int max = getMax(a); // 数组a中的最大值
// 从个位开始,对数组a按"指数"进行排序
for (exp = 1; max/exp > 0; exp *= 10)
countSort(a, exp);
}
public static void main(String[] args) {
int i;
int a[] = {53, 3, 542, 748, 14, 214, 154, 63, 616};
System.out.printf("before sort:");
for (i=0; i
文章转自:java排序算法_Java-答学网
作者:答学网,转载请注明原文链接:http://www.dxzl8.com/