多遍合并排序

时间:2018-12-17 16:34:46

标签: c++ mergesort array-merge

我有一个功能mergeLists,该函数将d个排序的子列表作为输入,并给出一个排序的合并列表作为输出。看起来如下:

    mergeLists (int d) {
        // Logic to Merge d sorted sub lists
        // Write the single big sorted list to file
    }

现在,当子列表太多时就会出现问题。我不能同时合并所有这些。

编辑:我的代码

struct MinHeapNode 
{ 
    // The element to be stored 
    int element; 

    // index of the array from which the element is taken 
    int i; 
}; 

// Prototype of a utility function to swap two min heap nodes 
void swap(MinHeapNode* x, MinHeapNode* y); 

// A class for Min Heap 
class MinHeap 
{ 
    MinHeapNode* harr; // pointer to array of elements in heap 
    int heap_size;   // size of min heap 

public: 
    // Constructor: creates a min heap of given size 
    MinHeap(MinHeapNode a[], int size); 

    // to heapify a subtree with root at given index 
    void MinHeapify(int); 

    // to get index of left child of node at index i 
    int left(int i) { return (2 * i + 1); } 

    // to get index of right child of node at index i 
    int right(int i) { return (2 * i + 2); } 

    // to get the root 
    MinHeapNode getMin() { return harr[0]; } 

    // to replace root with new node x and heapify() 
    // new root 
    void replaceMin(MinHeapNode x) 
    { 
        harr[0] = x; 
        MinHeapify(0); 
    } 
}; 

// Constructor: Builds a heap from a given array a[] 
// of given size 
MinHeap::MinHeap(MinHeapNode a[], int size) 
{ 
    heap_size = size; 
    harr = a; // store address of array 
    int i = (heap_size - 1) / 2; 
    while (i >= 0) 
    { 
        MinHeapify(i); 
        i--; 
    } 
} 

// A recursive method to heapify a subtree with root 
// at given index. This method assumes that the 
// subtrees are already heapified 
void MinHeap::MinHeapify(int i) 
{ 
    int l = left(i); 
    int r = right(i); 
    int smallest = i; 
    if (l < heap_size && harr[l].element < harr[i].element) 
        smallest = l; 
    if (r < heap_size && harr[r].element < harr[smallest].element) 
        smallest = r; 
    if (smallest != i) 
    { 
        swap(&harr[i], &harr[smallest]); 
        MinHeapify(smallest); 
    } 
} 

// A utility function to swap two elements 
void swap(MinHeapNode* x, MinHeapNode* y) 
{ 
    MinHeapNode temp = *x; 
    *x = *y; 
    *y = temp; 
} 

// Merges two subarrays of arr[]. 
// First subarray is arr[l..m] 
// Second subarray is arr[m+1..r] 
void merge(int arr[], int l, int m, int r) 
{ 
    int i, j, k; 
    int n1 = m - l + 1; 
    int n2 = r - m; 

    /* create temp arrays */
    int L[n1], R[n2]; 

    /* Copy data to temp arrays L[] and R[] */
    for(i = 0; i < n1; i++) 
        L[i] = arr[l + i]; 
    for(j = 0; j < n2; j++) 
        R[j] = arr[m + 1 + j]; 

    /* Merge the temp arrays back into arr[l..r]*/
    i = 0; // Initial index of first subarray 
    j = 0; // Initial index of second subarray 
    k = l; // Initial index of merged subarray 
    while (i < n1 && j < n2) 
    { 
        if (L[i] <= R[j]) 
            arr[k++] = L[i++]; 
        else
            arr[k++] = R[j++]; 
    } 

    /* Copy the remaining elements of L[], if there 
    are any */
    while (i < n1) 
        arr[k++] = L[i++]; 

    /* Copy the remaining elements of R[], if there 
    are any */
    while(j < n2) 
        arr[k++] = R[j++]; 
} 

FILE* openFile(char* fileName, char* mode) 
{ 
    FILE* fp = fopen(fileName, mode); 
    if (fp == NULL) 
    { 
        perror("Error while opening the file.\n"); 
        exit(EXIT_FAILURE); 
    } 
    return fp; 
} 

// Merges k sorted files. Names of files are assumed 
// to be 1, 2, 3, ... d 
void mergeFiles(char *output_file, int d) 
{ 
    FILE* in[d]; 
    for (int i = 0; i < d; i++) 
    { 
        char fileName[2]; 

        // convert i to string 
        snprintf(fileName, sizeof(fileName), "%d", i); 

        // Open output files in read mode. 
        in[i] = openFile(fileName, "r");
        remove(fileName);
    } 

    // FINAL OUTPUT FILE 
    FILE *out = openFile(output_file, "w"); 

    // Create a min heap with k heap nodes. Every heap node 
    // has first element of scratch output file 
    MinHeapNode* harr = new MinHeapNode[d]; 
    int i; 
    for (i = 0; i < d; i++) 
    { 
        // break if no output file is empty and 
        // index i will be no. of input files 
        if (fscanf(in[i], "%d ", &harr[i].element) != 1) 
            break; 

        harr[i].i = i; // Index of scratch output file 
    } 
    MinHeap hp(harr, i); // Create the heap 

    int count = 0; 

    // Now one by one get the minimum element from min 
    // heap and replace it with next element. 
    // run till all filled input files reach EOF 
    while (count != i) 
    { 
        // Get the minimum element and store it in output file 
        MinHeapNode root = hp.getMin(); 
        fprintf(out, "%d ", root.element); 

        // Find the next element that will replace current 
        // root of heap. The next element belongs to same 
        // input file as the current min element. 
        if (fscanf(in[root.i], "%d ", &root.element) != 1 ) 
        { 
            root.element = INT_MAX; 
            count++; 
        } 

        // Replace root with next element of input file 
        hp.replaceMin(root); 
    } 

    // close input and output files 
    for (int i = 0; i < d; i++) {
        fclose(in[i]);
    }

    fclose(out); 
}

您能否建议我做一个调整,通过它我可以实现某种递归或可以执行以下操作的东西:

反复直到只有一个列表,合并d个子列表(开始时有n个子列表,n >> d个)

0 个答案:

没有答案