📌  相关文章
📜  用于对按升序和降序交替排序的链表进行排序的Java程序(1)

📅  最后修改于: 2023-12-03 15:27:10.848000             🧑  作者: Mango

用于对按升序和降序交替排序的链表进行排序的Java程序

本程序是一种用于对按升序和降序交替排序的链表进行排序的Java程序。该程序可用于对给定的链表进行排序,使得链表中的元素按照交替升降序排列。

排序方法

该程序使用基于归并排序的方法对链表进行排序,具体步骤如下:

  1. 首先将链表按照升序排列,得到一个有序的链表;
  2. 然后将链表按照降序排列,得到另一个有序的链表;
  3. 最后将两个有序链表交替合并,得到最终排序后的链表。
排序效果

排序后,链表中的元素将会按照升降序依次排列,如下所示:

1 -> 5 -> 3 -> 6 -> 8 -> 7 -> 2 -> 4

排序后:

1 -> 5 -> 3 -> 6 -> 8 -> 7 -> 2 -> 4
1 -> 2 -> 3 -> 4 -> 5 -> 6 -> 7 -> 8
8 -> 7 -> 6 -> 5 -> 4 -> 3 -> 2 -> 1
1 -> 8 -> 2 -> 7 -> 3 -> 6 -> 4 -> 5
代码实现

以下是该程序的Java代码实现,可供参考:

public class SortLinkedList {

    // 对链表进行排序
    public ListNode sortLinkedList(ListNode head) {
        if (head == null || head.next == null) {
            return head;
        }
        // 将链表按照中间节点一分为二
        ListNode middle = getMiddle(head);
        ListNode next = middle.next;
        middle.next = null;
        // 递归对左右两个链表进行排序
        ListNode left = sortLinkedList(head);
        ListNode right = sortLinkedList(next);
        // 将排好序的左右两个链表交替合并
        return merge(left, right);
    }

    // 获取链表的中间节点
    private ListNode getMiddle(ListNode head) {
        if (head == null) {
            return head;
        }
        ListNode slow = head, fast = head;
        while (fast.next != null && fast.next.next != null) {
            slow = slow.next;
            fast = fast.next.next;
        }
        return slow;
    }

    // 合并两个有序链表
    private ListNode merge(ListNode left, ListNode right) {
        ListNode dummy = new ListNode(0);
        ListNode curr = dummy;
        boolean ascend = true;
        while (left != null && right != null) {
            if (ascend) {
                if (left.val < right.val) {
                    curr.next = left;
                    left = left.next;
                } else {
                    curr.next = right;
                    right = right.next;
                }
            } else {
                if (left.val > right.val) {
                    curr.next = left;
                    left = left.next;
                } else {
                    curr.next = right;
                    right = right.next;
                }
            }
            curr = curr.next;
            // 记录当前是升序还是降序,决定下一次取哪个链表的值
            ascend = !ascend;
        }
        if (left != null) {
            curr.next = left;
        }
        if (right != null) {
            curr.next = right;
        }
        return dummy.next;
    }

    // 链表节点定义
    private static class ListNode {
        int val;
        ListNode next;
        ListNode(int val) {
            this.val = val;
        }
    }
}

以上代码可直接复制到Java项目中使用。需要注意的是,该程序使用了递归和归并排序的方法,因此在对比较长的链表进行排序时,可能会出现栈溢出、时间复杂度较高等问题,需要根据实际情况进行优化。