Java实现各种基础排序
在排序的过程中,元素的比较和交换是避免不了的。在此我们先封装个工具类,封装起来元素的 比较方法、交换方法 及 排序前后的输出。
/**
* 封装 元素交换,元素比较
*/
public final class Utils{
/**
* 比较方法
* false t1 > t2
* true t1 < t2
*/
protected boolean less(int t1, int t2) {
return t1 - t2 < 0;
}
/**
* 交换方法
*/
protected void swap(int [] arr, int i, int j) {
int t = arr[i];
arr[i] = arr[j];
arr[j] = t;
}
/**
* 输出函数,排序前
*/
protected void showSortBefore(int [] arr) {
System.out.println("排序前:");
for (int i : arr)
System.out.print(i+" ");
System.out.println();
}
/**
* 输出函数,排序前
*/
protected void showSortAfter(int [] arr) {
System.out.println("排序后:");
for (int i : arr)
System.out.print(i+" ");
}
}
冒泡排序 : 从左到右不断交换相邻逆序的元素,在一轮的循环之后,可以让未排序的最大元素上浮到右侧。
/**
*
* 注意:在一轮循环结束,如果没有发生交换,说明数组的有序的,可以直接退出
*
* 第二个for循环, int j = 0; j < N - i - 1; j++
*/
public class BubbleSort{
public void sort(int[] nums) {
int N = nums.length;
boolean isSort = true;
for(int i = 0; i < N; i++) {
for(int j = 0; j < N - i - 1; j++) {
if(Utils.less(nums[j+1], nums[j])) {
Utils.swap(nums, j, j+1);
isSort = false;
}
}
if(isSort)
break;
}
}
public static void main(String[] args) {
int [] arr = {3,5,0,9,6};
Utils.showSortBefore(arr);
new BubbleSort().sort(arr);
Utils.showSortAfter(arr);
}
}
选择排序 : 选择出数组中的最小元素,将它与数组的第一个元素交换位置。再从剩下的元素中选择出最下的元素,将它与数组的第二个位置交换位置。不断进行这样的操作,直到将整个数组排序。
/**
* 第二个for循环,int j = i + 1; j < N; j++ (重点);
*/
public class SelectSort{
public void sort(int [] nums) {
int N = nums.length;
for(int i = 0; i < N; i++) {
int min = i;
for(int j = i + 1; j < N; j++) {
if(Utils.less(nums[j], nums[min]))
min = j;
}
Utils.swap(nums, i, min);
}
}
public static void main(String[] args) {
int [] arr = {3,2,5,6,8};
Utils.showSortBefore(arr);
new SelectSort().sort(arr);
Utils.showSortAfter(arr);
}
}
插入排序 : 每次都将当前元素插入到左侧已经排序的数组中,使得插入之后左侧数组依然有序。
/**
* 第一个for循环 int i = 1; i < N; i++
*/
public class InsertSort{
public void sort(int[] nums) {
int N = nums.length;
for(int i = 1; i < N; i++) {
for(int j = 0; j < N; j++) {
if(Utils.less(nums[i],nums[j]))
Utils.swap(nums, i, j);
}
}
}
public static void main(String[] args) {
int [] arr = {3,5,0,9,6};
Utils.showSortBefore(arr);
new InsertSort().sort(arr);
Utils.showSortAfter(arr);
}
}
快速排序 : 通过一个切分元素(基数),将此数组通过比较,交换分为两个子数组,左子数组小于等于切分元素,右子数组大于等于切分元素,再对两个子数组,以此方式切分,直到切分为一个元素,(递归调用)
public class QuickSort{
public void quickSort(int [] nums, int start, int end) {
int left = start;
int right = end;
int keyValue = nums[start];
while(left < right) {
while(left < right && keyValue <= nums[right])
right--;
if(Utils.less(nums[right], keyValue))
Utils.swap(nums, right, left);
while(left < right && keyValue >= nums[left])
left++;
if(Utils.less(keyValue, nums[left]))
Utils.swap(nums, left, right);
}
if(left > start)
quickSort(nums, start, left - 1);
if(right < end)
quickSort(nums, right + 1, end);
}
public static void main(String[] args) {
int [] arr = {3,5,0,2,6,1,3,6,5};
Utils.showSortBefore(arr);
new QuickSort().quickSort(arr , 0, arr.length - 1);
Utils.showSortAfter(arr);
}
}
归并排序 : 将数组分成两部分(递归,一直切分至两个或一个),分别进行排序,然后归并起来。
public class MergeSort{
//归并
public void merge(int [] nums, int low, int mid, int high) {
int [] arr = new int[high - low + 1];
int left = low;
int right = mid + 1;
int k = 0;
while( left <= mid && right <= high) {
if(nums[left] < nums[right])
arr[k++] = nums[left++];
else
arr[k++] = nums[right++];
}
while(left <= mid)
arr[k++] = nums[left++];
while(right <= high)
arr[k++] = nums[right++];
for(int x = 0; x < arr.length; x++)
nums[x+low] = arr[x];
}
//切分
public void fen(int [] nums, int low ,int high) {
int mid = (low + high)/2;
if(low < high) {
fen(nums, low, mid);
fen(nums, mid + 1, high);
merge(nums, low, mid, high);
}
}
public static void main(String[] args) {
int [] arr = {3,5,0,2,6,1,5,9,6};
Utils.showSortBefore(arr);
new MergeSort().fen(arr, 0 , arr.length - 1);
Utils.showSortAfter(arr);
}
}