冒泡排序
比较相邻的元素。如果第一个比第二个大,就交换他们两个。
对每一对相邻元素作同样的工作,从开始第一对到结尾的最后一对。这步做完后,最后的元素会是最大的数。
针对所有的元素重复以上的步骤,除了最后一个。
持续每次对越来越少的元素重复上面的步骤,直到没有任何一对数字需要比较。
package DataStructures.sort;
import java.util.Arrays;
/**
* 冒泡排序
* @author coffee
* @Date 2021-04-01 13:53
*/
public class BubbleSort {
public static void main(String[] args) {
int[] arr = {3,9,-1,10,-2};
bubbleSort(arr);
}
public static void bubbleSort(int[] arr){
int temp;
boolean flag = false;
for (int i = 0; i < arr.length - 1; i++) {
for (int j = 0; j < arr.length - 1 - i; j++) {
if (arr[j] > arr[j + 1]){
flag = true;
temp = arr[j + 1];
arr[j + 1] = arr[j];
arr[j] = temp;
}
}
if (!flag){
break;
}else {
flag = false;
}
System.out.println(Arrays.toString(arr));
}
}
}
选择排序
首先在未排序序列中找到最小(大)元素,存放到排序序列的起始位置。
再从剩余未排序元素中继续寻找最小(大)元素,然后放到已排序序列的末尾。
重复第二步,直到所有元素均排序完毕。
package DataStructures.sort;
import java.util.Arrays;
/**
* 选择排序
* @author coffee
* @Date 2021-04-01 14:24
*/
public class SelectSort {
public static void main(String[] args) {
int[] arr = {101,34,119,1};
selectSort(arr);
System.out.println(Arrays.toString(arr));
}
public static void selectSort(int[] arr){
for (int i = 0; i < arr.length - 1; i++) {
int minIndex = i;
int min = arr[i];//101
for (int j = i + 1; j < arr.length; j++) {
if (min > arr[j]){
min = arr[j];//较小数的赋值
minIndex = j;//较小数的位置
}
}
if (minIndex != i){
arr[minIndex] = arr[i];//较大数放到较小数的位置
arr[i] = min;//较小数放到较大数的位置
}
}
}
}
插入排序
将第一待排序序列第一个元素看做一个有序序列,把第二个元素到最后一个元素当成是未排序序列。
从头到尾依次扫描未排序序列,将扫描到的每个元素插入有序序列的适当位置。(如果待插入的元素与有序序列中的某个元素相等,则将待插入元素插入到相等元素的后面。)
package DataStructures.sort;
import java.util.Arrays;
/**
* 插入排序
* @author coffee
* @Date 2021-04-01 15:10
*/
public class InsertSort {
public static void main(String[] args) {
int[] arr = {101,34,119,1};
insertSort(arr);
System.out.println(Arrays.toString(arr));
}
private static void insertSort(int[] arr) {
for (int i = 0; i < arr.length - 1; i++) {
int indexVal = arr[i + 1];//34 (比较数的值)
int index = i;//101的位置(被比较数的索引)
while (index >= 0 && indexVal < arr[index]){//34 < 101
arr[index + 1] = arr[index];//,34的位置为101
index--;//索引向前移动,移动到-1循环结束
}
arr[index + 1] = indexVal;//101的位置为34。索引为-1,+1才是比较数的位置
}
}
}
希尔排序
选择一个增量序列 t1,t2,……,tk,其中 ti > tj, tk = 1;
按增量序列个数 k,对序列进行 k 趟排序;
每趟排序,根据对应的增量 ti,将待排序列分割成若干长度为 m 的子序列,分别对各子表进行直接插入排序。仅增量因子为 1 时,整个序列作为一个表来处理,表长度即为整个序列的长度。
package DataStructures.sort;
import java.util.Arrays;
/**
* 希尔排序
* @author coffee
* @Date 2021-04-02 10:10
*/
public class ShellSort {
public static void main(String[] args) {
int[] arr = {8,9,1,7,2,3,5,4,6,0};
shellSortExchange(arr);
shellSortShift(arr);
}
/**
* 交换法
* @param arr
*/
public static void shellSortExchange(int[] arr) {
int temp;
for (int gap = arr.length / 2; gap > 0; gap /= 2) {
for (int i = gap; i < arr.length; i++) {
for (int j = i - gap; j >= 0; j -= gap) {
if (arr[j] > arr[j + gap]){
temp = arr[j + gap];
arr[j + gap] = arr[j];
arr[j] = temp;
}
}
}System.out.println(Arrays.toString(arr));
}
}
/**
* 移位法
* @param arr
*/
public static void shellSortShift(int[] arr){
int temp;
for (int gap = arr.length / 2; gap > 0; gap /= 2) {
for (int i = gap; i < arr.length; i++) {
int j = i;
temp = arr[j];
if (arr[j] < arr[j - gap]){
while (j - gap >= 0 && temp < arr[j- gap]){
arr[j] = arr[j - gap];
j -= gap;
}
arr[j] = temp;
}
}
System.out.println(Arrays.toString(arr));
}
}
}
快速排序
从数列中挑出一个元素,称为 “基准”(pivot)
重新排序数列,所有元素比基准值小的摆放在基准前面,所有元素比基准值大的摆在基准的后面(相同的数可以到任一边)。在这个分区退出之后,该基准就处于数列的中间位置。这个称为分区(partition)操作
递归把小于基准值元素的子数列和大于基准值元素的子数列排序
package DataStructures.sort;
import java.util.Arrays;
/**
* 快速排序
* @author coffee
* @Date 2021-04-02 11:11
*/
public class QuickSort {
public static void main(String[] args) {
int[] arr = {7,6,5,56,4,6,4,8};
quickSort(arr,0,arr.length - 1);
}
private static void quickSort(int[] arr,int left,int right) {
if (left < right) {
int pivot = arr[left];
int l = left;
int r = right;
while (l < r) {
while (l < r && arr[r] >= pivot) {//后面大于pivot不动 下标向前移
r--;
} //后面小于pivot结束循环
arr[l] = arr[r]; //将其值赋给前面
while (l < r && arr[l] <= pivot) {//前面小于pivot不懂 下标向后移
l++;
} //前面大于pivot结束循环
arr[r] = arr[l]; //将其值赋给后面
} //当两个下标重合时(相等),退出循环
arr[l] = pivot; //将pivot放在重合位置
//递归
quickSort(arr,left,r); //从整个数组开始的地方开始,到pivot结束
quickSort(arr,r + 1,right); //从pivot下一个位置开始,到整个数组结束的地方结束
System.out.println(Arrays.toString(arr));
}
}
}
归并排序
申请空间,使其大小为两个已经排序序列之和,该空间用来存放合并后的序列;
设定两个指针,最初位置分别为两个已经排序序列的起始位置;
比较两个指针所指向的元素,选择相对小的元素放入到合并空间,并移动指针到下一位置;
重复步骤 3 直到某一指针达到序列尾;
将另一序列剩下的所有元素直接复制到合并序列尾。
package DataStructures.sort;
import java.util.Arrays;
/**
* 归并排序
* @author coffee
* @Date 2021-04-02 14:45
*/
public class MergeSort {
public static void main(String[] args) {
int[] arr = {8,4,5,7,1,3,6,2};
int[] temp = new int[arr.length];
mergeSort(arr,0,arr.length - 1,temp);
}
public static void mergeSort(int[] arr,int left,int right,int[] temp){
if (left < right){
int mid = (left + right) / 2;
mergeSort(arr, left, mid, temp);
mergeSort(arr, mid + 1, right, temp);
merge(arr,left,mid,right,temp);
System.out.println(Arrays.toString(arr));
}
}
/**
*
* @param arr 排序的原始数组
* @param left 左边有序序列的初始索引
* @param mid 中间索引
* @param right 右边索引
* @param temp 中转数组
*/
private static void merge(int[] arr,int left,int mid,int right,int[] temp) {
int i = left;//左索引
int j = mid + 1;//右索引
int total = 0;//指向中转数组的当前索引
//1.先把两边的数组按照规则填充到temp数组,直到两边中有一边先处理完为止
while (i <= mid && j <= right){
if (arr[i] > arr[j]){
temp[total] = arr[j];
j++;
}else{
temp[total] = arr[i];
i++;
}
total++;
}
//2.把有剩余数据的一边依次全部填充到temp
while (i <= mid){
temp[total] = arr[i];
i++;
total++;
}
while (j <= right){
temp[total] = arr[j];
j++;
total++;
}
//3.temp -> arr
total = 0;
int tempLeft = left;
while (tempLeft <= right){
arr[tempLeft] = temp[total];
total++;
tempLeft++;
}
}
}
基数排序(桶排序)
找出待排序的数组中最大和最小的元素
统计数组中每个值为i的元素出现的次数,存入数组C的第i项
对所有的计数累加(从C中的第一个元素开始,每一项和前一项相加)
反向填充目标数组:将每个元素i放在新数组的第C(i)项,每放一个元素就将C(i)减去1
package DataStructures.sort;
import java.util.Arrays;
/**
* 基数排序(桶排序)
* @author coffee
* @Date 2021-04-02 15:33
*/
public class RadixSort {
public static void main(String[] args) {
int[] arr = {53,3,542,748,14,214};
radixSort(arr);
}
private static void radixSort(int[] arr) {
int max = arr[0];
for (int value : arr) {
if (max < value) {
max = value;
}
}
int maxLength = (max + "").length();
int[][] bucket = new int[10][arr.length];
int[] indexOfBucket = new int[10];
for(int i = 0, n = 1;i < maxLength;i++,n *= 10){
//按规则向桶中添加数
for (int value : arr) {
int numOfBucket = value / n % 10;
bucket[numOfBucket][indexOfBucket[numOfBucket]] = value;
indexOfBucket[numOfBucket]++;
}
//从桶中按顺序取数
int index = 0;
for(int k = 0;k < indexOfBucket.length;k++){
if(indexOfBucket[k] != 0){
for(int l = 0;l < indexOfBucket[k];l++){
arr[index++] = bucket[k][l];
}
}
indexOfBucket[k] = 0;
}
System.out.println(Arrays.toString(arr));
}
}
}