排序算法总结

桶排序

取另外一个数组进行记录该排序数组中的出现次数,该数组初始的所有值都为0,当排序数组中的数在0~n时,就需要n+1长度为n+1的数组进行记录。桶排序是利用该数组的下标进行记录排序数组的出现次数,下标就表示值,当整个排序数组都被记录后,就遍历该数组,打印出该下标值。这样就排序出该数组了。 缺点:需要另外的数组开销大,且只适用用正整数的情况

 Scanner sc=new Scanner(System.in);
        
        int n=sc.nextInt(); 
        
        int[] array=new int[10001];
        
        for(int j=0;j<=10000;j++){
            array[j]=0;
            
        }
        
        for(int i=1;i<=n;i++){
            
            int num=sc.nextInt();
            array[num]+=1;
        }
                
        for(int len=1;len<=10000;len++){
            for(int count=1;count<=array[len];count++){


                System.out.print(len+" ");
            }

冒泡排序

每次总是与相邻位置的数据进行比较,当下一个数比它小时 ,就交换位置,第一轮结束后,就把最大的数排到最后的位置上了,然后进行下一轮的比较,接着就把倒数第二大的数排到倒数第二的位置上去了,以此类推,就把所有的数排序好了。长度为n的数组只需要n-1次比较 缺点:时间复杂度高


 //冒泡排序:n个数排序,只需要n-1次轮回比较
        //注意内部次数的界限

        for(int i=0;i<array.length-1;i++){

            for(int p=0;p<array.length-i-1;p++){

                if(array[p]>array[p+1]){

                    int temp=array[p+1];
                    array[p+1]=array[p];
                    array[p]=temp;

                }

            }
        }

选择排序

与冒泡排序类似,但不是只和相邻的数进行比较,而是依次与后面的数进行比较,然后交换位置。长度为n的数组只需要n-1次比较 缺点:时间复杂度高


 //选择排序
        for(int i=0;i<array.length-1;i++){

            for(int p=i;p<array.length;p++){
                 if(array[i]>array[p]){

                    int temp=array[i];
                    array[i]=array[p];
                    array[p]=temp;

                }

            }
        }

快速排序

需要定义一个基数,然后把数组中大于这个数的排在右边,小于这个数的排在左边。 方法:定义两个指针,左指针指向数组的头部,右指针指向数组的尾部,基数选取最左边的第一个数。每次都是右指针开始向中间移动,右指针只要没遇到比他(基数)小的数就一直向前移动,当遇到比他(基数)小的数就停止移动,然后左指针开始移动,只要左指针没有遇到比他大的数就一直向前移动,遇到后就停止移动,然后交换左右指针的值,只要左右指针没有指向同一个数,就一直重复上述步骤,当左右指针遇到同一个值后,就交换这个值与基数的位置,然后以基数为分割点递归处理左右两边的值,一旦左指针大与右指针就停止递归,意味着排序完成

题目推荐 215. ***********

public static void quicksort(int[] array,int left,int right){
      
      
       //判断是否终止
        if(left>right){
            return;
        }

         //定义基准数
        int base=array[left];

        //这里的ij表示新的移动值,二而left,right表示旧的值
        int i=left;
        int j=right;

        while(i!=j){

            //右指针向中间移动,右指针寻找小于基准数的值才跳出循环

            while(array[j]>=base && i<j){
                j--;


            }


            //左指针向中间移动,左指针寻找大于基准数的值才跳出循环
            while(array[i]<=base && i<j){
                i++;


            }

            //交换两个指针的值
            if(i<j){

                int temp=array[j];
                array[j]=array[i];
                array[i]=temp;



            }

        }
        //当一轮交换结束后,即左右指针相等。就交换基准数和共同指针的值
        array[left]=array[i];
        array[i]=base;


        //操作左边的值
        quicksort(array,left,i-1);
        //操作右边的值
        quicksort(array,i+1,right);



    } 

归并排序

采用分治的思想,不断将要排序的数组的进行拆分,直到 拆分成一个个子元素,然后再不断地将子元素进行合并排序,如要求从小到大排序,再合并的时候,就要求小的在前,大的在后,直到最后 合并的元素的长度等于之前的长度。

题目推荐
*************************
合并两个有序的数组_牛客题霸_牛客网 (nowcoder.com)

public class mergeSort{

	static int[] temp;

	public static void main(Stirng[] args){
		int[] nums={};

		temp=new int[nums.length];
		Sort(nums,0,nums.length-1);

	}


	public void Sort(int nums,int left,int right){
		if(left==right){
			return ;//递归终止条件
		}

		int mid=left+((right-left)>>1);

		Sort(nums,left,mid);//拆分左区间
		Sort(nums,mid+1,right);//拆分右区间

		merge(nums,left,mid,right);


	}


	public static void merge(int nums,int left,int mid,int right){


		//暂存区间的值,用于比较

		for(int i=left;i<=right;i++){
			temp[i]=nums[i];
		}

		int index1=left;
		int index2=mid+1;

		for(int i=left;i<=right;i++){

				if(index1==mid+1){
					nums[i]=temp[index2++];//只剩下右边
				}else if(index2=right+1){
					nums[i]=temp[index1++];//只剩下左边
				}else if(temp[index1]<temp[index2]){
					nums[i]=temp[index1++];
				}else{
					nums[i]=temp[index2++];
				}

		}



	}
}


#算法竞赛#
全部评论

相关推荐

8.15&nbsp;一面约的晚上七点半,过程&nbsp;52&nbsp;min,问的问题其实都很基础了,没有让编译器手撕代码;但奈何本人太菜,还是很多问题答的不对,不过面试官很和蔼,全程都在引导(阿里的笔试和测评今晚一起发邮件了,明天早上&nbsp;10&nbsp;点就笔试,时间好赶)8.18&nbsp;一面问题补充两天了没有反馈,应该是凉了补充一下一面的问题1.&nbsp;自我介绍2.&nbsp;了解一下想做什么(从&nbsp;0&nbsp;到&nbsp;1&nbsp;参与一个项目)3.&nbsp;笔试题复盘4.&nbsp;数据结构:哈希的底层原理,哈希冲突的解决方法,以及哈希冲突的具体查找过程(索引上的哈希值是否相等?)5.&nbsp;数据结构:特殊二叉树,满二叉树的性质6.&nbsp;数据结构:二叉树的层序遍历,二叉树的深度遍历(有几种顺序,非递归的结束条件)7.&nbsp;数据结构:有向图和无向图,邻接矩阵和邻接表8.&nbsp;数据结构:数组实现栈(太紧张了,在面试官引导下说对了)9.&nbsp;CSharp:接口和抽象类的区别,抽象类的抽象方法在派生类中不实现是被允许的吗?(C#&nbsp;的八股背的好少,被狠狠拷打了)10.&nbsp;CSharp:装箱和拆箱11.&nbsp;CSharp:.NET&nbsp;垃圾回收机制(这里向面试官申请去说了一下&nbsp;Unity&nbsp;中&nbsp;Mono&nbsp;和&nbsp;IL2CPP&nbsp;的不同实现,说完后面试官也进一步向我科普了一下&nbsp;Unity6&nbsp;的贝姆默认开的是增量)12.&nbsp;设计模式:说一下&nbsp;SOLID&nbsp;原则(因为我简历上写了这个)13.&nbsp;设计模式:里氏替换原则的实际应用(这里说了一下工厂方法和抽象工厂)14.&nbsp;Unity:Canvas&nbsp;的三种渲染模式,overlay&nbsp;这种模式下为什么不需要相机15.&nbsp;Unity:RectTransform&nbsp;和&nbsp;Transform&nbsp;的区别,RectTransform&nbsp;比&nbsp;Transform&nbsp;多了一个什么位置(anchoredPosition,完全忘记了)16.&nbsp;Unity:UI&nbsp;的排列展示组件(Layout&nbsp;Group),Grid&nbsp;和另外两个的区别17.&nbsp;Unity:UI&nbsp;的滑动组件,超出滑动区域的元素如何隐藏或裁剪(回答了&nbsp;Mask)18.&nbsp;Unity:三个&nbsp;Mask&nbsp;的底层原理(不小心把模版测试说错成深度测试了,面试官引导我两次都没反应过来,最后在下一个问题的回答过程中想起来并补充了一下,好尴尬)19.&nbsp;Unity:场景题,用户上传的图片都是方形的,如何实现圆形头像的显示(回答的传入圆形图片,说了一下&nbsp;alpha&nbsp;显示条件以及自定义模版测试)20.&nbsp;项目:介绍一下前两个项目做到什么程度21.&nbsp;项目:MMO&nbsp;最重要的模块是哪些,网络的实现,客户端之间的同步(协议广播&nbsp;+&nbsp;反射处理)22.&nbsp;项目:角色控制的实现(新版&nbsp;Input&nbsp;+&nbsp;Cinemachine)23.&nbsp;项目:对话系统的实现(UI&nbsp;Toolkit&nbsp;+&nbsp;IMGUI),为什么没有用&nbsp;UGUI(回答了面片开销)24.&nbsp;反问:如果能够加入贵司,我会负责什么样的一个位置?(会有集中培训,然后按需安排)25.&nbsp;反问:还需要学习什么(Unity&nbsp;官方文档、渲染管线、优化、GameObject,尤其是资源管理)还以为凉了,中午的时候&nbsp;HR&nbsp;电话和我约了二面8.21&nbsp;二面还是晚上七点半,过程&nbsp;47&nbsp;min,是半聊天半技术的方式,在聊的过程中穿插着问了些简历上的问题,每次回答之后面试官会以自己的角度来阐述问题,和他交流才终于知道架构师到底需要怎样的知识储备了;面试官真的很有人格魅力和技术力,被深深折服了8.22二面通过啦,约了下周一的三面昨晚面试官劝我,趁年轻去追求自己喜欢的,所以接下来我想投投大厂尝试一下8.25&nbsp;三面下午三点,过程&nbsp;39&nbsp;min,面试官是&nbsp;HRBP,总共三个环节:1.&nbsp;个人情况了解;2.&nbsp;测评结果探讨;3.&nbsp;反问;面试结束后,另一位&nbsp;HR&nbsp;与我持续沟通,为我争取了很高的薪资并发放了口头&nbsp;offer,特别感谢这位&nbsp;HR&nbsp;以及所有的面试官,但是由于我个人及实验室原因,目前打算释放这个&nbsp;offer&nbsp;了
投递阿里巴巴集团等公司10个岗位
点赞 评论 收藏
分享
评论
1
3
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务