基于有序数据的一些接口,比如二分查找,二分查找某个范围的集合

typedef int (*COMPAREFUNC) (void* pData, void* pValue);

 

/**
 * 在一个有序容器中采用二分法查找一个元素的插入位置
 * @param1 ppArray, 指针数组起始地址指针
 * @param2 count,  指针数组已含有的元素数量
 * @param3 comparefunc,  元素之间的比较函数
 * @param4 pValue,  要查找下标的元素的索引值 指针
 */ 
//int binaryfind(void** ppArray, int count, COMPAREFUNC comparefunc, unsigned int unValue)
int binaryfind(void** ppArray, int count, COMPAREFUNC comparefunc, void* pValue)
{
     assert(NULL != ppArray);
     assert(count >= 0);
     assert(NULL != pValue);

     int iBegin = 0;
     int iEnd = count - 1;
     int iMiddle = 0;
    
     while (iBegin <= iEnd)
     {
           iMiddle = ((unsigned)(iBegin + iEnd)) >> 1;
          
           if (((*comparefunc)(ppArray[iMiddle], pValue)) > 0)
           {
              iEnd = iMiddle - 1;
           }
           else if (((*comparefunc)(ppArray[iMiddle], pValue)) < 0)
           {
              iBegin = iMiddle + 1;
           }
           else
           {
              return iMiddle;
           }
     }
    
     return -1;
}


/**
 * 在一个有序容器中采用二分法查找一个元素的插入位置
 * @param1 ppArray, 指针数组起始地址指针
 * @param2 capacity,  指针数组的容量
 * @param3 count,  指针数组已含有的元素数量
 * @param4 comparefunc,  元素之间的比较函数
 * @param5 unValue,  要查找下标的元素的索引值
 */ 
//int binaryfindwheretoinsert(void** ppArray, int capacity, int count, COMPAREFUNC comparefunc, unsigned int unValue)
int binaryfindwheretoinsert(void** ppArray, int capacity, int count, COMPAREFUNC comparefunc, void* pValue)
{
     assert(NULL != ppArray);
     assert(count >= 0);
     assert(NULL != pValue);
  
     //首先判断容器是否已满
     if (count >= capacity)
     {
        return -1;
     }
    
     //判断容器是否为空
     if (0 == count)
     {
        return 0;
     }
    
     int iBegin = 0;
     int iEnd = count - 1;
     int iMiddle = 0;
    
     //判断是否小于数组头
     if (((*comparefunc)(ppArray[iBegin], pValue)) > 0)
     {
        return 0;
     }
     //判断是否大于数组尾
     else if (((*comparefunc)(ppArray[iEnd], pValue)) < 0)
     {
        return count;
     }
     //判断是否等于数组头
     else if (((*comparefunc)(ppArray[iBegin], pValue)) == 0)
     {
        return -1;
     }
     //判断是否等于数组尾
     else if (((*comparefunc)(ppArray[iEnd], pValue)) == 0)
     {
        return -1;
     }
     //元素在数组中间,采用二分法查找插入位置
     else
     {
         while (iBegin + 1 != iEnd)
         {
            iMiddle = ((unsigned)(iBegin + iEnd)) >> 1;
           
            if (((*comparefunc)(ppArray[iMiddle], pValue)) > 0) 
            {
               iEnd = iMiddle;
            }
            else if (((*comparefunc)(ppArray[iMiddle], pValue)) < 0)
            {
               iBegin = iMiddle;
            }
            else
            {
                return  -1;
            } 
         }
        
         return iEnd;
     }
         
}

/**
 * 将某个值插入有序数组中, 该函数的position必然由 binaryfindwheretoinsert函数求出,已经处理各种情况,这里只管插入
 * 这里的都是指针数组
 * @param1 ppArray, 指针数组起始地址指针
 * @param2 capacity,  指针数组的容量
 * @param3 count,  指针数组已含有的元素数量
 * @param4 position,  元素之间的比较函数
 * @param5 pValue,  插入的元素
 */ 
void insertsortarray(void** ppArray, int capacity, int* pCount, int position, void* pValue)
{
     assert(NULL != ppArray);
     assert(NULL != pCount);
     assert(*pCount < capacity);
     assert(position < capacity);
     assert(NULL != pValue);
     assert(*pCount >= 0);
     assert(position >= 0);
     assert(position <= *pCount);
    

     //移动内存
     memmove(ppArray + position + 1, ppArray + position, 4 * (*pCount - position));
     ppArray[position] = pValue;
     (*pCount)++;
}

/**
 * 该函数的position必然由 binaryfind函数求出,已经处理各种情况,这里只管删除
 * 这里的都是指针数组
 * @param1 ppArray, 指针数组起始地址指针
 * @param2 capacity,  指针数组的容量
 * @param3 pCount,  指针数组已含有的元素数量指针
 * @param4 position,  要删除元素的位置
 */ 
