这里我将常用的十种排序算法进行归纳,并且提供代码的实现。
本篇文章实现的有冒泡,选择,插入,希尔,归并,话不多说,详情请查看源码:
package day01;
import java.util.Random;
public class AlgTest {
static Random r=new Random();
static int[] array=new int[10];
public static void main(String[] args) {
for(int i=0;i<10;i++) {
array[i]=r.nextInt(100);
}
//调用各大算法来排序
printArr(array);
//冒泡排序
//array=BubbleSort(array);
//选择排序
//array=SelectSort(array);
//插入排序
//array=InsertSort(array);
//希尔排序
//array=ShellSort(array);
//归并排序
int r=array.length-1,l=0;
MergeSort(array,l,r);
printArr(array);
}
/*
* 循环打印,用于检验
*/
private static void printArr(int[] arr) {
int length=arr.length;
for(int i=0;i<arr.length;i++) {
System.out.print(arr[i]+" ");
}
System.out.println();
}
/*
* 冒泡排序: averageTime(O(n^2) bestTime(O(n)) wrostTime(O(n^2)) space(O(1)) 稳定 不需要外部空间
* 原理:将相邻两个元素进行比较,将较大者放置后一位,一直重复此步骤即可
* 改进:每次循环后,都会产生一位最大值,将该最大值加入已排序序列,只需比较前length-1-i个元素即可
*/
private static int[] BubbleSort(int[] arr) {
int temp;
int length=arr.length;
for(int i=0;i<length-1;i++) {
for(int j=0;j<length-1-i;j++) {
if(arr[j]>arr[j+1]) {
temp=arr[j];
arr[j]=arr[j+1];
arr[j+1]=temp;
}
}
}
return arr;
}
/*
* 选择排序 averageTime(O(n^2) bestTime(O(n^2)) wrost
* Time(O(n^2)) space(O(1)) 不稳定 不需要外部空间
* 原理:每次在未排序的数组中找到一个最小值,然后将该最小值加入到已排序序列,重复此步骤
*/
private static int[] SelectSort(int[] arr) {
int length=arr.length;
int temp;
for(int i=0;i<length-1;i++) {
int pos=i;
for(int j=i+1;j<length;j++) {
if(arr[pos]>arr[j]) {
pos=j;
}
}
//此时的pos是未排序中最小值所对应的下标,下一步就是将它加入到已排序序列中
temp=arr[pos];
arr[pos]=arr[i];
arr[i]=temp;
}
return arr;
}
/*
*插入排序 averageTime(O(n^2) bestTime(O(n)) wrostTime(O(n^2)) space(O(1)) 不稳定 不需要外部空间
*原理:从第一个元素开始,都被认为已经排好序,每个已排好序的元素都和新元素比较,大于新元素则向后移!
*/
private static int[] InsertSort(int[] arr) {
int length=arr.length;
for(int i=1;i<length;i++) {
int temp=arr[i];
int j=i-1;
for(;j>=0&&arr[j]>temp;j--) {
arr[j+1]=arr[j];
}
arr[j+1]=temp;
}
return arr;
}
/*
* 希尔排序 averageTime(O(nlogn) bestTime(O(nlog^2n)) wrostTime(O(nlog^2n)) space(O(1)) 不稳定 不需要外部空间
*原理: 对数组进行分组,然后对每个分组进行插入排序。每次减小分组量,直到每组只剩一个元素
*代码理解:第一个循环用于设置分组量,第二个循环用于设置起点,第三个循环用于查找插入位置
*/
private static int[] ShellSort(int[] arr) {
int length=arr.length,temp=0,gap=1;
for(gap=length/2;gap>0;gap/=2) {
for(int i=gap;i<length;i++) {
temp=arr[i];
int j=i-gap;
for(;j>=0&&arr[j]>temp;j-=gap) {
arr[j+gap]=arr[j];
}
arr[j+gap]=temp;
}
}
return arr;
}
/*
* 归并排序 averageTime(O(nlogn) bestTime(O(nlogn)) wrostTime(O(nlogn)) space(O(n)) 稳定 需要外部空间
*原理:采用递归将一个数组以二分的方法分割成若干个大小为1的小片段,然后按相反的方式还原,还原过程中进行排序
*/
private static void MergeSort(int[] arr, int left, int right) {
if(left<right) {
int mid=(left+right)/2;
MergeSort(arr, left, mid);
MergeSort(arr, mid+1, right);
merge(arr,left,mid,right);
}
}
private static void merge(int[] arr, int left, int mid, int right) {
int length_left=mid-left+1;
int length_right=right-mid;
int[] L=new int[length_left];
int[] R=new int[length_right];
int i=0,j=0,k=0;
//将二分后的左序列存放起来
for(k=left;i<length_left;i++,k++) {
L[i]=arr[k];
}
//将二分后的右序列存放起来
for(k=mid+1;j<length_right;j++,k++) {
R[j]=arr[k];
}
//进行排序,并覆盖到原数组中
for(i=0,j=0,k=left;i<length_left && j<length_right;k++) {
if(L[i]>R[j]) {
arr[k]=R[j]; j++;
}else {
arr[k]=L[i]; i++;
}
}
//将L/R中可能剩余的数据继续覆盖到原数组
if(i<length_left) {
for(j=i;j<length_left;j++,k++) {
arr[k]=L[j];
}
}
if(j<length_right) {
for(i=j;i<length_right;i++,k++) {
arr[k]=R[i];
}
}
}
}
参考博客:https://blog.csdn.net/u013270347/article/details/80604690
下一篇:常见排序算法合集2