实现kway合并排序

2024-10-08 19:24:08 发布

您现在位置:Python中文网/ 问答频道 /正文

import random as r
import heapq as h

n = 4
yo = 0
jk = []
o = []
l = 0

for ih in range(0, 5):
    jk = []

    for i in range(n):
        t = r.randint(0, 10)
        jk.append(t)

    jk.sort()    
    o.append(jk)

for i in o:
    print(i)

def ksort(l, a, b, c):
    print('c=', end='')
    print(c)
    print()

    for i in range(len(a)):
        if a[i] > (len(l[i])):
            a[i] = -3

    for i in range(len(l)):
        if a[i] >= 0:
            b[i] = l[i][a[i]]

    h.heapify(b)

    #print(a)
    #print(b)

    c.append(b[0])

    yu = b[0]
    op = 0
    for i in range(len(l)):
        if a[i] >= 0 and (l[i][a[i]] == yu) and op == 0:
            a[i] += 1
            b[i] = l[i][a[i] + 1]
            op = 1
    ksort(l, a, b, c)

ju = ksort(o, [0, 0, 0, 0, 0], [0, 0, 0, 0, 0], [])

ju

enter image description here

我正在使用上面的代码实现k路合并排序。我为每个单独的列表选择的长度是4。但在某一点之后,由于超出范围的错误,它崩溃了。有人能提出什么建议吗


Tags: andinimportforlenifasrange
1条回答
网友
1楼 · 发布于 2024-10-08 19:24:08

当所有元素都已合并时,代码未检查终止条件。还有一些其他问题或不需要的代码。我修改了问题代码,它似乎在工作

import random as r
import heapq as h

def ksort(l):
    a = [0]*len(l)
    c = []
    while True:
        for i in range(len(a)):
            if a[i] >= (len(l[i])):
                a[i] = -1
        j = 0                       #check if done
        for i in range(len(a)):
            if a[i] == -1:
                j = j + 1
        if j == len(a):
            return c
        b = []
        for i in range(len(l)):
            if a[i] >= 0:
                b.append(l[i][a[i]])
        h.heapify(b)                #only used to find smallest element
        c.append(b[0])
        yu = b[0]                   #scan for b[0] and advance corresponding index
        op = 0
        for i in range(len(l)):
            if a[i] >= 0 and (l[i][a[i]] == yu) and op == 0:
                a[i] += 1
                #b[i] = l[i][a[i] + 1]
                op = 1

n = 4
yo = 0
jk = []
o = []
l = 0

for ih in range(0, 5):
    jk = []

    for i in range(n):
        t = r.randint(0, 10)
        jk.append(t)

    jk.sort()    
    o.append(jk)

ju = ksort(o)

print(ju)

使用堆进行C++ k方式合并排序的例子。注意,由于堆开销,K路合并排序比传统的合并排序慢。K路与堆合并的典型用法是在执行外部(磁盘驱动器)排序时使用。标准的基于内存的排序用于创建一组已排序的临时文件(根据可用内存一次创建一个文件),然后使用K方式合并临时文件,直到生成单个已排序的文件。但是,4路合并排序可以使用嵌套的if语句而不是堆来实现,并且比传统的2路合并排序快15%

static void MergeSort(uint64_t *a, size_t n)
{
    uint64_t *b = new uint64_t [n];             // second buffer
    uint64_t *t = b;                            // backup of ptr to b
    std::pair<size_t, size_t>h[K];              // heap
    size_t s = 1;                               // run size
    while(s < n){
        size_t i = 0, k, o = 0;
        while(i < n){
            for(k = 0; k < K && i < n; k++){    // init run indexes
                h[k].first  = i;
                i = min(i+s, n);
                h[k].second = i;
            }
            std::make_heap(h+0, h+k,            // create heap
                [&a](std::pair<size_t, size_t>i, std::pair<size_t, size_t>j){
                    return a[i.first] > a[j.first];});
            while(k){                           // merge heap into b[]
                std::pop_heap(h+0, h+k,         //  pop run with smallest element
                    [&a](std::pair<size_t, size_t>i, std::pair<size_t, size_t>j){
                        return a[i.first] > a[j.first];});
                 k;
                b[o++] = a[h[k].first++];       //  copy element
                if(h[k].first == h[k].second)   //  if end run continue
                    continue;
                ++k;                            //  else update heap
                std::push_heap(h+0, h+k,
                    [&a](std::pair<size_t, size_t>i, std::pair<size_t, size_t>j){
                        return a[i.first] > a[j.first];});
                }
            }
            s *= K;                             // bump run size
            std::swap(a, b);                    // swap ptrs
        }
    if(t == a)                                  // if sorted data is in what was originally b
        std::memcpy(b, a, n*sizeof(uint64_t));  //  copy to what was orignally a
    delete[] t;                                 // delete what was originally b
}

相关问题 更多 >

    热门问题