八大排序的空间以及时间复杂度
1.冒泡排序
package com.company.八大排序算法;
import java.util.Arrays;
public class 冒泡排序 {
public static void main(String[] args) {
int []arr=new int[]{1,9,12,8,0,1,3};
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]){
int temp=arr[j];
arr[j]=arr[j+1];
arr[j+1]=temp;
}
}
}
System.out.println("冒泡排序结果为: "+Arrays.toString(arr));
}
}
2.基数排序
package com.company.八大排序算法;
import java.util.Arrays;
/**
* 基本原理:通过不断的分配和收集进行排序,即将最大元素找出来,确定位数N。
* 从每个元素的个位数开始,依次放入编号0-9的桶中,然后进行N轮。
*/
public class 基数排序 {
public static void main(String[] args) {
int []arr=new int[]{1,9,12,8,0,1,3};
sortArray(arr);
System.out.println(Arrays.toString(arr));
}
private static void sortArray(int[] arr) {
int max=getMax(arr);
//定义桶数组
int [][]tempArr1=new int[10][arr.length];
//定义标记数组用于标记一个桶放了多少个元素
int []tempArr2=new int[10];
int length = String.valueOf(max).length();
//循环将元素放入到桶里面
for (int i = 0,n=1; i <length; i++,n*=10) {
for (int j=0;j<arr.length;j++){
int ys=arr[j]/n%10;
tempArr1[ys][tempArr2[ys]++]=arr[j];
}
//取出元素
int index=0;
for (int k = 0; k <tempArr2.length ; k++) {
if(tempArr2[k]!=0){
for (int h = 0; h <tempArr2[k] ; h++) {
arr[index]=tempArr1[k][h];
index++;
}
tempArr2[k]=0;
}
}
}
}
//找出待排序数组中的最大数
private static int getMax(int[] arr) {
int max=arr[0];
for (int i = 1; i <arr.length ; i++) {
if (max<arr[i]){
max=arr[i];
}
}
return max;
}
}
3.堆排序
package com.company.八大排序算法;
import java.util.Arrays;
/**
* 基本原理:构建大顶堆,然后将root元素和叶子节点的最后一个元素交换位置,
* 然后去除掉最后一个元素,继续调整为大顶堆,执行如上操作即可
*/
public class 堆排序 {
public static void CreateHeap(int []arr){
//先构建大堆顶
for (int i=arr.length-1;i>0;i--){
AdjustHeap(arr,i);
int temp = arr[0];
arr[0] = arr[i];
arr[i] = temp;
}
}
//调整堆
public static void AdjustHeap(int []a,int n){
int child;
for (int i = (n - 1) / 2; i >= 0; i--) {
//左子节点位置
child = 2 * i + 1;
//右子节点存在且大于左子节点,child变成右子节点
if (child != n && a[child] < a[child + 1]) {
child++;
}
//交换父节点与左右子节点中的最大值
if (a[i] < a[child]) {
int temp = a[i];
a[i] = a[child];
a[child] = temp;
}
}
}
public static void main(String[] args) {
int []arr=new int[]{1,4,3,2,5,9,6,15,7,20,7,11};
CreateHeap(arr);
System.out.println(Arrays.toString(arr));
}
}
4.希尔排序
package com.company.八大排序算法;
import java.util.Arrays;
/**
* 基本原理(基于插入排序,可以提高排序的效率):
* 希尔排序(shell sort)这个排序方法又称为缩小增量排序,是1959年D·L·Shell提出来的。
* 该方法的基本思想是:设待排序元素序列有n个元素,首先取一个整数increment(小于n)作
* 为间隔将全部元素分为increment个子序列,所有距离为increment的元素放在同一个子序列中,
* 在每一个子序列中分别实行直接插入排序。然后缩小间隔increment,重复上述子序列划分和
* 排序工作。直到最后取increment=1,将所有元素放在同一个子序列中排序为止。
* (2)由于开始时,increment的取值较大,每个子序列中的元素较少,排序速度较快,到排序
* 后期increment取值逐渐变小,子序列中元素个数逐渐增多,但由于前面工作的基础,大多数
* 元素已经基本有序,所以排序速度仍然很快。
*/
public class 希尔排序 {
public static void main(String[] args) {
int []arr=new int[]{1,9,12,8,0,1,3};
//第一种取中间间隔是数组的一半,不是最优的间隔
for (int h = arr.length/2; h>0; h/=2) {
for (int i=h;i<arr.length;i++){
for (int j=i;j>h-1;j-=h){
if (arr[j]<arr[j-h]){
int temp=arr[j];
arr[j]=arr[j-h];
arr[j-h]=temp;
}
}
}
}
System.out.println("第一种排序结果: "+ Arrays.toString(arr));
//第二种,采用克努特序列来计算间隔,比一种更加高效
int jg=1;
while(jg<=arr.length/3){
jg=jg*3+1;
}
for (int h = jg; h>0; h=(h-1)/3) {
for (int i=h;i<arr.length;i++){
for (int j=i;j>h-1;j-=h){
if (arr[j]<arr[j-h]){
int temp=arr[j];
arr[j]=arr[j-h];
arr[j-h]=temp;
}
}
}
}
System.out.println("第二种排序结果: "+ Arrays.toString(arr));
}
}
5.归并排序
package com.company.八大排序算法;
import java.util.Arrays;
/**
* 基本原理:是把待排序序列分为若干个子序列,每个子序列是有序的,
* 然后再把有序子序列合并为整体有序序列。
*/
public class 归并排序 {
public static void main(String[] args) {
int []arr=new int[]{1,9,12,8,0,1,3};
chaifen(arr,0,arr.length-1);
System.out.println(Arrays.toString(arr));
}
//堆待排序序列进行拆分
private static void chaifen(int[] arr, int startIndex, int endIndex) {
int zjIndex=(startIndex+endIndex)/2;
if(startIndex<endIndex){
chaifen(arr,startIndex,zjIndex);
chaifen(arr,zjIndex+1,endIndex);
guibing(arr,startIndex,zjIndex,endIndex);
}
}
//进行归并
private static void guibing(int[] arr, int startIndex, int zjIndex, int endIndex) {
int []tempArr=new int[endIndex-startIndex+1];
int i=startIndex;
int j=zjIndex+1;
int index=0;
while(i<=zjIndex&&j<=endIndex){
if(arr[i]<=arr[j]){
tempArr[index]=arr[i];
i++;
}else {
tempArr[index]=arr[j];
j++;
}
index++;
}
while(i<=zjIndex){
tempArr[index]=arr[i];
i++;
index++;
}
while(j<=endIndex){
tempArr[index]=arr[j];
j++;
index++;
}
for (int k = 0; k <tempArr.length ; k++) {
arr[k+startIndex]=tempArr[k];
}
}
}
6.快速排序
package com.company.八大排序算法;
import java.util.Arrays;
/**
* 基本原理:就是分而治之,就是在数组中选取一个数作为基准,
* 然后比他大的数放在他的右边,比他小的数放在他的左边,然后
* 在对左右进行进行第一次的操作,直到各个区间只有一个数为止
*/
public class 快速排序 {
public static void quickSort(int[] arr, int start, int end) {
if (start < end) {
int index = getIndex(arr, start, end);
quickSort(arr, start, index - 1);
quickSort(arr, index + 1, end);
}
}
//获取中间基准数的下标
private static int getIndex(int[] arr, int start, int end) {
int i = start;
int j = end;
int x = arr[i];
while (i < j) {
//从后往前找比他小的数放到挖的上一个坑位置
while (i < j && arr[j] >= x) {
j--;
}
if (i < j) {
arr[i] = arr[j];
i++;
}
while (i < j && arr[i] < x) {
i++;
}
if (i < j) {
arr[j] = arr[i];
j--;
}
}
arr[i] = x;
return i;
}
public static void main(String[] args) {
int[] arr = new int[]{1, 20, 50, 0, 9, 7, 5, 6, 10,0,-1};
quickSort(arr, 0, arr.length - 1);
System.out.println(Arrays.toString(arr));
}
}
7.直接插入排序
package com.company.八大排序算法;
import java.util.Arrays;
/**
* 基本原理:就是将索引为0的数组后面的元素插入到前面有序的列表中使之变得有序
*/
public class 直接插入排序 {
public static void main(String[] args) {
int[] arr = new int[]{1, 20, 50, 0, 9, 7,5, 6, 10};
// for (int j = 1; j < arr.length; j++) {
// int i = j;
// while (i > 0 && arr[i] < arr[i - 1]) {
// int temp = arr[i];
// arr[i] = arr[i - 1];
// arr[i - 1] = temp;
// i--;
// }
// }
for (int i = 1; i <arr.length ; i++) {
for (int j = i; j >0 ; j--) {
if (arr[j]<arr[j-1]) {
int temp = arr[j];
arr[j] = arr[j - 1];
arr[j - 1] = temp;
}
}
}
System.out.println("直接插入排序: " + Arrays.toString(arr));
}
}
8.选择排序
package com.company.八大排序算法;
import java.util.Arrays;
/**
* 基本原理:从数组的下标从0开始,与数组的后面的每个元素依次比较,
* 如果后面的元素小于当前下标为0元素的值,则交换彼此位置的值,然后
* 继续比较,知道比较完之后后面的元素,则将数组下标为1的元素和后面
* 比较,步骤和下标为0的相同
*/
public class 选择排序 {
public static void main(String[] args) {
int []arr=new int[]{1,20,50,0,9,7,6,10};
for (int i = 0; i <arr.length-1 ; i++) {
for (int j = 1+i; j < arr.length; j++) {
if(arr[i]>arr[j]){
int temp=arr[i];
arr[i]=arr[j];
arr[j]=temp;
}
}
}
System.out.println("选择排序结果为: "+Arrays.toString(arr));
}
}