博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
算法——十大排序算法(java版本实现)
阅读量:366 次
发布时间:2019-03-04

本文共 12578 字,大约阅读时间需要 41 分钟。

十大排序算法

十大排序算法脑图:

排序算法

在这里插入图片描述

冒泡排序

传统的冒泡排序

public static void sort(int array[]) {
for (int i = 0; i < array.length - 1; i++) {
for (int j = 0; j < array.length - i - 1; j++) {
int temp = 0; if (array[j] > array[j + 1]) {
temp = array[j]; array[j] = array[j + 1]; array[j + 1] = temp; } } if (isSorted){
break; } }}

优化一:

问题:经过多轮排序后,数列已经有序了,剩下的几轮排序就不必执行了,可以提前结束

解决:判断数列是否已经有序,并做出标记
如果本轮排序中有元素交换,则说明数列无序,如果没有元素交换,则说明数列已经有序,直接跳出大循环。

public static void sort(int array[]) {
for (int i = 0; i < array.length - 1; i++) {
//有序标记,每一轮的初始值都是true boolean isSorted = true; for (int j = 0; j < array.length - i - 1; j++) {
int temp = 0; if (array[j] > array[j + 1]) {
temp = array[j]; array[j] = array[j + 1]; array[j + 1] = temp; //因为有元素进行交换,所以不是有序的,标记变为false isSorted = false; } } if (isSorted){
break; } }}

优化二:

问题:后半部分元素中的最小值大于前半部分元素的最大值,即右边的许多元素已经有序了

解决:对数列有序区的界定
每一轮排序后,记录下来最后一次元素交换的位置,该位置即为无序数列的边界,再往后就是有序区了

public static void sort_2(int array[]) {
for (int i = 0; i < array.length - 1; i++) {
//有序标记,每一轮的初始值都是true boolean isSorted = true; //无序数列的边界,每次比较只需要比到这里为止 int sortBorder = array.length -1; for (int j = 0; j < sortBorder; j++) {
int temp = 0; if (array[j] > array[j + 1]) {
temp = array[j]; array[j] = array[j + 1]; array[j + 1] = temp; //因为有元素进行交换,所以不是有序的,标记变为false isSorted = false; //把无序数列的边界更新为最后一次交换元素位置 sortBorder = j; } } if (isSorted){
break; } }}

参考链接:

鸡尾酒排序

参考链接:

选择排序

public class select_sort {
public static void selctionSort(int[] arr){
if (arr == null || arr.length < 2){
return; } for (int i = 0; i < arr.length; i++) {
int minIndex = i; for (int j = i + 1; j < arr.length; j++) {
minIndex = arr[j] < arr[minIndex] ? j : minIndex; } swap(arr,i,minIndex); } } public static void swap(int[] arr,int i,int j){
/* arr[i] = arr[i] ^ arr[j]; arr[j] = arr[i] ^ arr[j]; arr[i] = arr[i] ^ arr[j];*/ int temp = arr[i]; arr[i] = arr[j]; arr[j] = temp; }}

插入排序

/** *  插入排序 *  一堆有序的扑克牌,插入一张牌 */public class Insert_Sort {
public static void insertionSort(int[] arr){
if (arr == null || arr.length < 2){
return; } for (int i = 1; i < arr.length; i++) {
for (int j = i - 1; j >= 0 && arr[j] > arr[j + 1]; j--) {
swap(arr,j,j+1); } } } public static void swap(int[] arr,int i,int j){
int temp = arr[i]; arr[i] = arr[j]; arr[j] = temp; }}

希尔排序-x

在这里插入代码片

快速排序

在这里插入图片描述

递归实现–双边循环法、单边循环法

