图解算法JAVA

引言

开始学习算法,准备从《图解算法》这本书开始入门,写的确实通俗易懂、生动有趣,很适合算法入门。可惜的是书中的代码都是使用python来实现的,作为一名Java门下走(菜)狗,准备在学习的过程中,将书中的python代码用Java实现一遍,同时也会记录一些学习过程中的笔记。

第一章 算法简介

1.2 二分查找

二分查找就是一个“对半砍”的查找方式,简单粗暴的每次直接查询当前列表的中间部分,但只能在列表有序时才管用。

方法binary_search用于接收一个有序数组和一个元素。如果指定的元素包含在数组中,这个方法将返回其位置。你将跟踪要在其中查找的数组部分——开始时为整个数组。
首先,我们需要两个属性low和high(名字可以随意)来跟踪要查找的列表部分:
二分查找
如果猜测的数字太大了,我们就需要修改high的值,调整我们下一次猜测的范围(猜测小了就修改low的值):
在这里插入图片描述
直到low和high的范围缩小到只包含一个值。

Python2.7实现二分查找代码:

def binary_serch(list, item):
	# low和high用于跟踪要在其中查找的列表部分,索引low~high就是我们要查找得到范围
	low = 0 #数组索引从0开始
	high = len(list)-1 #数组的最后一个索引=数组长度-1
	
	while low <= high: 
		# 每一次都检查中间的元素
		mid = (low + high) / 2 # 如果(low + high)不是偶数,Python自动将mid向下取整
		guess = list[mid]
		if guess == item:
			return mid
		# 如果猜的数字大了,就相应的修改high,小了就修改low 
		if guess > item:
			high = mid - 1
		else:
			low = mid + 1
	retuen None

my_list = [1, 3, 5, 7, 9] 

print binary_serch(my_list, 3) # => 1	
print binary_serch(my_list, -1) # => None		

Java实现二分查找代码:

/**
 * 最基础的二分查找
 * 《图解算法》1.2Java版
 */
public class BinarySearch {
    public static void main(String[] args) {
        int[] arry = {-5,-4,-3,-2,-1,0,1,2,3,4,5,6,7,8,9,10};
        BinarySearch lin = new BinarySearch();
        Integer res = lin.binarySearch(arry,-5);
        if (res == null){
            System.out.println("数组中不存在该元素");
        }else {
            System.out.println("数组中存在item这个元素,它在数组的索引为" + res);
        }

    }

    /**
     *
     * @param arry 数组
     * @param item 被猜的答案
     * @return
     */
    public Integer binarySearch(int[] arry, int item){

        int low = 0;
        int high = arry.length - 1;

        while (low <= high){
            int mid = (low + high) / 2;
            int guess = arry[mid];
            if (guess > item){
                high = mid - 1;
            }else if (guess < item){
                low = mid + 1;
            }else if (guess == item){
                return mid;
            }
        }
        return null;
    }

}

第二章 选择排序

2.3 选择排序

选择排序就是多次遍历当前队列,每次遍历选出最大或者最小的元素,再插入一个新的队列,直到原本的队列每一个元素都添加到了新的队列当中,则排序完成。算法速度为 O ( n 2 ) O(n^2) O(n2)

假设我们需要对下图的歌单按照播放次数进行排序
在这里插入图片描述
那么首先,我们可以先遍历一遍这个列表,找出其中播放次数最多的乐队,并且将这个乐队添加到一个新的列表中。
在这里插入图片描述
再次这样做,找出播放量第二的乐队。
在这里插入图片描述
继续这样重复,就能获得一个有序列表。
在这里插入图片描述

示例代码Python版
先创建一个findSmallest()函数,用于找出数组中的最小元素

def findSmallest(arr):
 	smallest = arr[0] # smallest存储当前最小的值
 	smallest_index = 0 # smallest_index存储当前最小元素的索引
	 for i in range(1, len(arr)):
		 if arr[i] < smallest: #当arr[i]小于smallest,就将arr[i]的值赋给smallest,此时smallest又是当前的最小值,直到与整个数组进行比较,smallest就是最小值
			smallest = arr[i]
 			smallest_index = i
 	return smallest_index

现在就可以拿这个函数来编写排序算法啦~

def selectionSort(arr):------对数组进行排序
 	newArr = []
 	for i in range(len(arr)):
 		smallest = findSmallest(arr)------找出数组中最小的元素,并将其加入到新数组中
 		newArr.append(arr.pop(smallest))
 	return newArr
 	
print selectionSort([5, 3, 6, 2, 10])

示例代码Java版
不同于之前的二分查找,选择排序的Java实现和python实现有很大的不同,因为Java中并没有pop()函数(用于移除列表中的一个元素)。
但这并不意味着Java就没法实现选择排序,让我们来换一个角度来思考问题:python中我们是通过新建一个列表,将旧列表的元素一个一个移动到新列表中完成排序,那我们能不能就在原有的列表内部直接调整位置来完成排序呢?
当然是可以滴,首先默认列表的最小元素是smallest,最小元素索引是smallest_index。最开始它们为列表的第一个值arry[0],也就是5(但实际上5并不是这个列表的最小值,所以还要后续的比较)
在这里插入图片描述
然后让我们进行一次循环来不断比较,在比较过程中,每当发现比smallest更小的值,就将这个值赋值给smallest,保证smallest是当前的最小值,当列表遍历一次后,我们就能得到列表的最小值。
在这里插入图片描述
获得最小值后,将当前的最小值和列表的第一个值(也就是arry[0])交换位置,再将默认最小值设置为arry[1],继续上一步的操作,从arry[1]开始循环找到最小值,并且将最小值和列表的第二个值交换位置(arry[1]),直至将整个列表排序完成。在这里插入图片描述
示例代码Java版

import java.util.Arrays;

public class SelectionSort {
    public static void main(String[] args) {
        // 需要排序的数组
        int[] arry = {5, 3, 6, 2, 0};
        // 进行选择排序,并返回一个已经排序好的数组
        selecctionSort(arry);
        // 输出已经排序好的数组
        System.out.println("数组排序完毕:"+Arrays.toString(arry));



    }


    /**
     *
     * @param arry
     * @return
     */
    public static int[] selecctionSort(int[] arry){
        //第一层循环,控制交换位置的次数
        for (int i = 0; i < arry.length - 1 ; i++){

            int smallest = arry[i]; //本次交换的假定最小值
            int smallest_index = i; //本次交换假定最小值的索引位置
            //第二层循环,遍历数组,确定最小值
            for (int j = i + 1; j < arry.length; j++){
                if (arry[j] < smallest){
                    smallest = arry[j];
                    smallest_index = j;
                }
            }


            //再把确定的最小值换到假定最小值的位置
            int temp = arry[i];
            arry[i] = smallest;
            arry[smallest_index] = temp;

            System.out.println("第" + (i+1) + "次交换位置结果:" + Arrays.toString(arry));

        }
        return arry;

    }
}

运行结果:
在这里插入图片描述
最后更新时间:2022-1-11(更新中ing…)

第三章 递归

程序调用自身的编程技巧称为递归( recursion)。

书中使用了在嵌套的箱子中找钥匙🔑来解释递归:

  1. 仔细检查盒子A=>在盒子A中发现了盒子B和C,进入盒子B
  2. 检查盒子B=>在盒子中发现了盒子D,进入盒子D
  3. 检查盒子D=>里面什么也没有,是一个空的,return null到盒子B
  4. 返回盒子B=>除了空盒子D外什么也没有,return null到盒子A
  5. 搜索盒子C=>找到钥匙
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值