Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/arrays/13.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Arrays 在展开链表中查找k-最小数的二进制搜索_Arrays_C_Linked List_Binary Search - Fatal编程技术网

Arrays 在展开链表中查找k-最小数的二进制搜索

Arrays 在展开链表中查找k-最小数的二进制搜索,arrays,c,linked-list,binary-search,Arrays,C,Linked List,Binary Search,我将序列存储在展开的链表中,以处理其他操作(插入、删除、反转),并在每个节点中的每个操作后维护排序数组,以实现高效的k-least查询。 我使用了两种二进制搜索,一种是在k-least函数中,另一种是在lessunt和lessthanCount中。假设数字介于10^5和-10^5之间,第一类是确定mid是大于还是小于k-最小数。第二种是对每个节点进行二进制搜索并将结果相加,得到中间节点的顺序范围 我认为时间复杂度是O(lg(arraysize)*n/arraysize),我设置arraysize

我将序列存储在展开的链表中,以处理其他操作(插入、删除、反转),并在每个节点中的每个操作后维护排序数组,以实现高效的k-least查询。
我使用了两种二进制搜索,一种是在k-least函数中,另一种是在lessunt和lessthanCount中。假设数字介于10^5和-10^5之间,第一类是确定mid是大于还是小于k-最小数。第二种是对每个节点进行二进制搜索并将结果相加,得到中间节点的顺序范围

我认为时间复杂度是O(lg(arraysize)*n/arraysize),我设置arraysize=sqrt(n)以在k-least查询和其他操作之间取得平衡

然而,该计划仍然不够有效。有没有办法在不调整arraysize的情况下提高k-least查询操作

int lessCount(int x, LinkNode *node){
    if (node->size == 0)
        return 0;
    int left = 0;
    int right = node->size;
    while (left < right){
        int mid = (left + right) / 2;
        if (node->sorted[mid] >= x){
            right = mid;
        }else if (node->sorted[mid] < x) {
            left = mid + 1;
        }
    }
    return left;
}
int lessthanCount(int x, LinkNode *node){
    if (node->size == 0)
        return 0;
    int left = 0;
    int right = node->size;
    while (left < right){
        int mid = (left + right) / 2;
        if (node->sorted[mid] <= x) {
            left = mid + 1; 
        }else if (node->sorted[mid] > x) {
            right = mid;
        }
    }

    return left;
}
int k_least(LinkNode *start, LinkNode *end, int nodeLen, int k){
    LinkNode *ptr;
    int max = 100001;
    int min = -100000;
    int mid = (max + min) / 2;
    while (true){
        int lower = 0, upper = 0;
        ptr = start;
        for (int i = 0; i < nodeLen; i++){
            lower += lessCount(mid, ptr);
            upper += lessthanCount(mid, ptr);
            ptr = ptr->next;
        }
        lower += lessCount(mid, end);
        upper += lessthanCount(mid, end);
        if (k <= lower){
            max = mid - 1;
            mid = (max + min) / 2;
        }else if (k > upper){
            min = mid + 1;
            mid = (max + min) / 2;
        }else{
            break;
        }
    }
    return mid;
}
int-lessunt(int-x,LinkNode*node){
如果(节点->大小==0)
返回0;
int左=0;
int right=节点->大小;
while(左<右){
int mid=(左+右)/2;
如果(节点->排序的[mid]>=x){
右=中;
}else if(节点->已排序[中间]大小==0)
返回0;
int左=0;
int right=节点->大小;
while(左<右){
int mid=(左+右)/2;
如果(节点->已排序的[mid]已排序的[mid]>x){
右=中;
}
}
左转;
}
int k_最小值(LinkNode*开始,LinkNode*结束,int nodeLen,int k){
LinkNode*ptr;
int max=100001;
最小整数=-100000;
int mid=(最大+最小)/2;
while(true){
整数下限=0,上限=0;
ptr=启动;
for(int i=0;inext;
}
下部+=下部(中部、末端);
上限+=下限计数(中间、末端);
if(k上){
最小值=中间值+1;
中间=(最大+最小)/2;
}否则{
打破
}
}
中途返回;
}

它必须是一个展开的链表吗?考虑到有大量的操作(最多50000个),包括删除、插入和反转,并且序列长度可能高达50000,我想不出任何其他数据结构。我建议使用B-树。它与数组块具有相同的优势,但它也可以按排序顺序维护所有内容。您可以扩展它以存储每个节点中较小值的数量,并保持更新。还可以考虑自平衡搜索树族中的其他数据结构。