📜  用于双向链表的合并排序的Java程序(1)

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

用于双向链表的合并排序的Java程序

双向链表是一种常见的数据结构,用于存储线性数据,具有可以从前向后或从后向前遍历的优点。对于需要对双向链表进行排序的情况,可以使用合并排序(merge sort)算法来实现。

在Java语言中,可以使用递归的方式来实现双向链表的合并排序。下面是一个示例程序:

public class LinkedListSort<T extends Comparable<T>> {

    private Node<T> head;
    
    // 定义节点类
    private static class Node<T> {
        T data;
        Node<T> prev;
        Node<T> next;

        public Node(T data) {
            this.data = data;
        }
    }

    // 对外的排序接口
    public void sort() {
        head = mergeSort(head);
    }

    // 递归实现合并排序
    private Node<T> mergeSort(Node<T> head) {
        if (head == null || head.next == null) {
            return head; // 链表为空或只有一个元素,直接返回
        }

        Node<T> middle = getMiddle(head); // 获取中间节点
        Node<T> nextOfMiddle = middle.next;
        nextOfMiddle.prev = null;
        middle.next = null;

        Node<T> left = mergeSort(head); // 对左半链表进行排序
        Node<T> right = mergeSort(nextOfMiddle); // 对右半链表进行排序

        Node<T> sorted = merge(left, right); // 合并左右两个有序链表

        return sorted;
    }

    // 获取中间节点
    private Node<T> getMiddle(Node<T> head) {
        if (head == null) {
            return head;
        }

        Node<T> slow = head;
        Node<T> fast = head;

        while (fast.next != null && fast.next.next != null) {
            slow = slow.next;
            fast = fast.next.next;
        }

        return slow;
    }

    // 合并两个有序链表
    private Node<T> merge(Node<T> left, Node<T> right) {
        Node<T> result = null;
        if (left == null) {
            return right;
        }
        if (right == null) {
            return left;
        }

        if (left.data.compareTo(right.data) <= 0) {
            result = left;
            result.next = merge(left.next, right);
            result.prev = null;
            if (result.next != null) {
                result.next.prev = result;
            }
        } else {
            result = right;
            result.next = merge(left, right.next);
            result.prev = null;
            if (result.next != null) {
                result.next.prev = result;
            }
        }

        return result;
    }

    // 插入一个新元素
    public void insert(T data) {
        Node<T> newNode = new Node<>(data);
        if (head == null) {
            head = newNode;
        } else {
            Node<T> current = head;
            while (current.next != null) {
                current = current.next;
            }
            current.next = newNode;
            newNode.prev = current;
        }
    }

    // 打印链表
    public void printList() {
        Node<T> current = head;
        while (current != null) {
            System.out.print(current.data + " ");
            current = current.next;
        }
        System.out.println();
    }

    public static void main(String[] args) {
        LinkedListSort<Integer> list = new LinkedListSort<>();
        list.insert(5);
        list.insert(1);
        list.insert(7);
        list.insert(2);
        list.insert(6);
        System.out.print("Before sorting: ");
        list.printList(); // Before sorting: 5 1 7 2 6
        list.sort();
        System.out.print("After sorting:  ");
        list.printList(); // After sorting:  1 2 5 6 7
    }
}

在该程序中,定义了一个泛型类LinkedListSort,用于存储和排序双向链表。其中,Node为节点类,包括数据域data,前向指针prev和后向指针nextmergeSort方法使用递归的方式实现了合并排序。具体的思路如下:

  • 对于单个或空的链表,直接返回。
  • 获取链表的中间节点,使用快慢指针的思想。
  • 将链表从中间节点处断开,得到两个左右两个链表。
  • 对左半部分进行递归排序,对右半部分进行递归排序。
  • 合并左右两个有序链表。

另外,insert方法用于在链表末尾插入一个元素,printList用于打印链表。在main方法中,用于测试双向链表的排序效果。

通过以上的程序,可以实现对双向链表的合并排序。在实际应用中,需要根据实际情况进行简单的修改即可。