排序算法总结

1.冒泡排序

分两层循环,外层循环负责循环整个数组,内层循环用来判断相邻两个元素的大小 经过第一遍循环之后,最大的元素已经被放到了最后一位
针对所有的元素进行上面的操作,除了最后一位 直到没有一个元素需要交换,就return

时间复杂度O(n^2)    最优时间复杂度O(n)
最差时间复杂度O(n^2)     空间复杂度O(1)
public void bubbleSort(int[] numbers) {
		int tmp;
		boolean change = false; // 判断这一轮下来有没有交换
		for (int i = 0; i < numbers.length; i++) {
			for (int j = 0; j < numbers.length - 1 - i; j++) {
				if (numbers[j] > numbers[j + 1]) {
					change = true;
					tmp = numbers[j];
					numbers[j] = numbers[j + 1];
					numbers[j + 1] = tmp;
				}
			}
			if (!change) {  // 如果没有交换就直接退出
				return;
			}
		}

	}
2.选择排序

分两轮循环,第一个循环用来遍历整个数组 第二个循环从i开始,用来比较相邻的两个值的大小
在第二个循环里面,从i 开始,要找到最小值的下标,并跟这轮循环的i交换

 时间复杂度O(n^2)
public void selectSort(int[] numbers) {
		for (int i = 0; i < numbers.length; i++) {
			int minIndex = i;
			for (int j = i; j < numbers.length; j++) {
				// 获取最小索引数
				if (numbers[j] < numbers[minIndex]) {
					minIndex = j;
				}
			}
			// 把最小值与i交换
			int tmp = numbers[minIndex];
			numbers[minIndex] = numbers[i];
			numbers[i] = tmp;
		}
	}
3.插入排序

插入排序 第一位数默认有序,从第二位数开始循环,逐个比较大小,进行排序
如果当前位数的值小于要比较的值,则把被比较的值后移一位,i下标减1,继续向前进行比较 最后找到合适的位置,把当前位数的值放入

时间复杂度:最佳O(n)    最差O(n^2)
	public void insertSort(int[] numbers) {
		for (int i = 0; i < numbers.length - 1; i++) {
			int current = numbers[i + 1];
			while (i >= 0 && current < numbers[i]) {
				numbers[i + 1] = numbers[i];
				i--;
			}
			numbers[i + 1] = current;
		}
	}
4.希尔排序

也是一种插入排序
初始增量gap的值为length/2,缩小增量继续以gap =gap/2的方式。 把整个数组分为gap组,对每一组进行插入排序

  时间复杂度为O(nlog_2n)
public void shellSort(int[] numbers) {

		int gap = numbers.length/2;
		while(gap>0){
			
			for (int i = gap; i < numbers.length; i++) {
				int preIndex = i-gap;  
				int tmp = numbers[i];
				while(preIndex>=0 && numbers[preIndex]>tmp){
					numbers[preIndex+gap] = numbers[preIndex];
					preIndex = preIndex - gap;
				}
				numbers[preIndex+gap] = tmp;
			}
			gap /= 2;
		}
		
	}
5.归并排序

先递归,后合并
* 思路:把无序数组对半进行拆分,拆分的左右两个数组再递归进行拆分,直到最后每个数组只有一个元素。对这两个元素进行排序,排序之后再次进行合并,得到左右两个有序的子数组,最终把两个子数组进行合并。

 时间复杂度:最佳O(n)    最差:O(nlogn)
public int[] mergeSort(int[] numbers) {
	if (numbers.length < 2)
		return numbers;
	int mid = numbers.length / 2;
	int[] left = Arrays.copyOfRange(numbers, 0, mid);
	int[] right = Arrays.copyOfRange(numbers, mid, numbers.length);
	return merge(mergeSort(left), mergeSort(right));
}

	//合并并排序操作
public int[] merge(int[] left, int[] right) {
	int[] result = new int[left.length + right.length]; //
	// 声明一个等于左右两个数组长度之和的数组
	int i = 0, j = 0;
	for (int index = 0; index < result.length; index++) {
		if (j >= right.length) {
			result[index] = left[i];
			i++;
		} else if (i >= left.length) {
			result[index] = right[j];
			j++;
		} else if (left[i] > right[j]) { // 如果左边数组的值大于右边对应位的值
			result[index] = right[j];
			j++;
		} else {						 // 否则,小于等于
			result[index] = left[i];
			i++;
		}
	}

		return result;
}
6.快速排序

左边指针为i,右边指针为j,初始基准值pivot为第一个元素
从右边j开始进行比较,如果numbers[j]>pivot,则移动指针j,否则,就把numbers[i] = numbers[j], 并把指针i+1,从左边i指针开始比较,同理指针j

 时间复杂度:最佳O(nlogn)  最差情况:O(n^2)  平均情况O(nlogn)
public void quickSort(int[] numbers,int left,int right){
		
		int i = left;   //从左开始的指针 
		int j = right;  //从右开始的指针
		int pivot = numbers[i];  //基准值
		while(i<j){
			while(numbers[j]>pivot && j>i){  // 如果比基准值大
				j--;				         // 指针继续向左移动
			}
			
			if(j>i){
				//number[j]是比pivot小的,直接放左边i的位置
				numbers[i] = numbers[j];  
				//并把i指针后移
				i++;					  
				
				while(numbers[i]<pivot && i<j){
					i++;
				}
				
				if(i<j){
					numbers[j] = numbers[i];
					j--;
				}
			}
			
		}
		
		numbers[i] = pivot;  // 此时,i,j指针重合
		// 递归的对左边进行排序
		if(left<(i-1)) quickSort(numbers, left, i-1);
		/ 递归的对右边进行排序
		if(right>(j+1)) quickSort(numbers, j+1, right);
	}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值