直接上代码(测试+方法实现)
package com.zhaowa.nuoya.algorithms.sort;
import java.util.Random;
/**
* 排序算法集合
* @author
* @Description:
*/
public class SortCollection {
public static void main(String[] args) {
int n = 10000;
SortCollection sortCollection = new SortCollection();
/*冒泡排序测试*/
sortTest(sortCollection,"bubbleSort",n,0);
/*插入排序*/
sortTest(sortCollection,"insertionSort",n,0);
/*选择排序*/
sortTest(sortCollection,"selectionSort",n,0);
/*归并排序*/
sortTest(sortCollection,"mergeSort",n,0);
/*快速排序*/
sortTest(sortCollection,"quickSort",n,0);
/*计数排序*/
sortTest(sortCollection,"countingSort",n,0);
/*查找第K大元素*/
sortTest(sortCollection,"findKLargest",n,4);
}
private static void sortTest(SortCollection sortCollection, String sortType, int n,int k) {
int[] nums = genNums(n);
int kLargest = 0;
printNums(sortType,nums,n,0);
long startTime = System.currentTimeMillis();
switch(sortType){
case "bubbleSort" : sortCollection.bubbleSort(nums,n);
break;
case "insertionSort" : sortCollection.insertionSort(nums,n);
break;
case "selectionSort" : sortCollection.selectionSort(nums,n);
break;
case "mergeSort" : sortCollection.mergeSort(nums,n);
break;
case "quickSort" : sortCollection.quickSort(nums,n);
break;
case "findKLargest" : kLargest = sortCollection.findKLargest(nums,n,k);
break;
case "countingSort" : sortCollection.countingSort(nums,n);
break;
}
long endTime = System.currentTimeMillis();
printNums(sortType,nums,n,endTime-startTime);
if (kLargest != 0){
System.out.println("kLargest="+kLargest);
}
}
private static int[] genNums(int n) {
int[] nums = new int[n];
Random random = new Random();
for (int i = 0;i < n;i++){
nums[i] = random.nextInt(1000);
}
return nums;
}
/**
* 打印数组
* @param preStr
* @param nums
* @param n
* @param useTime
*/
private static void printNums(String preStr,int[] nums, int n ,long useTime) {
StringBuilder sb = new StringBuilder();
sb.append("耗时:").append(useTime).append("ms--").append(preStr).append("=[").append(nums[0]);
for (int i = 1;i < n;i++){
sb.append(",").append(nums[i]);
}
System.out.println(sb.append("]").toString());
}
/**
* 冒泡排序
* @param a
* @param n
*/
public void bubbleSort(int[] a,int n){
if (n <= 1)return;
for (int i = 0;i < n;i++){
boolean flag = false;
for (int j = 0;j < n-i-1;j++){
if (a[j] > a[j+1]){//存在逆序对
int temp = a[j];
a[j] = a[j+1];
a[j+1] = temp;
flag = true;
}
}
if (!flag){
break;
}
}
}
/**
* 直接插入排序
* @param a
* @param n
*/
public void insertionSort(int[] a,int n){
if (n <= 1)return;
for (int i = 1;i < n;i++){//无序列表
int value = a[i];
int j = i-1;
for (;j >=0;j--){//有序列表,从后往前对比,确定元素插入位置(j+1)
if (a[j] > value){
a[j+1] = a[j];
}else {
break;
}
}
a[j+1] = value;
}
}
/**
* 选择排序
* @param a
* @param n
*/
public void selectionSort(int[] a,int n){
if (n <= 1)return;
for (int i = 0;i< n-1;i++){//有序列表
int minPos = i;
for (int j = i;j < n;j++){//在剩余的无序列表中找最小值的数组下标
if (a[j] < a[minPos]){
minPos = j;
}
}
int temp = a[i];
a[i] = a[minPos];
a[minPos] = temp;
}
}
/**
* 归并排序:先分组排序后合并
* @param a
* @param n
*/
public void mergeSort(int[] a,int n){
mergeSortJ(a,0,n-1);
}
/**
* 递归
* @param a
* @param l
* @param r
*/
private void mergeSortJ(int[] a, int l, int r) {
if (l >= r)return;
int mid = l + ((r - l) >> 1);
mergeSortJ(a,l,mid);
mergeSortJ(a,mid+1,r);
merge(a,l,mid,mid+1,r);
}
/**
* 合并两有序数组列表
* @param a
* @param l
* @param mid
* @param l2
* @param r
*/
private void merge(int[] a, int l, int mid, int l2, int r) {
int i = l,j = l2,k = 0;
int[] temp = new int[r-l+1];
while (i <= mid && j<= r){//合并两数组,将数据小的放在temp前面
if (a[i] < a[j]){
temp[k++] = a[i++];
}else {
temp[k++] = a[j++];
}
}
int start = i,end = mid;
if (j <= r){//若后一个数据中还有数据
start = j;
end = r;
}
while (start <= end){
temp[k++] = a[start++];
}
for (int m = 0;m <= r-l;){
a[l+m] = temp[m++];
}
}
/**
* 快速排序
* @param a
* @param n
*/
public void quickSort(int[] a,int n){
quickSortJ(a,0,n-1);
}
/**
* 递归
* @param a
* @param l
* @param r
*/
private void quickSortJ(int[] a, int l, int r) {
if (l >= r)return;
int q = partition(a,l,r);//分区,[l,q-1]<[q]<=[q+1,r]
quickSortJ(a,l,q-1);
quickSortJ(a,q+1,r);
}
/**
* 分区
* @param a
* @param l
* @param r
* @return
*/
private int partition(int[] a, int l, int r) {
int pivot = a[r];//分区点
int i = l;
for (int j = l;j < r;j++){
if (a[j] < pivot){
int temp = a[i];
a[i] = a[j];
a[j] = temp;
i++;
}
}
a[r] = a[i];
a[i] = pivot;
return i;
}
/**
* 线性查找第K大元素
* @param a
* @param n
* @return
*/
public int findKLargest(int[] a,int n,int k){
return findKLargestJ(a,0,n-1 ,k);
}
/**
* 递归查找
* @param a
* @param l
* @param r
* @param k
* @return
*/
private int findKLargestJ(int[] a, int l, int r ,int k) {
if (l > r)return -1;
int p = partition(a,l,r);//利用分区算法
if (k == (p+1)) return a[p];
else if (k < (p+1)){
return findKLargestJ(a,l,p-1,k);
}else {
return findKLargestJ(a,p+1,r,k);
}
}
/**
* 计数排序
* @param a
* @param n
*/
public void countingSort(int[] a,int n){
/*查找a数组中的最大值,确定计数数组的大小*/
int max = a[0];
for (int i = 0;i < n;i++){
if (max < a[i]){
max = a[i];
}
}
int[] c = new int[max+1];//计数数组
for (int i = 0;i< max+1;i++){//给计数数组赋初值
c[i] = 0;
}
/*计算a数组中相同值的个数,并放入c数组中*/
for (int i = 0;i < n;i++){
c[a[i]]++;
}
/*c数据按项累加,得到元素在有序列表中的存储位置*/
for (int i = 1;i <= max;i++){
c[i] = c[i-1] + c[i];
}
int[] r = new int[n];
/*排序,从后向前(维持稳定性)遍历原始a数组*/
for (int i = n-1;i >= 0;i--){
int index = c[a[i]] - 1;
r[index] = a[i];
c[a[i]]--;
}
for (int i = 0;i < n;i++){
a[i] = r[i];
}
}
}
在这里插入代码片