void deletesortarray(void** ppArray, int capacity, int* pCount, int position)
{
     assert(NULL != ppArray);
     assert(NULL != pCount);
     assert(*pCount < capacity);
     assert(position < capacity);
     assert(capacity > 0);
     assert(*pCount >= 0);
     assert(position >= 0);
     assert(position <= *pCount);
    
     //保存要删除的地址
     void* pDelete = ppArray[position];
    
     //释放删除地址对应的空间
     free(pDelete);
    
     //移动内存
     memmove(ppArray + position, ppArray + position + 1, 4 * (*pCount - position -1));

     //数组长度减一
     *pCount = *pCount - 1;
}


void destroyall(void** ppArray, int count)
{
     assert(NULL != ppArray);
    
     for (int i = 0; i < count; ++i)
     {
         void* pDelete = ppArray[i];
        
         free(pDelete);
     }
    
     free(ppArray);
}


/**
 * 在一个有序容器中采用二分法查找一个元素的位置低位插入位置
 * @param1 ppArray, 指针数组起始地址指针
 * @param2 capacity,  指针数组的容量
 * @param3 count,  指针数组已含有的元素数量
 * @param4 comparefunc,  元素之间的比较函数
 * @param5 pValue,  要查找下标的元素的索引值
 */ 
int binaryfindlowposition(void** ppArray, int capacity, int count, COMPAREFUNC comparefunc, void* pValue)
{
 assert(NULL != ppArray);
      assert(count >= 0);
      assert(NULL != pValue);

 //判断容器是否为空
      if (0 == count)
      {
         return -1;
      }
    
      int iBegin = 0;
      int iEnd = count - 1;
      int iMiddle = 0;
    
      //判断是否小于数组头
      if (((*comparefunc)(ppArray[iBegin], pValue)) > 0)
      {
         return 0;
      }
      //判断是否大于数组尾
      else if (((*comparefunc)(ppArray[iEnd], pValue)) < 0)
      {
        return -1;
      }
      //判断是否等于数组头
      else if (((*comparefunc)(ppArray[iBegin], pValue)) == 0)
      {
        return 0;
      }
      //判断是否等于数组尾
      else if (((*comparefunc)(ppArray[iEnd], pValue)) == 0)
      {
        return count -1;
      }
      //元素在数组中间,采用二分法查找插入位置
      else
      {
          while (iBegin + 1 != iEnd)
          {
              iMiddle = ((unsigned)(iBegin + iEnd)) >> 1;
           
              if (((*comparefunc)(ppArray[iMiddle], pValue)) > 0) 
              {
                 iEnd = iMiddle;
              }
              else if (((*comparefunc)(ppArray[iMiddle], pValue)) < 0)
              {
                 iBegin = iMiddle;
              }
              else
              {
                  return  iMiddle;
              } 
         }
        
         return iEnd;
     }
}

/**
 * 在一个有序容器中采用二分法查找一个元素的位置高位插入位置
 * @param1 ppArray, 指针数组起始地址指针
 * @param2 capacity,  指针数组的容量
 * @param3 count,  指针数组已含有的元素数量
 * @param4 comparefunc,  元素之间的比较函数
 * @param5 pValue,  要查找下标的元素的索引值
 */ 
int binaryfindhighposition(void** ppArray, int capacity, int count, COMPAREFUNC comparefunc, void* pValue)
{
 assert(NULL != ppArray);
      assert(count >= 0);
      assert(NULL != pValue);

 //判断容器是否为空
      if (0 == count)
      {
         return -1;
      }
    
      int iBegin = 0;
      int iEnd = count - 1;
      int iMiddle = 0;
    
      //判断是否小于数组头
      if (((*comparefunc)(ppArray[iBegin], pValue)) > 0)
      {
         return -1;
      }
      //判断是否大于数组尾
      else if (((*comparefunc)(ppArray[iEnd], pValue)) < 0)
      {
        return count -1;
      }
      //判断是否等于数组头
      else if (((*comparefunc)(ppArray[iBegin], pValue)) == 0)
      {
        return 0;
      }
      //判断是否等于数组尾
      else if (((*comparefunc)(ppArray[iEnd], pValue)) == 0)
      {
        return count -1;
      }
      //元素在数组中间,采用二分法查找插入位置
      else
      {
          while (iBegin + 1 != iEnd)
          {
              iMiddle = ((unsigned)(iBegin + iEnd)) >> 1;
           
              if (((*comparefunc)(ppArray[iMiddle], pValue)) > 0) 
              {
                 iEnd = iMiddle;
              }
              else if (((*comparefunc)(ppArray[iMiddle], pValue)) < 0)
              {
                 iBegin = iMiddle;
              }
              else
              {
                  return  iMiddle;
              } 
         }
        
         return iEnd - 1;
     }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值