问答题 现在有一个已排序的字典,请改写二分法检索算法,使之当排序码key在字典中重复出现时算法能找出第一个key出现的元素下标(用*position来保存)。保持算法时间代价为O(logn)。
【正确答案】(1)数据结构
   字典采用的顺序表示法。
   typedef int KeyType;
   typedef int DataType;
   (2)思路
   一般的二分法检索算法只要找出关键码key在字典中的一个下标。在比较的过程中,一旦发现相等,记录下当前下标mid就符合要求。
   (3)二分法检索算法
   int binarySearch(SeqDictionary*pdic,KeyType key,int*position){
       int low,mid,high;
       low=0:
       high=pdic->n-1:
       while(low<=high){
         mid=(low+high)/2;
         if(pdic->element[mid]key==key){
           *position=mid;
           return TRUE:
       }
       else
           if(pdic->element[mid].key>key)
             high=mid-1;
           else
             low=mid+1;
       }
       *position=low;
       return FALSE;
   }
   改写后的算法想要找出关键码key在字典中第一次出现的下标。在比较中,如果遇到相等(key与pdic->element[mid].key相等),则需要分情形讨论。
   ①如果当前下标mid等于0,或者key与pdic->element[mid-1].key不等,那么mid一定是key第一次出现的下标,返回mid即可。
   ②如果情形①不成立,那么mid一定大于等于key第一次出现的下标,需要在low和mid-1之间继续进行搜索,找出key第一次出现的下标。
   下面算法中,加粗的部分是对原算法的修改。
   (4)修改后的二分法检索算法
   int binarySearchl(SeqDictionary*pdic,KeyType key,int*position){
   /*算法结束后,*position存放key第一次出现的下标*/
       int low,mid,high;
       low=0;
       high=pdic->n-1;
       while(low<=high){
         mid=(low+high)/2;
         if(pdic->element[mid].key==key){
           if(mid==0parallel key!=pdie->element[mid-1].key){
           *position=mid;
           return TRUE;
         }    /*此时mid就是key在字典中第一次出现的下标*/
         else high=mid-1;   /*在左半段继续搜索*/
       }
       else
         if(pdic->element[mid].key>key)
           high=mid-1:
         else
           low=mid+1;
       }
       *position=low;
       return FALSE;
   }
   (5)代价分析
   该算法的时间复杂度为O(logn)。
【答案解析】