当前位置: 首页 > 知识库问答 >
问题:

单链表合并排序

孔欣可
2023-03-14

我试图借助单链表编写合并排序,节点定义如下,

public class Node {

    public int item;
    public Node next;

    public Node(int val) {
        this.item = val;
    }

    public Node() {

    }

    @Override
    public String toString() {
        return "Node{" +
                "item=" + item +
                ", next=" + next +
                '}';
    }
}

合并排序的工作方式如下:

i、 将未排序的列表划分为n个子列表,每个子列表包含1个元素(1个元素的列表被视为已排序)。

二、。重复合并子列表以生成新排序的子列表,直到只剩下1个子列表。这将是排序列表。代码如下所示。

public class MergesortWithSinglyLL {

    private Node head;

    public MergesortWithSinglyLL() {
        head = null;
    }

    public boolean isEmpty() {
        return (head == null);
    }

    public void insert(int val) {

        Node newNode = new Node(val);

        newNode.next = head;
        head = newNode;
    }

    // get the end of the queue
    public Node getHead() {
        return head;
    }


    /*
     Initially, this method is called recursively till there will be only one node
     */

    // this mergeSort returns the head of the sorted LL
    public Node mergeSort(Node head) {

        /*
            list is null or just one node is prevail
         */
        if (head == null || head.next == null) {
            return head;
        }

        Node a = head;
        Node b = head.next;

        while ((b != null) && (b.next != null)) {
            head = head.next;
            b = (b.next).next;
        }

        b = head.next;

        // split the list in 2 parts now
        head.next = null;

        return merge(mergeSort(a), mergeSort(b));
    }

    // This is the merge method provided.

    public Node merge(Node a, Node b) {

        Node head = new Node();
        Node c = head;

        while ((a != null) && (b != null)) {

            if (a.item <= b.item) {
                c.next = a;
//                c = a;
                c = c.next;
                a = a.next;
            } else {
                c.next = b;
//                c = b;
                c = c.next;
                b = b.next;
            }
        }

        // define the last element of the ll
        c.next = (a == null) ? b : a;
        return head.next;
    }


    public void display() {

        Node current = head;
        String result = "";

        while (current != null) {
            result += " " + current.item + " ";
            current = current.next;
        }
        System.out.println(result);
    }
}

我像这样打入会电话,

    int[] arr = {12, 3, 4, 56, -7, -6, -5, 1};

    MergesortWithSinglyLL merges = new MergesortWithSinglyLL();

    for (int i = 0; i < arr.length; i++) {
        merges.insert(arr[i]);
    }

    merges.mergeSort(merges.getHead());
    merges.display();

结果是,所有负值似乎都消失了。这里有什么问题?

共有1个答案

景哲
2023-03-14

您的实现很好,错误在您所称的初始化调用中。

MergeSort返回排序列表,但您不分配它,因此您最终会得到解决方案的子集。

如果你更换这条线

merges.mergeSort(merges.getHead());

用这条线

merges.head = merges.mergeSort(merges.getHead());

(当然,您必须公开MergesortWithSinglyLL.head)

结果,您将看到您获得了正确的排序列表。

 类似资料:
  • 我在C语言课程考试前练习一些算法问题,我被这个问题卡住了(至少3个小时甚至4个小时),我不知道如何回答: 您有两个已排序的循环单链接列表,必须合并它们并返回新循环链接列表的标题,而不创建任何新的额外节点。返回的列表也应该进行排序。 节点结构为: 我尝试了很多方法(递归和非递归),但都没有解决问题。 谢谢你的帮助。

  • 有什么算法让它成为一个链表的并行排序值得吗? 众所周知,合并排序是用于排序链表的最佳算法。 大多数合并排序都是根据数组来解释的,每一半都是递归排序的。这将使并行化变得微不足道:对每一半独立排序,然后合并两半。 但是链表没有“中途”点;链表一直持续到结束: 头→[a]→[b]→[c]→[d]→[e]→[f]→[g]→[h]→[i]→[j]→… 我现在使用的实现遍历列表一次以获取计数,然后递归地拆分计

  • 我试图用C语言合并排序列表。我在法语维基百科上看到了这里的代码,但它给了我一个不正确的列表(即未排序)。不过,该函数编译得很好。请注意,我并没有真正使用top,我可能很快就会把它从结构中去掉。你能帮我找出这个代码的错误吗?我必须把它从算法伪代码翻译成C代码。非常感谢。 是未排序的输入列表。是列表的长度。

  • 合并排序通常是对链表排序的首选方式。链表缓慢的随机访问性能使得一些其他算法(如quicksort)表现不佳,而另一些算法(如heapsort)则完全不可能。我一直在努力在链表上做归并排序。它不断返回一个错误。我正在提供我试图执行的代码。请一定要帮我。它不断给出运行时错误。

  • NowCoder 题目描述 解题思路 递归 // java public ListNode Merge(ListNode list1, ListNode list2) { if (list1 == null) return list2; if (list2 == null) return list1; if (list1.val <= lis

  • 假设列表“A”是1- 请回顾一下这个,帮我即兴创作