单链表扩展

我们来扩展一下单链表:实现以下比较特殊的方法

逆序输出链表

思路1:不断的遍历链表尾结点,遍历一次,删除一个尾结点,直到遍历到head为止。

思路2:链表遍历入栈,再出栈

思路3:递归方法

由于思路1和思路2非常简单,我们详细描述思路3

    public static <E> void reversePrintList(SingleLinkedList<E>.Node<E> head){
   
        //递归终止条件
        if(head == null){
     // 传入的这个头节点head 实际上是不断的向后移动的,如果移动到尾结点了,就结束这个方法。
            return;//处理办法
        }
        //提取重复逻辑,缩小问题规模
        reversePrintList(head.next);    //移动到尾结点的指向的null了,返回后,打印,方法结束,再 “归来” 返回到上一层,再打印
        System.out.println(head.element + " ");
    }


逆置链表

思路1:创建一个新的链表,然后与逆序输出单链表的思路1类似,遍历尾结点,添加到新的链表中,最后再指向这个新的链表。

思路2:我们定义两个移动的紧紧挨着的节点(pre和current),遍历访问,先保存 current 的 next 域指向的节点(next),然后将 current 节点的 next 域指向前一个节点(pre),再让 current 指向 next,pre 指向 current。向后移动,当 next 为 null 的时候,证明遍历到头了。那么我们把链表的头指向 current 。就完成了。

在这里插入图片描述

以上是初始状态,和结束状态

在这里插入图片描述
实现:

   public static <E> SingleLinkedList<E>.Node<E> reverseList(SingleLinkedList<E>.Node<E> head){
   
        SingleLinkedList<E>.Node<E> current = head; //当前节点
        SingleLinkedList<E>.Node<E> prev = null;//当前节点的前一个
        SingleLinkedList<E>.Node<E> newHead = null;//逆置后链表的头节点

        while(current != null){
   

            //保存当前节点的下一个节点
            SingleLinkedList<E>.Node<E> next = current.next;

            if(next == null){
    //证明遍历到头了
                newHead = current; //把新的头指针赋给原链表的最后一个
            }

            //以下为移动节点的步骤

            current.next = prev;   //把当前节点的next指向前一个节点
            prev = current;         //让前一个节点指向当前节点
            current = next;         //当前节点指向next节点,也就是最开始保存的节点

        }

        return newHead;     //最后返回头节点
    }



合并两个有序的单链表,保证合并之后依然有序

举个例子:
list1:1,3,5,
list2:2,4,6,8,10
合成之后:
在这里插入图片描述
思路:我们创建一个新链表。

1:确定头节点:我们对比list1和list2的头节点,谁的element小,谁链入,谁的head引用向后走一个节点。

2: 确定下一个节点,我们对比当前两个head引用指向的节点的element,谁小谁入链,谁的head引用向后走一个单位。

3:当某一个链表为空时,那么我们就判断一下,谁的head指向的不是null,谁就直接添加到新链表的后面。

实现:

 public static <E extends Comparable<E>> SingleLinkedList<E>.Node<E> mergeLinkedList(
            SingleLinkedList<E>.Node<E> head1, SingleLinkedList<E>.Node<E> head2){
   

        //先确定新链表的头节点‘
        SingleLinkedList<E>.Node<E> curHead = null;
        if(head1.element.compareTo(head2.element) < 0) {
    //哪一个节点的element小,哪一个节点当新链表的头节点
            curHead = head1;
            head1 = head1.next;     //因为第一个节点已经链入了新链表,所以head引用向后移动一个节点
        }else{
   
            curHead = head2;
            head2 = head2.next;
        }


        //创建一个临时的移动引用,用来链入节点
        SingleLinkedList<E>.Node<E> tmp = curHead;

        //来回比对,谁小,谁链入,谁向后移动一个节点
        while(head1 != null && head2 != null){
   
            if(head1.element.compareTo(head2.element) < 0){
   
                tmp.next = head1;
                head1 = head1.next;
            }else{
   
                tmp
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值