package sort;/** * Copyright (C), 2019-2020 * author  candy_chen * date   2020/7/3 10:50 * version 1.0 * Description: 快速排序 * * partition()  分治法(双边循环法) * partitionV2()  分治法(单边循环法) */import java.util.Arrays;import java.util.HashMap;import java.util.Map;import java.util.Stack;/** * */public class quickSort {
/** * 递归实现快排 */ public static void quickSort(int[] arr,int startIndex,int endIndex){
//递归结束条件:startIndex大于或等于endIndex时 if (startIndex >= endIndex){
return; } //得到基准元素位置 int pivotIndex = partition(arr,startIndex,endIndex); //根据基准元素,分成两部分进行递归排序 quickSort(arr,startIndex,pivotIndex-1); quickSort(arr,pivotIndex +1,endIndex); } /** * 非递归实现快排 * 转换成栈的实现,在栈中存储每一次方法调用的参数 * 该方法引入一个存储Map类型元素的栈,用于存储每一次交换时的起始下标和结束下标 * 每一次循环,都会让栈顶元素出栈,通过partition方法进行分治,并且按照基准元素的位置分成左右两部分,左右两部分再分别入栈。 * 当栈位空时,说明排序完毕,退出循环。 */ public static void quickSort_(int[] arr,int startIndex,int endIndex){
//用一个集合栈来代替递归的函数栈 Stack
> quickSortStack = new Stack
>(); //整个数列的起止下标,以哈希的形式入栈 Map rootParam = new HashMap(); rootParam.put("startIndex",startIndex); rootParam.put("endIndex",endIndex); quickSortStack.push(rootParam); //循环结束条件:栈为空时 while (!quickSortStack.isEmpty()){
//栈顶元素出栈,得到起止下标 Map
param = quickSortStack.pop(); //得到基准元素位置 int pivotIndex = partition(arr,param.get("startIndex"),param.get("endIndex")); //根据基准元素分成两部分,把每一部分的起止下标入栈 if (param.get("startIndex") < pivotIndex -1){
Map
leftParam = new HashMap
(); leftParam.put("startIndex",param.get("startIndex")); leftParam.put("endIndex",pivotIndex-1); quickSortStack.push(leftParam); } if (pivotIndex +1 < param.get("endIndex")){ Map
rightParam = new HashMap
(); rightParam.put("startIndex",pivotIndex +1); rightParam.put("endIndex",param.get("endIndex")); quickSortStack.push(rightParam); } } } /** * partition方法实现了元素的交换,让数列中的元素依据自身大小,分别交换到基准元素的左右两边 * 分治 (双边循环法) * @param arr 待交换的数组 * @param startIndex 起始下标 * @param endIndex 结束下标 */ private static int partition(int[] arr,int startIndex,int endIndex){ //取第一个位置的元素作为基准元素 int pivot = arr[startIndex]; int left = startIndex; int right = endIndex; while (left != right){ //控制right指针比较并左移 while (left
pivot){ right--; } //控制left指针比较并右移 while (left

非递归实现快速排序-x

在这里插入代码片

参考链接:

归并排序

package basic_class_01;import java.util.Arrays;public class Code_05_MergeSort {
public static void mergeSort(int[] arr) {
if (arr == null || arr.length < 2) {
return; } mergeSort(arr, 0, arr.length - 1); } public static void mergeSort(int[] arr, int l, int r) {
if (l == r) {
return; } int mid = l + ((r - l) >> 1); mergeSort(arr, l, mid); mergeSort(arr, mid + 1, r); merge(arr, l, mid, r); } public static void merge(int[] arr, int l, int m, int r) {
int[] help = new int[r - l + 1]; int i = 0; int p1 = l; int p2 = m + 1; while (p1 <= m && p2 <= r) {
help[i++] = arr[p1] < arr[p2] ? arr[p1++] : arr[p2++]; } while (p1 <= m) {
help[i++] = arr[p1++]; } while (p2 <= r) {
help[i++] = arr[p2++]; } for (i = 0; i < help.length; i++) {
arr[l + i] = help[i]; } } // for test public static void comparator(int[] arr) {
Arrays.sort(arr); } // for test public static int[] generateRandomArray(int maxSize, int maxValue) {
int[] arr = new int[(int) ((maxSize + 1) * Math.random())]; for (int i = 0; i < arr.length; i++) {
arr[i] = (int) ((maxValue + 1) * Math.random()) - (int) (maxValue * Math.random()); } return arr; } // for test public static int[] copyArray(int[] arr) {
if (arr == null) {
return null; } int[] res = new int[arr.length]; for (int i = 0; i < arr.length; i++) {
res[i] = arr[i]; } return res; } // for test public static boolean isEqual(int[] arr1, int[] arr2) {
if ((arr1 == null && arr2 != null) || (arr1 != null && arr2 == null)) {
return false; } if (arr1 == null && arr2 == null) {
return true; } if (arr1.length != arr2.length) {
return false; } for (int i = 0; i < arr1.length; i++) {
if (arr1[i] != arr2[i]) {
return false; } } return true; } // for test public static void printArray(int[] arr) {
if (arr == null) {
return; } for (int i = 0; i < arr.length; i++) {
System.out.print(arr[i] + " "); } System.out.println(); } // for test public static void main(String[] args) {
int testTime = 500000; int maxSize = 100; int maxValue = 100; boolean succeed = true; for (int i = 0; i < testTime; i++) {
int[] arr1 = generateRandomArray(maxSize, maxValue); int[] arr2 = copyArray(arr1); mergeSort(arr1); comparator(arr2); if (!isEqual(arr1, arr2)) {
succeed = false; printArray(arr1); printArray(arr2); break; } } System.out.println(succeed ? "Nice!" : "Fucking fucked!"); int[] arr = generateRandomArray(maxSize, maxValue); printArray(arr); mergeSort(arr); printArray(arr); }}
public class mergeSort {
public static void mergeSort(int[] array,int left,int right){
if (right <= left) return; int mid = (left + right) >> 1;// (left + right) / 2 mergeSort(array, left, mid); mergeSort(array,mid + 1,right); merge(array,left,mid,right); } private static void merge(int[] arr, int left, int mid, int right) {
int[] temp = new int[right - left + 1]; int i = left,j = mid + 1,k = 0; //两个数组要合并在一起的数组 while (i <= mid && j <= right){
temp[k++] = arr[i] <= arr[j] ? arr[i++] : arr[j++]; } while (i <= mid) temp[k++] = arr[i++]; while (j <= right) temp[k++] = arr[j++]; for (int p = 0; p < temp.length; p++) {
arr[left + p] = temp[p]; } //也可以用System.arraycopy(a,start1,b,start2,length) }}

堆排序

public class heapSort {
static void heapify(int[] array,int length,int i){
int left = 2 * i + 1,right = 2 * i + 2; int largest = i; if (left < length && array[left] > array[largest]) {
largest = left; } if (right < length && array[right] > array[largest]) {
largest = right; } if (largest != i){
int temp = array[i]; array[i] = array[largest]; array[largest] = temp; heapify(array, length,largest); } } public static void heapSort(int[] array){
if (array.length == 0) return; int length = array.length; for (int i = length / 2 - 1;i >= 0; i--) {
heapify(array,length,i); } for (int i = length - 1; i >= 0;i--){
int temp = array[0]; array[0] = array[i]; array[i] = temp; heapify(array,i,0); } }}

参考链接:

计数排序

传统的计数排序

1.先得到数列的最大值;

2.根据数列最大值确定统计数组的长度,数组长度为:输入数列的最大值+1;
3.遍历数列,填充统计数组;
4. 遍历统计数组,输出结果

public static int[] countSort(int[] array) {
//1.得到数列的最大值 int max = array[0]; for (int i = 0; i < array.length; i++) {
if (array[i] > max) {
max = array[i]; } } //2.根据数列最大值确定统计数组的长度 int[] countArray = new int[array.length]; //3.遍历数列,填充统计数组 for (int i = 0; i < array.length; i++) {
countArray[array[i]]++;//每一个整数按照其值对号入座,同时对应数组下标的元素进行加1操作 } //4.遍历统计数组,输出结果 int index = 0; int[] sortedArray = new int[array.length]; for (int i = 0; i < array.length; i++) {
for (int j = 0; j < countArray[i]; j++) {
sortedArray[index++] = i; } } return sortedArray;}

