简体   繁体   English

Mergesort 的这个合并函数需要 O(1) 空间还是 O(n) 空间?

[英]Does this merge function of Mergesort take O (1) space or O(n) space?

private ListNode merge(ListNode list1, ListNode list2) {
    ListNode dummy = new ListNode(0);
    ListNode curr = dummy;
    while (list1 != null && list2 != null) {
        if (list1.val < list2.val) {
            curr.next = list1;
            list1 = list1.next;
        } else {
            curr.next = list2;
            list2 = list2.next;
        }
        curr = curr.next;
    }
    if (list1 == null) {
        curr.next = list2;
    } else {
        curr.next = list1;
    }
    return dummy.next;
}

Here I believe due to " curr" node it takes O(n) space as curr node would gradually contain complete linked list.在这里,我相信由于“curr”节点,它需要 O(n) 空间,因为 curr 节点将逐渐包含完整的链表。

This merge function uses O(1) space.merge函数使用O(1)空间。 Aside from the local variables which have a constant size, it only allocates a single ListNode in ListNode dummy = new ListNode(0);除了具有恒定大小的局部变量外, ListNodeListNode dummy = new ListNode(0);分配单个ListNode ListNode dummy = new ListNode(0);

The rest of the function just changes the next members of the list elements pointed to by list1 and list2 .该函数的其余部分只是更改list1list2指向的列表元素的next成员。

It is possible to modify the function to not even allocate a single extra object by writing an initial test to select the initial node of the resulting list.通过编写初始测试来选择结果列表的初始节点,可以修改函数,甚至不分配单个额外对象。

Combining this function with a top down recursive approach or a bottom up iterative one yields a sorting algorithm with an O(log(N)) space complexity and a O(N.log(N)) time complexity.将此函数与自上而下的递归方法或自下而上的迭代方法相结合,可以生成具有O(log(N))空间复杂度和O(N.log(N))时间复杂度的排序算法。

To achieve stable sort, the comparison operator should be changed to <= .为了实现稳定排序,比较运算符应该更改为<=

Here is a modified version without any allocation:这是一个没有任何分配的修改版本:

private ListNode merge(ListNode list1, ListNode list2) {
    Listnode head, curr;
    if (list1 == null)
        return list2;
    if (list2 == null)
        return list1;
    if (list1.val <= list2.val) {
        curr = head = list1;
        list1 = list1.next;
    } else {
        curr = head = list2;
        list2 = list2.next;
    }
    while (list1 != null && list2 != null) {
        if (list1.val <= list2.val) {
            curr = curr.next = list1;
            list1 = list1.next;
        } else {
            curr = curr.next = list2;
            list2 = list2.next;
        }
    }
    curr.next = (list1 != null) ? list1 : list2;
    return head;
}

Here is a modified version with fewer tests in most cases:这是在大多数情况下测试较少的修改版本:

private ListNode merge(ListNode list1, ListNode list2) {
    Listnode head, curr;
    if (list1 == null)
        return list2;
    if (list2 == null)
        return list1;
    if (list1.val <= list2.val) {
        curr = head = list1;
        list1 = list1.next;
        if (list1 == null) {
            curr.next = list2;
            return head;
        }
    } else {
        curr = head = list2;
        list2 = list2.next;
        if (list2 == null) {
            curr.next = list1;
            return head;
        }
    }
    for (;;) {
        if (list1.val <= list2.val) {
            curr = curr.next = list1;
            list1 = list1.next;
            if (list1 == null) {
                curr.next = list2;
                return head;
            }
        } else {
            curr = curr.next = list2;
            list2 = list2.next;
            if (list2 == null) {
                curr.next = list1;
                return head;
            }
        }
    }
}

In C or C++, the original code can be changed to avoid allocation with pointers:在 C 或 C++ 中,可以更改原始代码以避免使用指针进行分配:

static ListNode *merge(ListNode *list1, ListNode *list2) {
    ListNode *head = NULL;
    ListNode **nextp = &head;
    while (list1 && list2) {
        if (list1->val <= list2->val) {
            *nextp = list1;
            nextp = &list1->next;
            list1 = list1->next;
        } else {
            *nextp = list2;
            nextp = &list2->next;
            list2 = list2->next;
        }
    }
    *nextp = list1 ? list1 : list2;
    return head;
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM