冒泡排序
package Sort;
import java.util.Arrays;
/**
*
* @author y
* 冒泡排序
*/
public class BubbleSort {
public static void main(String[] args){
int[] arr = new int[]{3,21,5,6,3,6,8,4,7};
System.out.println(Arrays.toString(arr));
bubbleSort(arr);
System.out.println(Arrays.toString(arr));
}
//冒泡排序
public static void bubbleSort(int[] arr){
//第一个for循环为比较轮数
for(int i=0;i<arr.length-1;i++){
//第二个for循环为每轮比较次数
for(int j=0;j<arr.length-1-i;j++){
if(arr[j]>arr[j+1]){
int temp = arr[j];
arr[j] = arr[j+1];
arr[j+1] = temp;
}
}
}
}
}
插入排序
直接插入排序
package Sort;
import java.util.Arrays;
/**
* 直接插入排序
* @author y
*
*/
public class InsertSort {
public static void insertSort(int arr[]){
//遍历数组排序
for(int i=1;i<arr.length;i++){
if(arr[i]<arr[i-1]){
//遍历arr[i]之前的所有元素
int j;
int temp = arr[i];
for(j=i-1;j>=0&&arr[j]>temp;j--){
arr[j+1] = arr[j];
}
arr[j+1] = temp;
}
}
}
public static void main(String[] args){
int[] arr = {3,4,5,2,8,6,9,4,3,1};
System.out.println(Arrays.toString(arr));
insertSort(arr);
System.out.println(Arrays.toString(arr));
}
}
希尔排序
直接插入排序很大有一个缺点,就是当较小的数处在数组后面时,将会耗费大量资源去将它移动到数组前面。
希尔排序是对直接插入排序的一种优化。能够将较小的数更快的移动到数组前。
package Sort;
import java.util.Arrays;
/**
* 希尔排序能在插入排序的基础上,将后面较小的数快速移动到前面来。
* 采用分步的方法,步长为数组长度/2,每一步进行一次插入排序,之后步长再/2。直至步长减少到0.
* @author y
*
*/
public class ShellSort {
public static void shellSort(int[] arr){
//遍历所有步长
for(int d=arr.length/2;d>0;d/=2){
//遍历所有元素
for(int i=d;i<arr.length;i++){
//将每一组元素进行排序
for(int j=i-d;j>=0;j-=d){
if(arr[j]>arr[j+d]){
int temp = arr[j+d];
arr[j+d] = arr[j];
arr[j] = temp;
}
}
}
}
}
public static void main(String[] args){
int[] arr = {3,4,5,2,8,6,9,4,3,1};
System.out.println(Arrays.toString(arr));
shellSort(arr);
System.out.println(Arrays.toString(arr));
}
}
归并排序
首先想象已经有两个排序好的数组,让你把这两个数组归并成一个数组,并且合并后的新数组还是要排序好的。
/**
*
* @param arr
* @param low 排序的起始位置
* @param mid 分割位置
* @param high 排序最后的位置
*/
//arr的low-mid、mid+1-high 已经有序
public static void merge(int[] arr, int low, int mid, int high){
//新建一个数组暂存归并后的数组。
int[] temp = new int[high-low+1];
//记录数组下标
int index = 0;
int i = low;
int j = mid+1;
//比较左右两边数组元素大小,将更小的数取出,放入新数组
while(i<=mid&&j<=high){
if(arr[i]<arr[j]){
temp[index] = arr[i];
i++;
index++;
}else{
temp[index] = arr[j];
j++;
index++;
}
}
//将剩下未排序的元素添加进数组
while(i<=mid){
temp[index] = arr[i];
i++;
index++;
}
while(j<=high){
temp[index] = arr[j];
j++;
index++;
}
//将临时数组中的数据存入原数组中。
for(int k=0;k<temp.length;k++){
arr[k+low] = temp[k];
}
}
当拿到一个无序的数组时可以参照下图,将数组分割成若干个只有一个元素的小数组。这样也可看成这些小数组都是各自有序的。
很明显,这里利用递归便可实现归并算法。
//分割到直至每个数组只有一个元素为止。
public static void mergeSort(int[] arr, int low, int high){
int mid = (high+low)/2;
if(low<high){
mergeSort(arr, low, mid);
mergeSort(arr, mid+1, high);
merge(arr,low,mid,high);
}
}
快速排序
package Sort;
import java.util.Arrays;
/**
* 快速排序
* @author y
*
*/
public class QuickSort {
public static void quickSort(int arr[],int start, int end){
if(start<end){
//取第一个数作为比较的基准
int standard = arr[start];
//左右两边的下标
int left = start;
int right = end;
while(left<right){
//右边的数比基准数大则下标向左移
while(left<right&&standard<=arr[right]){
right--;
}
//用右边的数替换左边的数
arr[left] = arr[right];
//左边的数比基准数小则下标右移
while(left<right&&standard>=arr[left]){
left++;
}
//用左边的数替代右边的数
arr[right] = arr[left];
}
//排序结束后中间的值替换为基准数
arr[left] = standard;
//利用递归完成排序
quickSort(arr,start,left);
quickSort(arr,left+1,end);
}
}
public static void main(String[] args){
int[] arr = {3,4,5,2,8,6,9,4,3,1};
System.out.println(Arrays.toString(arr));
quickSort(arr,0,arr.length-1);
System.out.println(Arrays.toString(arr));
}
}
选择排序
package Sort;
import java.util.Arrays;
/**
* 选择排序
* @author y
*
*/
public class SelectSort {
public static void selectSort(int[] arr){
for(int i=0;i<arr.length-1;i++){
int minIndex = i;
for(int j=i+1;j<arr.length;j++){
if(arr[minIndex]>arr[j]){
minIndex = j;
}
}
if(i!=minIndex){
int temp = arr[i];
arr[i] = arr[minIndex];
arr[minIndex] = temp;
}
}
}
public static void main(String[] args){
int[] arr = {3,4,5,2,8,6,9,4,3,1};
System.out.println(Arrays.toString(arr));
selectSort(arr);
System.out.println(Arrays.toString(arr));
}
}
基数排序
基数排序适用于比较的数存在位数参差不齐的情况。
可以看到,排序的次数由所有数中最大的决定,它有几位就排序几次。每一次排序结束后都按顺序0-9队列中取出取出数重新排序好后再排序。
注意到,这里可以利用了队列先进先出的性质。这里的MyQueue实现了队列的一些简单操作。底层是用数组实现的。
package Sort;
import java.util.Arrays;
import linear.MyQueue;
/**
* 基于队列实现的基数排序
* 适用于所排序的数的位数不同的情况
* @author y
*
*/
public class RadixQueueSort {
public static void main(String[] args){
int[] arr = {1,3751,5,4,13,45,1352,543,43,247,724,7425};
System.out.println(Arrays.toString(arr));
radixSort(arr);
System.out.println(Arrays.toString(arr));
}
public static void radixSort(int[] arr){
//找到最大的数,从而得到比较轮次
int max = Integer.MIN_VALUE;
for(int i=0;i<arr.length;i++){
if(arr[i]>max){
max = arr[i];
}
}
//最大数有几位则比较几个轮次
int maxLength = (max+"").length();
//用十个队列暂存每个数对应的数组
MyQueue[] temp = new MyQueue[10];
for(int i=0;i<10;i++){
temp[i] = new MyQueue();
}
//根据最大数有几位来决定比较几个轮次。
for(int i=0, n=1;i<maxLength;i++,n*=10){
//将余数相同的数放入同一个数组中
for(int j=0;j<arr.length;j++){
int yushu = arr[j]/n%10;
//余数是几,就让其进入下标是几的队列。
temp[yushu].add(arr[j]);
}
int index = 0; //用于记录数组下标
//每一轮比较完成后,将每个数组中的数按顺序取出,重新放入原数组中
for(int k=0;k<10;k++){
//如果队列中有成员,则让其出队
while(!temp[k].isEmpty()){
arr[index] = temp[k].poll();
index++;
}
}
}
}
}
堆排序
堆排序是指在排序过程中,将向量中储存的数据看成一颗完全二叉树。这里就需要用顺序存储的二叉树。先将数调整为一个大顶堆(双亲节点比子节点大)。
下图为堆排序原理:
代码实现:
package Sort;
import java.util.Arrays;
/**
* 堆排序,利用顺序存储的二叉树
* 大顶堆:双亲节点比子节点大
* 最后一个父节点的位置:(n-1)/2 n为节点数
* @author 1
*
*/
public class HeapSort {
/**
*
* @param arr 要转化成堆的数组
* @param size 数组要调整的长度,每从堆顶选出一个数排到最后,要调整的长度就减一
* @param index 调整元素对应的下标
*/
public static void maxHeap(int[] arr,int size,int index){
//左儿子
int leftSon = 2*index+1;
//右儿子
int rightSon = 2*index+2;
int max = index;
//双亲节点和子节点比较,选出最大的值
if(leftSon<size&&arr[leftSon]>arr[max]){
max = leftSon;
}
if(rightSon<size&&arr[rightSon]>arr[max]){
max = rightSon;
}
//交换位置
if(max!=index){
int temp = arr[index];
arr[index] = arr[max];
arr[max] = temp;
//交换位置以后,之前排列好的堆可能需要重新排列。
maxHeap(arr,size,max);
}
}
public static void heapSort(int[]arr){
//开始位置为最后一个父节点
int start = (arr.length-1)/2;
//调整为大顶堆
for(int i = start;i>=0;i--){
maxHeap(arr,arr.length,i);
}
//把数组中的第0个元素和最后一个元素交换位置,再把前面的处理为大顶堆
for(int i=arr.length-1;i>0;i--){
int temp =arr[i];
arr[i] = arr[0];
arr[0] = temp;
//再次调整为大顶堆
maxHeap(arr,i,0);
}
}
public static void main(String...args){
int[] arr = {9,4,2,4,5,3,6,4,7,2,65,6,7};
heapSort(arr);
System.out.println(Arrays.toString(arr));
}
}