• 多路归并


       问题:设计一个算法将k个有序链表合并成一个有序链表,已知k个链表总元素个数为n.

           算法要求的复杂度是O(nlogk),可以采用最小堆来实现k路归并,具体算法如下:

           1.取出k个链表头结点调准成一个最小堆heap[k];

           2.取出堆heap中的最小值,然后将该最小值下一个结点放在heap[0]位置,然后调准heap再次成为最小堆。入过该最小值下一个结点不存在,就删除heap[0],调准最小堆heap,元素个数减一。

           3.重复步骤2,知道k个链表都为空。

    c++代码如下:

    #include<iostream>
    using namespace std;
    struct Node {
        int value;
        Node*next;
    };
    Node *Build_Node(int m); //创建元素个数为m的链表
    void MinHeap_Pihy(Node *A[], int n, int i);
    void BuildMinHeap(Node *A[], int n); //建立最小堆
    Node*Push(Node*A[], int n); //返回堆顶元素并且堆元素个数减一
    Node*MergeK(Node*heap[], int k, int n); //K路归并
    void Print_Node(Node*head) {
        Node*p = head;
        while (p) {
            cout << p->value << " ";
            p = p->next;
        }
        cout << endl;
    }
    int main() {
        int m1, m2, m3;
        Node*heap[3]{ NULL };
        cin >> m1;
        heap[0] = Build_Node(m1);
        cin >> m2;
        heap[1] = Build_Node(m2);
        cin >> m3;
        heap[2] = Build_Node(m3);
        Node*head = MergeK(heap, 3, m1 + m2 + m3);
        Print_Node(head);
        return 0;
    }
    Node *Build_Node(int m) {
        Node*head = new Node;
        Node*p1 = head, *p2 = head;
        cin >> head->value;
        for (int i = 1; i < m; i++) {
            p1 = new Node;
            cin >> p1->value;
            p2->next = p1;
            p2 = p2->next;
        }
        p2->next = NULL;
        return head;
    }
    void MinHeap_Pihy(Node*A[], int n, int i) { //在A中调准第i个元素向下过滤
        int left, child;
        for (left = i * 2 + 1; left <n; left = i * 2 + 1) {
            child = i;
            if (A[left]->value<A[child]->value)
                child = left;
            if (left + 1 <n&&A[left + 1]->value<A[child]->value)
                child = left + 1;
            if (i == child)
                break;
            swap(A[child], A[i]);
            i = child;
        }
    }
    void BuildMinHeap(Node* A[], int n) {
        for (int i = n / 2 - 1; i >= 0; i--)
            MinHeap_Pihy(A, n, i);
    }
    Node*Push(Node*A[], int n) {
        Node*p = A[0];
        A[0] = A[n - 1];
        MinHeap_Pihy(A, n - 1, 0);
        return p;
    }
    Node*MergeK(Node*heap[], int k, int n) {
        Node*head = new Node; //设置一个空头结点
        Node*p1 = head, *p2 = head;
        BuildMinHeap(heap, k);
        for (int i = 0; i < n; i++) {
            if (heap[0]->next == NULL) { //堆顶元素下一个结点为空时
                p1 = Push(heap, k);
                k--;
            }
            else {
                p1 = heap[0];
                heap[0] = p1->next;
                MinHeap_Pihy(heap, k, 0);
            }
            p2->next = p1;
            p2 = p2->next;
        }
        p2->next = NULL;
        p1 = head;
        head = head->next;
        delete p1; //删除空头结点
        return head;
    }
  • 相关阅读:
    java基础2(Map)
    java基础1
    数据类型
    入门&常量&变量
    spark 机器学习 朴素贝叶斯 原理(一)
    spark 机器学习 knn 代码实现(二)
    spark 机器学习 knn原理(一)
    spark 机器学习 ALS原理(一)
    数学符号表及读法
    spark 机器学习基础 数据类型
  • 原文地址:https://www.cnblogs.com/td15980891505/p/5166678.html
Copyright © 2020-2023  润新知