牛客网修炼之路(冒泡、选择排序)

一位非计算机专业的程序员分享了自己从零开始学习算法的过程,包括数据结构的学习、LeetCode刷题经历及遇到的挑战。文中还详细介绍了如何通过二分查找解决特定问题,并给出了冒泡排序和选择排序的具体实现。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

毕业这一年来,学了挺多东西的,但是学着学着,总是感觉不到进步,所以尝试学习下算法。

因为不是科班出身,所以相关的课程自然没学过,所以前段时间学了下数据结构的知识,开始了(leetcode)刷题之路,但是对我来说真的好难,然后找到牛客网的视频和资料,打算啃完这个再去刷题。

1、一个有序数组A,一个无序数组B,请打印出B中,A不存在的数字。

   //一个有序数组A,一个无序数组B,请打印B中,A不存在的数字
   //使用junit测试工具进行测试
	@Test
	public void test() {
		int[] a = {1,3,4,6,78,89};
		int[] b = {1,5,3,6,2,78};
		//遍历b的时间为n
		for(int i = 0; i < b.length -1; i++) {
			//循环遍历b中的数,判断是否存在a数组中,
			//不存在就打印出对应的数字
            // 判断是否存在的时间为logn
            //所以 n * logn
			if(!flag(b[i],a)) {
				System.out.println(b[i]);
			}
		}
	}
    
	//二分查找,查到返回true,否则返回false
	private boolean flag(int bnum,int[] a) {
        //右标记
		int aright = a.length-1; 
        //左标记
		int aleft = 0;
		int mid = (aright+aleft)/2;
		while(aleft <= aright) {
            //相等就返回true
			if(bnum == a[mid]) {
				return true;
			}
			//小于中间的数,说明中间的数右边是不可能存在
            //和bnum相等的数的(a是递增的),所以右标记往中间左边走
			if(bnum < a[mid]) {
				aright = --mid;
			}
			//大于中间的数,所以左边的数都比bnum要小,因此,左标记要
            //移动到mid的右边
			if(bnum > a[mid]) {
				aleft = ++mid;
			}
		}
		return false;
	}

2、冒泡排序

    @Test
	public void bubleSort() {
		int[] arrs = {1,5,3,2,6,2,78};
        //最外层是遍历数量依次减少,采用打擂台的方式,每次循环
        //找到最大的,放在最末尾,放完后这个数的位置,不参与下次循环
        //直到n-1个数都排完了(n > 0,表示最后一个数就不用找了,它本身就是最大数了),退出循环
		for(int i = arrs.length; i > 0; i--) {
			for(int j = 0; j < arrs.length-1; j++) {
                //前面大的就交换,否则不交换,说明,两个相等的
                //数,他们的位置是稳定的。如果这个大于号,改成
                //大于等于,则表示是不稳定的。说明冒泡排序可以做到
                //稳定的排序
				if(arrs[j] > arrs[j+1]) {
					swap(j,j+1,arrs);
				}
			}
		}
        //遍历结果,查看是否排序正确
		for(int i = 0; i < arrs.length; i++) {
			System.out.println(arrs[i]);
		}
	}
	
    //交换两个数
	private void swap(int j, int i, int[] arrs) {
        int temp = arrs[j];
        arrs[j] = arrs[i];
        arrs[i] = temp;
	}

3、选择排序

    /**
	 * 选择排序跟冒泡有点区别,它每次是找到最小的数,放到起始位置,
	 * 下一次选好,起始位置不参与,那么,当排序完n-1个数后,就
	 * 排完了。
	 */
    @Test
	public void chooseSort() {
    	int[] arrs = {1,5,3,2,6,2,78};
    	for(int i = 0; i < arrs.length-1; i++) {
    		int min = i;//记录最小的数下标
    		for(int j = i+1; j < arrs.length; j++) {
                //也是小于的话才记录,说明也是稳定的排序。
    			if(arrs[j] < arrs[min]) {
    				min = j;
    			}
    		}
            //当前数是否为最小,不是的话,则和最小标记的数交换,
            //同时,该位置下一次循环,不参数。
    		if(min != i) {
                //这个方法跟上述冒泡的交换方法一样
    			swap(min,i,arrs);
    		}
    	}
        //打印数组,查看是否排序正确
    	print(arrs);
	}
	
	private void print(int[] arrs) {
		for(int i = 0; i < arrs.length; i++) {
			System.out.println(arrs[i]);
		}
	}

上述提到的稳定的排序的意思是,当两个数相等的时候,如果他们排完序后,相对为值不变,那么就是稳定的。举个例子,A和

A'这两个相等,且A在A'的前面,那么排完后,同样A在A'的前面,那么就是稳定的。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值