排序复习hh

基础——排序


重要排序
异或的小运用
请添加图片描述 在这里插入图片描述
请添加图片描述
在这里插入图片描述
在这里插入图片描述
异或 等于无进位相加
请添加图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

    public static int[] selectSort(int[] a){//选择排序 不稳定
    	if(a == null || a.length < 2)return a;
    	for(int i = 0; i < (a.length-1); i++){
    		int mindex = i;
    		for(int j = (i+1); j < a.length; j++){
    			mindex = a[mindex]<a[j] ? mindex : j;
    		}
    		swap(a,i,mindex);
    	}
    	return a;
    }
    public static int[] bubbleSort(int[] a){//冒泡排序 等于时不换即稳定
    	if(a == null || a.length < 2)return a;
    	for(int e = a.length-1; e > 0; e--){
    		for(int i = 0; i < e; i++){
    			if(a[i+1]<a[i])swap(a,i,i+1);
    		}
    	}
    	return a;
    }
public static int[] insertSort(int[] a){//插入排序 等于时不换即稳定
    	if(a == null || a.length < 2)return a;
    	for(int i = 1; i < a.length; i++){
    		for(int j = (i-1); j >= 0 && a[j+1] < a[j]; j--){
    			swap(a,j,j+1);
    		}
    	}
    	return a;
    }
    //test----------------------------------------------------------------
    public static int[] generateRandomArray(int maxSize,int maxValue){
    	int a[] = new int[(int)(Math.random()*(maxSize+1))];
    	for(int i = 1; i < a.length;i++){
    		a[i] = (int)(Math.random()*(maxValue+1))-(int)(Math.random()*maxValue);
    	}
    	return a;
    }
    public static int[] clone(int[] a){
    	if(a == null)return null;
    	int[] arr = new int[a.length]; 
    	for(int i = 0; i < a.length; i++){
    		arr[i] = a[i];
    	}
    	return arr;
    }
    public static boolean isEqual(int[] a,int[] b){
    	boolean flag = true;
    	for(int i = 0; i<a.length; i++){
    		if(a[i]!=b[i]){
    			flag = false;break;
    		}
    	}
    	return flag;
    }
    public static void print(int a[]){
    	System.out.println("数组来啰!");
    	for(int i:a){
    		System.out.print(i+" ");
    	}
    	System.out.print("\n");
    }

在这里插入图片描述在这里插入图片描述master公式求解时间复杂度master公式求解时间复杂度

在这里插入图片描述
在这里插入图片描述

递归调用一分为二左右再分,
归并多化一小有序变成大有序

  //归并排序  递归不断二分,比大小合并 无序大到小,有序小到大 稳定
    public static void process(int[] a, int l, int r){
    	if(l == r)return;
    	int mid = l + ((r-l)>>1);//取中间数
    	process(a, l, mid);//递归调用
    	process(a,mid+1,r);
    	merge(a,l,mid,r);
    }
    public static void merge(int[] a, 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++] = a[p1] <= a[p2]? a[p1++]: a[p2++];
    	}
    	while(p1 <= m){ //随机必有一个数组越界
    		help[i++] = a[p1++];
    	}
    	while(p2 <= r){
    		help[i++] = a[p2++];
    	}
    	for(i = 0; i < help.length; i++){//将归并好的赋值给原数组对应下标
    		a[l+i] = help[i];
    		System.out.print(help[i]+" ");
    	}
    }
    public static int[] mergeSort(int[] a){
    	if(a == null || a.length < 2)return a;
    	process(a,0,a.length-1);
    	return a;
    }

在这里插入图片描述在这里插入图片描述

 //快排=========================================不稳定=============
    public static int[] quickSort(int[] a){		
    	if(a == null || a.length < 2)return a;
    	quickSort(a,0,a.length-1);
    	return a;
    }
    //递归给a[l,r]排好序 先左后右 
    public static int[] quickSort(int[] a,int l, int r){
    	if(l < r){
    		swap(a, (l+(int)Math.random()*(r-l+1)),r);//随机生成一个坐标换到数组最右侧作为基值
    		int[] qua = partition(a, l, r);
    		quickSort(a, l, qua[0]-1); //<区
    		quickSort(a, qua[1]+1, r); //>区
    		
    	}
    	return a;
    }
    //处理a[l..r] 默认a[r]做划分 小于 等于 大于 区
    //返回值为等于区域(左右边界) 长度为二的数组
    public static int[] partition(int[] a, int l,int r){
    	int less = l-1;//<区右边界
    	int more = r;//>区左边界
    	while(l < more){//l为当前数的位置
    		if(a[l] < a[r]){
    			swap(a, ++less,l++);//交换小于区域右边界下一个数,和当前数,扩大小于区
    		}else if(a[l] > a[r]){
    			swap(a,l,--more);//交换大于区域左边界下一个数(未知故l不变),和当前数
    		}else l++;//等于区 大于小于区推着走
    	}
    	swap(a,more,r);//将基值置换到等于区
    	return new int[]{less+1,more}; 
    }
   //=============================================

