/**
* 本源码包含1、冒泡排序;2、选择排序;3、快速排序;
* 并试图对一维64K的随机整形数组排序,从而检验三种排序执行的效率
* 3的效率最高,但是容易栈内存溢出
*/
class ArraySort {
public static void main(String[]args) {
/**
* 创建一个随机整形数组
*/
int[] bytes = newint[1024* 8 * 8];// 64k的数据
int length = bytes.length;
for (int i = 0; i <= length - 1;i++) {
bytes[i]= (int) (Math.random()* length);
}
// 记录排序前时间
long start = System.currentTimeMillis();
// selectSort(bytes);// 选择排序,用时2.7秒
// bubbleSort(bytes);// 冒泡排序,用时3.7秒
quickSort(bytes,0 ,bytes.length- 1);// 快速排序,用时惊人的40微秒
System.out.println("排序用时:" + (System.currentTimeMillis() -start));
// printArray(bytes);
}
// 冒泡排序
public static void bubbleSort(int[] arr) {
for (int i =arr.length - 2;i >= 1; i--) {
for (int j = 0; j <= i; j++) {
if (arr[i] < arr[i + 1]){// 如果不是从大到小,则交换元素
swap(arr,i, i + 1);
}
}
}
}
// 打印数组
public static void printArray(int[] arr) {
System.out.print("[");
for (int i = 0; i < arr.length;i++) {
System.out.print(arr[i]);
System.out.print((i== arr.length - 1)?"]":",");
}
System.out.println();
}
// 选择排序法排序
// 相对冒泡排序法,减少了数组元素值交换的次数,排序效率更高
public static void selectSort(int[] arr) {
for (int j =arr.length - 1;j >= 1; j--) {
int index = findMin(arr, j);// 找出从0号元素到j号元素中值最小的那个元素的下标
swap(arr,index, j);// 然后把最小的那个元素和第j个元素进行交换
}
}
// 该方法查找出一个数组从下标0到下标n的元素中最小的元素的下标
public static int findMin(int[] arr, intn){
int minIndex = 0;
for (int i = 1; i <= n; i++) {
if (arr[minIndex] > arr[i] ) {
minIndex= i;
}
}
return minIndex;
}
// 该方法查找出一个数组从下标0到下标n的元素中最大的元素的下标
public static int findMax(int[]arr, int n){
intmaxIndex = 0;
for(int i = 1;i <= n; i++) {
if(arr[maxIndex] < arr[i] ) {
maxIndex = i;
}
}
returnmaxIndex;
}
// 交换数组中下标i和j的两个元素
public static void swap(int A[], int i,int j) {
int temp= A[i];
A[i] = A[j];
A[j] = temp;
}
public static int Partition(int A[], intleft, int right)//划分函数
{
intpivot = A[right]; // 这里每次都选择最后一个元素作为基准
int tail= left - 1; //tail为小于基准的子数组最后一个元素的索引
for (int i = left; i < right; i++) // 遍历基准以外的其他元素
{
if(A[i] <= pivot) // 把小于等于基准的元素放到前一个子数组末尾
{
swap(A, ++tail, i);
}
}
swap(A, tail + 1,right); // 最后把基准放到前一个子数组的后边,剩下的子数组既是大于基准的子数组
// 该操作很有可能把后面元素的稳定性打乱,所以快速排序是不稳定的排序算法
returntail + 1; //返回基准的索引
}
public static void quickSort(int A[], intleft, int right)
{
if (left>= right)
return;
intpivot_index = Partition(A, left, right); // 基准的索引
quickSort(A, left, pivot_index - 1);
quickSort(A, pivot_index + 1, right);
}
}