有序链表的合并的一种实现

概述:合并有序链表的一种实现

在Leetcode刷题的时候,碰到有序链表的合并问题,第21题是两个链表的合并,第23提是k个链表的合并,第23题利用第21题的解法,将两个链表合成一个,再把合成的链表作为新链表和下一个链表合并即可。合并链表有很多方法:
a.将所有节点拆开,放到数组里进行排序,再放回链表,这种方法实现最简单,但是放弃了链表本身插入删除成本低的优势;
b.另一种方法是分别遍历两个链表,将节点从小到大一次加到另外一个新链表中,这种方法也比较简单,定义两个指针分别遍历就好;
c.第三种方法是遍历其中一张表,将节点数据插入到另一张链表对应的节点,这种方法的思路也简单,很容易想到,但是实现起来会有一些坑,没有IDE的情况下调试起来还是不太直观的,其中需要特别注意的是头插和尾插的处理。

代码如下:

public class T23 {
    /**
     * 合并k个有序链表
     * @param lists 待合并的链表的数组
     * @return 合并后的有序链表第一个节点
     */
    public ListNode mergeKLists(ListNode[] lists) {
        ListNode p = null;
        for(ListNode node : lists){
            p = mergeTwoLists(p,node);
        }
        return p;
    }

    /**
     * 合并两个有序链表
     * @param p 有序链表1
     * @param node 有序链表2
     * @return 链表2插入到链表1的合并结果
     */
    public static ListNode mergeTwoLists(ListNode p, ListNode node) {
        if (p == null) {
            return node;
        }
        if (node == null) {
            return p;
        }

        ListNode pFirst = p;
        ListNode prep = p;
        ListNode curNode = node;

        while (curNode != null) {
            node = node.next;
            while (p != null) {
                if (p.val < curNode.val) {
                    prep = p;
                    p = p.next;
                } else if (prep != p) {
                    curNode.next = prep.next;
                    prep.next = curNode;
                    break;
                } else {
                    break;
                }
            }
            // prep == p 说明在第一个节点之前插入
            if (prep == p) {
                curNode.next = prep;
                pFirst = curNode;
            }
            // p == null 说明在末尾插入
            if (p == null) {
                prep.next = curNode;
                curNode.next = null;
            }
            curNode = node;
            p = pFirst;
            prep = p;
        }
        return pFirst;
    }
}

class ListNode {
    int val;
    ListNode next;
    ListNode(int x) {
        val = x;
    }
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章