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;
}
}