简单排序算法

选择排序

时间复杂度:O(N^2)

空间复杂度:O(1)

/*
 * 选择排序
 * 有一组数据长度为n
 * 第一次找0~n-1中最小的数 放在0位置上
 * 第二次找1~n-1中最小的数 放在1位置上
 * 第三次找2~n-1中最小的数 放在2位置上
 * ......
 * */
public class Selectionsort {
	public static void selectionSort(int[] arr) {
		if(arr == null || arr.length < 2) {
			return;
		}
		for(int i = 0;i < arr.length - 1;i++) {//i~n-1
			int min = i;
			for(int j = i + 1;j < arr.length;j++) {//i~n-1上找最小值的下标
				min = arr[j] < arr[min] ? j : min;
			}
			swap(arr,i,min);
		}
	}
	public static void swap(int[] arr, int i, int j) {
		int tmp = arr[i];
		arr[i] = arr[j];
		arr[j] = tmp;
	}

}

冒泡排序

时间复杂度:O(N^2)

空间复杂度:O(1)

/**
 * @author hzx
 * 冒泡排序
 * 有一个数组长度为n 相邻两个数比较大小谁大谁在右边
 */
public class Bubblesort {
	public static void bubbleSort(int[] arr) {
		if(arr == null || arr.length < 2) {
			return;
		}
		for(int i = arr.length-1; i > 0; i--) {//0~i
			for(int j = 0; j < i; j++) {
				if(arr[j] > arr[j+1]) {
					swap(arr,i,i+1);
				}
			}
		}
	}
	
	//交换arr的i和j位置上的值
	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];
	}

}

插入排序

时间复杂度:O(N^2)        

空间复杂度:O(1)

最坏情况数组降序排列时间复杂度:O(N^2) 

最好情况数组升序排列时间复杂度:O(N)

时间复杂度按照最差的情况估计 所以插入排序时间复杂度:O(N^2) 

/*
 *插入排序
 *一个数组长度为n
 *第一次0~0位置上有序往前看
 *第二次0~1位置上有序往前看 如果1位置上的数小0位置上的数 两个位置上的数就交换
 *第三次0~2位置上有序往前看 如果2位置上的数小1位置上的数 两个数交换 交换后 如果1位置上的数小于0位置上就继续交换
 *......
 */
public class Insertionsort {
	public static void insertionSort(int[] arr) {
		if(arr == null || arr.length < 2) {
			return;
		}
		//0~0有序
		//0~i想有序
		for(int i = 1; i < arr.length; i++) {// 0~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) {
		arr[i] = arr[i] ^ arr[j];
		arr[j] = arr[i] ^ arr[j];
		arr[i] = arr[i] ^ arr[j];
	}

}

快速排序

最坏         时间复杂度:O(N^2)             额外空间复杂度:O(N)

理想         时间复杂度:O(N*logN)        额外空间复杂度:O(logN)

荷兰国旗问题

不改进的快速排序

  1. 把数组范围中的最后一个数作为划分值,然后把数组通过荷兰国旗问题分成三个部分:          左侧<划分值、中间==划分值、右侧>划分值
  2. 对左侧范围和右侧范围递归

分析

  1. 划分值越靠近两侧,复杂度越高;划分值越靠近中间,复杂度越低
  2. 可以轻而易举的举出最差的例子,所以不改进的快速排序时间复杂度为O(N^2)

随机快速排序(改进的快速排序)

  1. 在数组范围中,等概率随机选一个数作为划分值,然后把数组通过荷兰国旗问题分成三个部分:                                                                                                                                             左侧<划分值、中间==划分值、右侧>划分值
  2. 对左侧范围和右侧范围递归
  3. 时间复杂度为O(N*logN)
/*
 * 快速排序
 * 荷兰国旗问题
 */
public class Quicksort {
	
	public static void quickSort(int[] arr) {
		if(arr == null || arr.length < 2){
			return;
		}
		quickSort(arr, 0, arr.length - 1);
	}
	//arr[L~R]排好序
	public static void quickSort(int[] arr, int L, int R) {
		if(L < R) {
			swap(arr, L + (int)(Math.random() * (R - L + 1)), R);
			int[] p = partition(arr, L, R);
			quickSort(arr, L, p[0] - 1);// <区
			quickSort(arr, p[1] + 1, R);// >区
		}
	}
	/*
	 * 这是处理arr[L~R]的函数
	 * 默认以arr[R]做划分, arr[R] -> p      <p    ==p      >p
	 * 返回等于区域(左边界,右边界),所以返回一个长度为2的数组res,res[0] res[1]
	 */
	public static int[] partition(int[] arr, int L, int R) {
		int less = L -1; // <区右边界
		int more = R; // >区左边界
		while(L < more){//L表示当前数的位置 arr[R] -> 划分值
			if(arr[L] < arr[R]) {// 当前数 < 划分值
				swap(arr, ++less, L++);
			}else if(arr[L] < arr[R]) {// 当前数 > 划分值
				swap(arr, --more, L);
			}else {
				L++;
			}
		}
		swap(arr, more, R);
		return new int[] {less + 1, more};
	}
	
	public static void swap(int[] arr, int i, int j) {
		int temp = arr[i];
		arr[i] = arr[j];
		arr[j] = temp;
	}

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值