【读书笔记】《大学算法教程》——chpt4.搜索

本文详细阐述了计算机科学领域内的关键算法与技术,包括对分搜索、深度优先搜索、广度优先搜索、拓扑排序、回溯法等算法的原理与应用,以及前端开发、后端开发、移动开发等技术领域的最新进展。文章旨在为读者提供全面的技术视角,助其深入理解计算机科学的基础与前沿。
 


by Richard Johnsonbaugh Marcus Schaefer

4.1 对分搜索

      本算法在非降序数组L[i],…,L[j]中搜索值key。如果找到key,则回送下表k,L[k]等于key。如果没有找到key,则回送-1(假定-1不是一个有效的下表)。

Input Parameters: L,i,j,key
Output Parameters: None 
bsearch(L,i,j,key){
	while(i<=j){		k=(i+j)/2	
	if(key==L[k])//找到		  return k	
	if(key<L[k])// 查找第一部分		  j= k-1		else//查找第二部分		  i=k+1
	}
	return -1
}


 

对规模n的输入,bsearch的最坏情况时间为O(lgn)。

4.2 深度优先搜索

       本算法在具有顶点1,…,n的图中,从顶点start开始执行深度优先搜素,并将顶点以访问先后的次序输出。

       图用邻接表表示;与顶点i相邻的那些顶点用一个链接表表示,adj[i]是对连接表中第一个节点的索引。每个节点的成员包括与i相邻的顶点ver,以及对链接表中下一个节点的索引next,对链接表中最后一个节点来说,其next的值为null。

       为了跟踪已访问的顶点,使用数组visit;若顶点i已访问,则置visit[i]为真,否则为假。

Input Parameters:  adj,start
Output Parameters:  None
dfs(adj,start){
	n = adj.last
	for i = 1 to n		visit[i] = false
	dfs_recurs(adj,start)
}
dfs_recurs(adj,start){
	println(start)
	visit[start] = true
	trav = adj[start]
	while(trav != null){		v = trav.ver		if(!visit[v])		
	dfs_recurs(adj,v)	
	trav = trav.next
	}
}


 

 小结:

   1.一个有m条边,n个顶点的图,dfs以时间O(m+n)运行。

   2.dfs 与 图的规模成线性关系。

   3.dfs检测图是否连通:任意顶点为起始顶点,运行dfs。图是连通的,当且仅当全部节点被访问到。

4.3 广度优先搜索

    本算法在有顶点1,…,n的图中从顶点start开始执行广度优先搜索,并将顶点以访问先后的次序输出。

    图用邻接表表示;与顶点i相邻的那些顶点用一个链接表表示,adj[i]是对连接表中第一个节点的索引。每个节点的成员包括与i相邻的顶点ver,以及对链接表中下一个节点的索引next,对链接表中最后一个节点来说,其next的值为null。

    数组visit跟踪访问过的顶点,队列q存放待处理的当前顶点。q.enqueue(val) 将val加入q;q.front会送q队列首部的值,但不删除;q.dequeue删除q队列首部的项;q.empty(),若q唯恐返回真,否则为假。

   

Input Parameters: adj,start
Output Parameters:  None

bfs(adj,start){
     n = adj.last
     for i = 1 to n
          visit[i] = false
     visit[start] = true
     println(start)
     //q是一个初始为空的队列
   q.enqueue(start)
    while(!q.empty()){
          current = q.front()
          q.dequeue()
          trav = adj[current]
          while(trav!=null){
               v = trav.ver
               if(!visit[v]){
                     visit[v]=true
                     println(v)
                     q.euqueue(v)
               }
               trav.trav.next
          }
    }
}


  小结:

   1. 一个有m条边,n个顶点的图,bfs以时间O(m+n)运行。

   2. 使用广度优先搜索寻找最短路径长度

4.4 拓扑排序

   本算法计算一个有顶点1,…,n的有向非循环的拓扑排序。拓扑排序中的顶点存放于数组ts。

   图用邻接表表示;与顶点i相邻的那些顶点用一个链接表表示,adj[i]是对连接表中第一个节点的索引。每个节点的成员包括与i相邻的顶点ver,以及对链接表中下一个节点的索引next,对链接表中最后一个节点来说,其next的值为null。数组vist跟踪访问过的节点。

Input Parameters: adj
Output Parameters: ts

top_sort(adj,ts){
    n=adj.last    //k是ts中的下标,拓扑排序中的下一个顶点存放在ts。
    //假定k在top_sort_recurs中可见
    k=n    for i = 1 to n
       visit[i] = false
    for i = 1 to n 
       if(!visit[i]) 
           top_sort_recurs(adj,i,ts)  
 
}
 top_sort_recurs(adj,start,ts){
    visit[start] = true
    trav = adj[start]
    while(trav != null){
        v = trav.ver
        if(!visit[v]) 
           top_sort_recurs(adj,v,ts)
        trav = trav.next
    }
    ts[k] = start
    k = k-1
}


 

   1.  可以利用深度有限速锁构建一个有向非循环拓扑排序。假定从G的任意一个起始顶点v1开始运行深度优先搜索。深度优先搜索先访问v1,然后从v1访问一个未访问顶点v2,等。最后dfs达到一个顶点vk,这个顶点没有(vk,v')的边,其中v'未被访问过。因为如果有这样一条边,v'就会被访问,而图就会包含一个有向环路。

   这个事实可以用来确定任意一个有向图是否是有向非循环图

   2. 一个有m条边,n个顶点的图是拓扑排序的输入,调用总时间为O(m+n)。

4.5 回溯法

涉及 n王后问题和哈密尔顿环路问题

回溯算法的形式:

   假定回溯算法解一个问题,其解有形式 x[1],…,x[n],在假定x[i]的值是在集S里,回溯算法的一般形式为:

backtrack(n){
      rbacktrack(1,n)
}

rbacktrack(k,n){
      for each x[k]∈S
            if(bound(k))
                if( k==n ){
                      //输出一个结果。若只要一个结果,则停止
                for i = 1 to n
                            print(x[i]+" "
                       println()
                }
                else
                      rbacktrack(k+1,n)
}
 

函数bound(k)假定x[1],…,x[k-1]是部分解,并且x[k]已经赋予一个值。于是,如果x[1],…,x[k]是一个部分解,则回送真,否则回送假。

      编写一个的高效的界定函数,它可以从搜索树中消除不少可能的节点。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值