java排序归纳(全世界最(不)全的排序)未完待续

1.选择排序

时间复杂度为O(n^2) , 空间复杂度为O(n)
比较基础的遍历啦 思想是很容易的 , 将数组先遍历一遍(0 ~ length-1)找到最小的的值,将他放在第一位(索引为0), 继续交换剩余数组(1 ~ length -1) 将他和第二个数进行交换(索引为1)一直到条件不满足。
文字描述文化有限,我们来看看代码:

	for(int i = 0 ; i < arr.length - 1 ; i++){ // 0 ~ n-1
		int minNum = arr[i];
		for(int j = i + 1 ; j < arr.length ; j++){ // i ~ n-1上找最小的值
			int minNum = arr[i] < arr[j] ? i : j;
		}
		int temp = arr[i];
		arr[i] = arr[minNum];
		arr[minNum] = temp;
	}

人话来说 就是挑最小值放在第一个 , 然后剩余的数挑一个最小的放在第二个…
最终完成排序。
简单吧!!

2.冒泡排序

下面这个也很简单,和选择排序有点像 都是 时间复杂度为 O(n^2) 空间复杂度为 O(1);
每一次比较将相邻的数进行比较将大的往后交换 , 就会在最后一位得到最大值 将剩下的继续进行比较,倒数第二个数就是最大的。依次类推得到排序好的数组啦
代码如下

 	for(int i = 0 ; i < arr.length -1 ; i++){ //0 ~ n-1
		for(int j = 0 ; j < arr.length - 1 - i ; j++){	// 0 ~ n-1-i (每次范围缩小1个)
			if(arr[j] > arr[j+1]){
				int temp = arr[j];
				arr[j] = arr[j+1];
				arr[j+1] = temp;
			}
		}
	}

还是很简单的吧~~

3.插入排序

这会比上面两个排序好一点的排序,还是不算难
插入排序如同他的名字。
想象一下,你有一把的牌, 你要把他从小到大进行排序 首先你要保证第1张牌之前是整齐的(这不是废话吗,就1张。。。纯纯哥谭噩梦)然后呢,你就要保证前两张牌是排好序的(如果比第一个数小,就和他进行交换大于他就不进行交换)以此类推,每当你拿到新的牌,他之前的牌全是有序的,你只需考虑新牌应该排到哪里就好啦。
听懂我的故事了嘛,没听懂没关系哦~ 让我们一起看看源码吧

	for(int i = 1 ; i < arr.length -1 ; i++){ //这就是你准备要排序的牌啦,我直接跳过了第一张的排序(又不傻)
		for(int j = i - 1 ; j >= 0 && arr[j] > arr[j+1] ; j--){//这个j表示拍好数的最后一张牌哦
		//当他比后一个数大的时候就需要进行交换啦
		int temp = arr[j];
		arr[j] = arr[j+1];
		arr[j+1] = temp;
		}	
	}

代码简单明了 其中第二个for循环有一丝丝难度(当然是对我)j表示已经排好序中最后一位

4.归并排序

这是一个必要重要的排序相对于上几个档次要高为什么呢因为
时间复杂度 : O(N * log N) 空间复杂度 : O(N)
终于不是时间复杂度为O(N^2)的排序算法了,学会他功力大大提升!!,有没有学习他的冲动!
不用着急,让我们来盘一盘他是怎么实现排序的
整体上就是一个递归,左侧排好序之后让右侧排好序,最后让整体有序
感觉是不是不是很难,让我们看看代码:

	public void guibing(int[] arr , int l , int r){
		if(l = r){
			return;
		}
		int mid = l + (r - l) >> 1;
		guibing(arr, l , mid);
		guibing(arr, mid + 1 , r);
		merge(arr, l , mid , r);
	}

	private void merge(int[] arr , int l , int m , int r){
		int[] help = new int[r - l +1];
		int i = 0;
		int p1 = l;
		int p2 = m+1;
		while(p1 <= m && p2 <=r){
			help[i++] = arr[p1] < arr[p2] ? arr[p1++] : arr[p2++]; 
		}
		while(p1 <= m){
			help[i++] = arr[p1++];
		}
		while(p2 <= r){
			help[i++] = arr[p2++];
		}
		for(int j = 0 ; j < help.length ; j++){
			arr[l+j] = help[j];
		}
 	}

