图解算法笔记| 第一章 二分法与大O表示

274 阅读2分钟

1. 二分查找

二分法是查找元素在一个有序列表中的位置的算法

联系场景:

  • 通讯录查找一个人
  • 给定一个数字,给他划分档位

首先想到的可能会使遍历,遍历所有的人,所有的档位,最差的情况从头遍历到尾部,也就是n个元素遍历n次,

二分法是范围取一半,通过比较大小来判断进入的位置,这也是为什么要有序.

那么二分法最差能进行多少次呢?

元素数量为n,我们进行一次模拟:

次数为x,

次数x剩余的元素数
1n/2
2n/2/2
3n/2/2/2
4n/2/2/2/2
xn/(2^x)

最终剩余元素数为1时候就是我们找到该元素的时候, 2^x=n 求解x的值log2n,通过这个我们看出,遍历的话他的 数量增加速度是y=x是线性的, 而二分法是log2n是对数,增速较慢

练习:

php:

<?php

function findPos($arr,$target){
    $first_index = 0;
    $last_index = count($arr)-1;
    $flag = false;
    while($first_index <= $last_index){
        $mid = ceil(($first_index+$last_index)/2);
        if ($arr[$mid]==$target){
            $flag = $mid;
            return [
                "res"=>true,
                "index"=>$mid
            ];
        }else if($arr[$mid]<$target){
            $first_index=$mid+1;
        }else{
            $last_index = $mid-1;
        }    
    }
    return [
        "res"=>false
    ];
}
$arr = [1,2,3,4];
$target = 1;
$res = findPos($arr,$target);
var_dump($res);

golang:

package main

import "fmt"

func findPos(num []int, target int) (res bool, pos int) {
	first_index := 0
	last_index := len(num) - 1
	for {
		if first_index <= last_index {
			mid := (int)((last_index + first_index) / 2)
			if num[mid] == target {
				return true, mid
			} else if num[mid] > target {
				last_index = mid - 1
			} else {
				first_index = mid + 1
			}
		} else {
			return false, 0
		}
	}
}

func main() {
	num := []int{1, 2, 3, 4, 5, 6}
	target := 2
	res, index := findPos(num, target)
	fmt.Println(res, index)
}

python:

import math
def findPos(lists,target):
    first_index=0
    last_index = len(lists)-1
    while(first_index<=last_index):
        mid=math.ceil((first_index+last_index)/2)
        if lists[mid]==target:
            return mid
        elif lists[mid]<target:
            first_index = mid+1
        else:
            last_index=mid-1
    return None

lists =[1,2,3,4]
target=2
res=findPos(lists,target)
if not res is None:
    print("找到了,位置是:"+str(res))

2. 大O表示法

大O表示法可以理解成算法的求导, 算法的运行时间以不同的速度在增加,大O表示法,表示的是比较的程序运行的次数,大O表示法表示的是最差情况下的操作数.

常见的大O运行的时间:

  • O(logn) 对数时间, 二分法查找
  • O(n) 线性时间, 快速排序算法
  • O(n2) 选择排序
  • O(n!)

3.旅行商问题

旅行商要去5个城市,要算出所有排列的长度,然后挑选出最短的,所以算法就是5x4x3x2x1 这个也就是O(n!)