1、Java实现各种基础排序
在排序的过程中,元素的比较和交换是避免不了的。在此我们先封装个工具类,封装起来元素的 比较方法、交换方法 及 排序前后的输出。
1.1、工具类(封装了元素的比较、交换等方法)
/**
* 封装了元素比较、交换等方法
*/
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+" ");
}
}
2、冒泡排序
从左到右不断交换相邻逆序的元素(将较大的元素放到右侧),在一轮的循环之后,可以让未排序的最大元素上浮到右侧。
/**
* 冒泡排序
* 注意:在一轮循环结束,如果没有发生交换,说明数组的有序的,可以直接退出
*
* 第二个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);
}
}
3、选择排序
选择出数组中的最小元素,将它与数组的第一个元素交换位置。再从剩下的元素中选择出最下的元素,将它与数组的第二个位置交换位置。不断进行这样的操作,直到将整个数组排序。
/**
* 选择排序
* 第二个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);
}
}
4、插入排序
每次都将当前元素插入到左侧已经排序的数组中,使得插入之后左侧数组依然有序。
/**
* 插入排序
*
* 第一个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++) { //循环是从下标为 1开始
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);
}
}
5、快速排序
通过一个切分元素(基数),将此数组通过比较,交换分为两个子数组,左子数组小于等于切分元素,右子数组大于等于切分元素,再对两个子数组,以此方式切分,直到切分为一个元素,(递归调用)
/**
* 快速排序
*
*/
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);
}
}
6、归并排序
将数组分成两部分(递归,一直切分至两个或一个),分别进行排序,然后归并起来。
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);
}
}
转载:https://blog.csdn.net/qq_42465672/article/details/82051827