5.快速排序

这是十分关键的一个排序哦,进大厂的小伙伴这个是必须要会的,和前面的排序相比,直接降维打击好吧!!
时间复杂度 : O(N * log N) 空间复杂度 : O(logN)
思想:先在数组中随机选一个数和最后一个进行交换,然后进行partition过程,然后左右进行递归
partition过程:将数组最后一个数为标准,使用双指针,小于他的放左边,等于他的放在中间,大于他的放在右边,然后将最后一位和大于他的区域第一个数进行交换,
是不是有点懵懵的,让我们看看源代码再说自己能不能看懂哈

	public void kuaiPaiMain(int[] arr){
		//对边界进行的划分
		if(arr == null || arr.length <= 1){
			return;
		}
		kuaipai(arr , 0 ,arr.length-1);
	}
	public void kuaiPai(int[] arr , int l , int r){
		if(l >= r){
			return;
		}
		//随机一个位置和最后位进行交换
		int target = l+(int)(Math.random * (r - l +1))
		int temp = arr[target];
		arr[target] = arr[r];
		arr[r] = temp;

		//进行partition  然后左右分割继续递归
		int[] p = partition(arr , l , r);
		kuaipai(arr , l , p[0] - 1);//左
		kuaipai(arr , p[1] + 1 , r);//右
	}
	public int[] partition(int[] arr , int l , int r){
		int less = l-1;
		int more = r;
		//当l没有到达有边界more时,小于左边界扩移动l,大于右边界扩但不移动l,等于移动l
		while(l < more){
			if(arr[l] < arr[r]){
				int temp = arr[l];
				arr[l++] = arr[++less];
				arr[less] = temp;
			}if(arr[l] == arr[r]){
				l++;
			}else{
				int temp = arr[--more];
				arr[more] = arr[l];
				arr[l] = temp;
			}
		}
	}
	int temp = arr[r];
	arr[r] = arr[more];
	arr[more] = temp;
	//返回相等区域在左边界和右边界
	return new int[] {less + 1 , more};

6 . 堆排序

这是一个和快速排序一样地位的排序,将数组想象成一个完全二叉树利用二叉树的性质来完成排序。
时间复杂度 : O(N * log N) 空间复杂度 : O(1)
那么就有一个问题,怎么利用二叉树 :

  • 每一个节点的左子树是2i+1 右子树是 2i + 2
  • 子树的父结点是(i-1)/2

利用这两点就可以完成排序啦!让我们来一起看看代码~

	public void heapSort(int[] arr ){
		if(arr == null || arr.length < 2){
			return;
		}
		
		for(int i = arr.length - 1 ; i >= 0 ; i--){
			heapify(arr , i , arr.length);
		}

		int size = arr.length;
		swap(arr , 0 , --size);
		while(size > 0){
			heapify(arr , 0 , size);
			swap(arr , 0 , --size);
		}
	}

	public void heapify(int[] arr , int index , int size){
		int left = index * 2 + 1;
		while(left < size){
			int lageNum = left +1 < size && arr[left + 1] > arr[left] ? left+1: left;
			lageNum = lageNum > index ? lageNum : index;
			if(lageNum == index){
				break;
			} 
			swap(arr , index , lageNum);
			index = lageNum;
			left = index * 2 + 1;
		}
	}
	public void swap(int[] arr , int p , int q ){
		int temp = arr[p] ;
		arr[p] = arr[q];
		arr[q] = temp;
	}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值