二分查找实现----面试总结

           今天面试面试官提了一个问题:两万个整数、整数有序、平时不会怎么修改,如何使空间最小查找最快。

           其实论查找速度当然是常数级别的哈希算法最快了,最简单的哈希就是以数组下标做键,对应数组元素做值。但是哈希可能需要解决冲突,而冲突会带来空间的开销。所以在此提出以数组存储、二分查找查询的办法。二分查找的复杂度是log(n)。

           好久没写了,当面竟然没写对,惭愧,回来再好好复习一下。有时候大概懂和能写出来还是有一定距离的。

           2、问题是:一个程序有多个线程如何能够知道是哪个线程出现了死循环。一种是运用工具minidown,另外是利用一个守护进程跟踪线程PC是否一直在某个小范围内移动(其实我不知道怎么实现,以后再想)。

           3、#include<stdio.h>

            #define TOTAL (sizeof(array) / sizeof(array[0]))
            #define TOTAL_ELEMENTS 7

            int array[] = {23,34,12,17,204,99,16};

                 for(int d=-1;d <= TOTAL_ELEMENTS-2;d++)

            这个d会退化为0xfffffff,但是在C++的编译器下这种情况不会发生。

       4、如果一个服务器过了两三天突然崩溃了,会是什么原因:

           第一,内存泄漏
           C/C++程序还可能产生另一个指针问题:丢失对已分配内存的引用。当内存是在子程序中被分 配时,通常会出现这种问题,其结果是程序从子程            序中返回时不会释放内存。如此一来,对已分配的内存的引用就会丢失,只要操作系统还在运行中,则进程就会一 直使用该内存。这样的结果            是,曾占用更多的内存的程序会降低系统性能,直到机器完全停止工作,才会完全清空内存。

           第二,C指针错误
           用C或C++编写的程序,如Web服务器API模块,有可能导致系统的崩溃,因为只要间接引 用指针(即,访问指向的内存)中出现一个错误,就会            导致操作系统终止所有程序。另外,使用了糟糕的C指针的Java模拟量(analog)将访问一个空的 对象引用。Java中的空引用通常不会导致立刻             退出JVM,但是前提是程序员能够使用异常处理方法恰当地处理错误。在这方面,Java无需过多的关注,但 使用Java对可靠性进行额外的度量              则会对性能产生一些负面影响。

          第三,数据库中的临时表不够用
         许多数据库的临时表(cursor)数目都是固定的,临时表即保留查询结果的内存区域。在临时表中的数据都被读取后,临时表便会被释放,但大量            同时进行的查询可能耗尽数目固定的所有临时表。这时,其他的查询就需要列队等候,直到有临时表被释放时才能再继续运行。

          第四,线程死锁
          由多线程带来的性能改善是以可靠性为代价的,主要是因为这样有可能产生线程死锁。线程死锁 时,第一个线程等待第二个线程释放资源,而             同时第二个线程又在等待第一个线程释放资源。我们来想像这样一种情形:在人行道上两个人迎面相遇,为了给对方让 道,两人同时向一侧迈出           一步,双方无法通过,又同时向另一侧迈出一步,这样还是无法通过。双方都以同样的迈步方式堵住了对方的去路。假设这种情况一直持续 下             去,这样就不难理解为何会发生死锁现象了。

          第五,磁盘已满
          导致系统无法正常运行的最可能的原因是磁盘已满。一个好的网络管理员会密切关注磁盘的使用情况,隔一定的时间,就需要将磁盘上的一些负           载转存到备份存储介质中(例如磁带)。日志文件会很快用光所有的磁盘空间。Web服务器的日志文件、SQL*Net的日志文件、 JDBC日志文件,           以及应用程序服务器日志文件均与内存泄漏有同等的危害。可以采取措施将日志文件保存在与操作系统不同的文件系统中。日志文件系统空间已           满时Web服务器也会被挂起,但机器自身被挂起的几率已大大减低。

          第六,服务器超载
          Netscape Web服务器的每个连接都使用一个线程。Netscape Enterprise Web服务器会在线程用完后挂起,而不为已存在的连接提供任何服             务。如果有一种负载分布机制可以检测到服务器没有响应,则该服务器上的负载就可以分布到其 它的Web服务器上,这可能会致使这些服务器             一个接一个地用光所有的线程。这样一来,整个服务器组都会被挂起。操作系统级别可能还在不断地接收新的连接, 而应用程序(Web服务器)             却无法为这些连接提供服务。用户可以在浏览器状态行上看到connected(已连接)的提示消息,但这以后什么也不会发生。
          总之,还有许多因素也极有可能导致Web香港服务器租用或香港服务器托管站点无法工作。有许多种原因可能导致Web站点无法正常工作,这             使得系统地检查所有问题变得很困难。

           

循环实现
第一种
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
int  BinSearch(SeqList *R, int  n,KeyType K)
{
     //在有序表R[0..n-1]中进行二分查找,成功时返回结点的位置,失败时返回-1
     int  low=0,high=n-1,mid; //置当前查找区间上、下界的初值
     while (low<=high)
         {
             if (R[low].key==K)
                 return  low;
             if (R[high].key==k)
                 return  high;     //当前查找区间R[low..high]非空
             mid=low+((high-low)/2);
                 /*使用(low+high)/2会有整数溢出的问题
                 (问题会出现在当low+high的结果大于表达式结果类型所能表示的最大值时,
                     这样,产生溢出后再/2是不会产生正确结果的,而low+((high-low)/2)
                     不存在这个问题*/
                 if (R[mid].key==K)
                     return  mid; //查找成功返回
                           if (R[mid].key<K)
                               low=mid+1; //继续在R[mid+1..high]中查找
                                   else
                                       high=mid-1; //继续在R[low..mid-1]中查找
         }
     if (low>high)
         return  -1; //当low>high时表示所查找区间内没有结果,查找失败
}
第二种
1
2
3
4
5
6
7
8
9
10
11
12
13
14
int  bsearchWithoutRecursion( int  array[], int  low, int  high, int  target)
{
     while (low<=high)
         {
             int  mid=(low+high)/2;
             if (array[mid]>target)
                 high=mid-1;
             else  if (array[mid]<target)
             low=mid+1;
             else
                 return  mid;
         }
     return -1;
}
第三种
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
int  binSearch( const  int  *Array, int  start, int  end, int  key)
{
         int  left,right;
         int  mid;
         left=start;
         right=end;
         while (left<=right)
             
         {
                     mid=(left+right)/2;
                     if (key==Array[mid])   return  mid;
                     else  if (key<Array[mid]) right=mid-1;
                     else  if (key>Array[mid]) left=mid+1;
                 
         }
         return  -1;
}
递归实现(可直接编译)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
#include<iostream>
#include<cstdlib>
#include<cstdio>
#include<cmath>
#include<cstring>
#include<algorithm>
using  namespace  std;
int  a[100]={1,2,3,5,12,12,12,15,29,55}; //数组中的数(由小到大)
int  k; //要找的数字
int  found( int  x, int  y)
{
     int  m=x+(y-x)/2;
     if (x>y) //查找完毕没有找到答案,返回-1
         return  -1;
     else
     {
         if (a[m]==k)
             return  m; //找到!返回位置.
         else  if (a[m]>k)
             return  found(x,m-1); //找左边
          else
             return  found(m+1,y); //找右边
     }
}
int  main()
     {
         cin>>k; //输入要找的数字c语言把cin换为scanf即可
         cout<<found(0,9); //从数组a[0]到a[9]c语言把cout换为printf即可
         return  0;
     }

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值