在这里插入图片描述在这里插入图片描述在这里插入图片描述荷兰国旗问题 整数三组分类 小于区通过交换推动等于区移动

偶遇:摩尔投票法
在这里插入图片描述

在这里插入图片描述在这里插入图片描述在这里插入图片描述![在这里插入图片描述](https://img-blog.csdnimg.cn/b09209678c564020a82e4b2a21c77c39.png

依次插入,依次弹出
在这里插入图片描述

堆排:两个基本操作 向上insert或者向下heapify
![在这里插入图片描述](https://img-blog.csdnimg.cn/1170d0245232496caee376f4144b5b3f.png

//堆排 不稳定
    public static int[] heapSort(int[] a){		
    	if(a == null || a.length < 2)return a;
    	for(int i = 0; i < a.length; i++){
    		heapInsert(a, i);
    	}
    	int heapSize = a.length;
    	swap(a, 0, --heapSize);
    	while(heapSize > 0){
    		heapify(a,0,heapSize);
    		swap(a, 0, --heapSize);
    	}
    	return a;
    }
    public static void heapInsert(int[] a, int index){
    	while(a[(index-1)/2] < a[index]){
    		swap(a,(index-1)/2,index);
    		index = (index-1)/2;
    	}
    }
    //某数在index位置能否下移
    public static void heapify(int[] a, int index, int size){
    	int larger;
    	int left = 2*index+1;
    	while(left < size){//有左孩子?
    		if((left+1) >= size)larger = left;//有右孩子?孩子节点较大值的下标
    		else larger = a[left] > a[left+1]? left: left+1;
    		if(a[larger] <= a[index])break;//子节点不大于父节点 跳出循环
    		else{
    			swap(a,larger,index);
    			index = larger;//节点继续向下沉淀
    			left = index*2+1;
    		}
    	}
    }
    

在这里插入图片描述
在这里插入图片描述在这里插入图片描述在这里插入图片描述

//基数排序  非负 稳定
    public static void radixSort(int[] a){		
    	if(a == null || a.length < 2)return ;
    	radixSort(a, 0, (a.length-1), maxbits(a));
    }
    public static int maxbits(int[] a){	//计算数组中最大数的位数
    	int max = Integer.MIN_VALUE;
    	for(int i = 0; i < a.length; i++){
    		max = Math.max(a[i], max);
    	}
    	int digit = 0;
    	while(max != 0){
    		max /= 10;
    		digit++;
    	}
    	return digit;
    }
    public static int getDigit(int a,int d){
    	return (((a/((int)Math.pow(10, d-1))))%10);
    	
    }
    public static void radixSort(int[] a, int l, int r, int digit){
    	final int radix = 10;//0~9
    	int[] bucket = new int[r-l+1];
    	int i = 0;
    	int j = 0;
    	for(int d = 1; d <= digit; d++){ //1~dight位循环,高位级别高,后排
    		int[] count = new int[radix];
    		for(i = l; i <= r; i++){	//从左往右遍历数组,统计d位0~9的个数
    			j = getDigit(a[i],d);
    			count[j]++;
    		}
    		for(i = 1; i < radix; i++){//count更新为d位<= i的个数
    			count[i] =  count[i] + count[i-1];
    		}
    		for(i = r; i >= l; i--){//从右往左遍历,d位上数组当前值是第coun[j]个;
    			j = getDigit(a[i],d);
    			bucket[count[j]-1] = a[i];
    			count[j]--;
    		}
    		for(i = l,j=0; i <= r; i++,j++){//重装
    			a[i] = bucket[j];
    		}
    	}
    }

数组不行,10问题后稳定性保证不好,但是链表可以做到
在这里插入图片描述![在这里插入图片描述](https://img-blog.csdnimg.cn/205c817dd19f49189f80cfdb02d732ab.png
在这里插入图片描述在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值