A-反转链表&合并两个排序的链表

题目16:定义一个函数,输入一个链表的头结点,反转该链表并输出反转后链表的头结点。链表定义如下:

    public class Node<T> {
        public T item;
        public Node<T> next;

        public Node() {
        }

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

分析:
  为了正确地反转链表,需要调整链表中指针的方向。如下图所示:
在这里插入图片描述
  在图(a)中,h、i、j三个结点是相邻的,假设经过若干操作,我们已经把结点h之前的指针调整完毕,接下来我们把i的next指向h,此时链表结构如(b)所示。此时i、j之间断裂,为了避免这种情况,需要在调整结点i的next之前,把结点j保存起来。因此在调整之前,我们除了需要知道当前结点,还需要知道它的前一个结点以及后一个结点。
  此外还需要注意一下几种情况:
  1)输入链表的头指针为null,或者链表只有一个结点。
  2)反转后的链表出现断裂。
  3)返回的反转之后的头结点不是原始链表的尾结点。
  代码如下所示:

    public static Node reverseNodeList(Node pNode) {
        Node result = null;
        Node concurNode = pNode;
        Node preNode = null;
        while (concurNode != null) {
            Node nextNode = concurNode.next;
            if (nextNode == null) result = concurNode;
            concurNode.next = preNode;
            preNode = concurNode;
            concurNode = nextNode;
        }
        return result;
    }

    public static void main(String[] args) {
        Node<Integer> a = new Node<>(1);
        Node<Integer> b = new Node<>(2);
        Node<Integer> c = new Node<>(3);
        Node<Integer> d = new Node<>(4);
        Node<Integer> e = new Node<>(5);
        Node<Integer> f = new Node<>(6);
        a.next = b;
        b.next = c;
        c.next = d;
        d.next = e;
        e.next = f;

        // 含有多个结点
//        Node node = reverseNodeList(a);
        // 仅含有一个结点
//        Node node = reverseNodeList(new Node(2));
        // 头结点为空
        Node node = reverseNodeList(null);
        while (node != null) {
            System.out.print(node.item + " ");
            node = node.next;
        }
    }

题目17:输入两个递增排序的链表,合并这两个链表并使新链表中的结点仍然是按照递增排序的。链表结点定义和上一题一致。
分析:
  分析从合并两个链表的头结点开始。链表1的头结点的值小于链表2的头结点的值,因此链表1的头结点将是合并后链表的头结点。如下图所示。
在这里插入图片描述
在这里插入图片描述
  在剩余的结点中,链表2的头结点的值小于链表1的头结点的值,因此链表2的头结点是剩余结点的头结点,把这个结点和之前已经合并好的链表的尾结点链接在一起。如下图所示,以此类推。
在这里插入图片描述
  此外还要对空链表单独处理,当第一个链表为空链表时,那么第二个链表就是合并之后的结果;当第二个链表为空链表时,那么第一个链表就是合并之后的结果;当两个链表都为空时,合并后的链表也为空。
  代码如下所示:

    public static Node merge(Node pNode1, Node pNode2) {
        if (pNode1 == null) return pNode2;
        else if (pNode2 == null) return pNode1;

        Node result = null;
        if ((Integer) pNode1.item < (Integer) pNode2.item) {
            result = pNode1;
            result.next = merge(pNode1.next, pNode2);
        } else {
            result = pNode2;
            result.next = merge(pNode1, pNode2.next);
        }
        return result;
    }

    public static void main(String[] args) {
        Node<Integer> a = new Node<>(1);
        Node<Integer> b = new Node<>(3);
        Node<Integer> c = new Node<>(5);
        Node<Integer> d = new Node<>(7);
        Node<Integer> e = new Node<>(9);
        a.next = b;
        b.next = c;
        c.next = d;
        d.next = e;
        Node<Integer> f = new Node<>(2);
        Node<Integer> g = new Node<>(4);
        Node<Integer> h = new Node<>(6);
        Node<Integer> i = new Node<>(8);
        Node<Integer> j = new Node<>(10);
        f.next = g;
        g.next = h;
        h.next = i;
        i.next = j;

//        Node node = merge(a,f);
        // 有一个链表为空
//        Node node = merge(null,f);
        // 两个链表都只含有一个结点
        Node node = merge(new Node<>(10), new Node<>(12));
        while (node != null) {
            System.out.print(node.item + " ");
            node = node.next;
        }
    }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值