计数排序优化

问题:最大数和最小数相差较小的时候,用最大值决定统计数组的长度容易浪费空间

解决

  1. 数组的长度为数列最大值-最小值+1
  2. 数列的最小值作为一个偏移量,用于计算整数在统计数组中的下标
public static int[] countSort2(int[] array){
//1.得到数列的最大值和最小值,并计算出差值d int max = array[0]; int min = array[0]; for (int i=0;i
max){
max = array[i]; } if (array[i]
=0;i--){
/* * 先找到统计数组中下标为 * */ sortedArray[countArray[array[i] - min] -1] = array[i]; countArray[array[i] - min]--; } return sortedArray;}

参考链接:

桶排序

桶排序:每一个桶代表的一个区间范围,可以承载一个或对个元素

桶的数量
桶的区间跨度

package sort;/** * Copyright (C), 2019-2020 * author  candy_chen * date   2020/7/13 19:03 * version 1.0 * Description: 测试 */import java.util.ArrayList;import java.util.Arrays;import java.util.Collections;import java.util.LinkedList;/** *桶排序 * 所有的桶都保存在ArrayList集合中,每一个桶都被定义成一个链表LinkedList
,这样便于在尾部进行插入元素 */public class bucketSort {
public static double[] bucketSort(double[] array){
//1.得到数列的最大值和最小值,并算出差值d double max = array[0]; double min = array[0]; for (int i=1;i
max){
max = array[i]; } if (array[i]
> bucketList = new ArrayList
>(bucketNum); for (int i = 0 ;i
()); } //3.遍历初始数组,将每个元素放入桶中 for (int i = 0;i
linkedList: bucketList){ for (double element:linkedList) { sortedArray[index] = element; index++; } } return sortedArray; } public static void main(String[] args) { double[] array = new double[]{ 4.12,6.421,0.0023,2.123,8.122,4.12,10.09}; double[] sortedArray = bucketSort(array); System.out.println(Arrays.toString(sortedArray)); }}

参考链接:

基数排序-x

在这里插入代码片

说明:根据网络资料进行搜索学习理解整理 若有侵权联系作者

转载地址:http://euer.baihongyu.com/

你可能感兴趣的文章