本文主要是介绍下怎么使用java代码实现冒泡排序,快速排序和堆排序。但由于时间关系,具体原理后续有时间在进行充。(注:本文以升序为例)
一、实现方法
由于这几种排序方法要频繁使用到交换,所以我们先写一个用于交换数组中两个元素的方法:
public static void swap(int[] arr, int a,int b){//交换数组中下标为a和b的两个元素
int t = arr[a] ;
arr[a] = arr[b];
arr[b] = t;
}
1、冒泡排序:
public static void bubbleSort(int[] arr){
boolean flag = true;//用于标记当前这趟是否有交换,若无可提前结束
for(int i=0;i<arr.length-1 && flag;i++){//要冒泡的趟数(数组长度-1)
flag = false;
for(int j=0;j<arr.length-i-1;j++){
if(arr[j]>arr[j+1]){//顺序不对进行交换
swap(arr,j,j+1);
flag = true;
}
}
}
}
2、快速排序
//arr为要排序的数组,low表示要排序的范围最低位,high表示最高位
public static void quickSort(int[] arr, int low,int high){
if(low>high) return ;
int i=low,j=high,temp=arr[low];//temp为哨兵,即比较的对象
while(i<j){//此处要理解快排的原理,每次定位一个元素(temp)到最终位置。该元素最终会将比它大的和比它小的分在左右两边
while(i<j && arr[j]>=temp) j--;//若高位元素大于(本例为升序)哨兵且i<j,则向低位移动
while(i<j && arr[i]<=temp) i++;//同上
if(i<j){//若i<j则说明高位和低位还没有相遇,交换两元素
swap(arr,i,j);
}
}
arr[low] = arr[i];//i==j时,将哨兵与当前i所在位置进行交换,哨兵到达自己最终的位置
arr[i] = temp;
//分别对哨兵左边和右边进行递归排序
quickSort(arr,low,j-1);
quickSort(arr,j+1,high);
}
3、堆排序
先写个调整堆的方法,如下:
//该方法为调节大顶堆的方法:i为当前要调节的元素的下标,len为要调节的数组arr的长度
public static void adjustHeap(int[] arr,int i,int len){
int temp = arr[i];//暂存arr[i]的值
for(int k=2*i+1;k<len;k=k*2+1){//初始化k为i的左孩子的下标
if(k+1<len && arr[k]<arr[k+1]) k++;//若又孩子存在且大于左孩子,则k指向右孩子
if(arr[k]>temp){//如果k指向的值大于temp
arr[i] = arr[k];//让i处的值等于k处的值
i = k;//i指向k
}else break;
}
arr[i] = temp;//最后将temp的值给i指向的位置
}
然后是堆排序的主体:
public static void heapSort(int[] arr){
for(int i=arr.length/2-1;i>=0;i--){//初始化数组:构建大顶堆(若要降序,则构建小顶堆)
adjustHeap(arr,i,arr.length);
}
for(int j=arr.length-1;j>0;j--){
swap(arr,0,j);//交换堆顶和堆末元素
adjustHeap(arr,0,j);//调节堆顶元素(不包括已经交换到堆末的那些元素)
}
}
二、测试
1、冒泡排序
public static void main(String[] args){
int[] a = {4,2,6,8,3,12,65,55,13,18,66,18};
System.out.println("排序前:");
System.out.println(Arrays.toString(a));
bubbleSort(a);//冒泡排序
// quickSort(a,0,a.length-1);//快速排序
// heapSort(a);//堆排序
System.out.println("排序后:");
System.out.println(Arrays.toString(a));
}
2、快速排序
public static void main(String[] args){
int[] a = {4,2,6,8,3,12,65,55,13,18,66,18};
System.out.println("排序前:");
System.out.println(Arrays.toString(a));
// bubbleSort(a);//冒泡排序
quickSort(a,0,a.length-1);//快速排序
// heapSort(a);//堆排序
System.out.println("排序后:");
System.out.println(Arrays.toString(a));
}
3、堆排序
public static void main(String[] args){
int[] a = {4,2,6,8,3,12,65,55,13,18,66,18};
System.out.println("排序前:");
System.out.println(Arrays.toString(a));
// bubbleSort(a);//冒泡排序
// quickSort(a,0,a.length-1);//快速排序
heapSort(a);//堆排序
System.out.println("排序后:");
System.out.println(Arrays.toString(a));
}
三种排序的结结果都如下所示:
排序前:
[4, 2, 6, 8, 3, 12, 65, 55, 13, 18, 66, 18]
排序后:
[2, 3, 4, 6, 8, 12, 13, 18, 18, 55, 65, 66]