算法 | 单链表的五个常见操作

问题:

1.单链表反转:事先存好下一个节点再改变指针

2.链表中环的检测:快慢指针终会相遇

3.两个有序链表的合并:两个链表各一个指针,比较大小后加到最终的链表中(有点快排的感觉)

4.删除链表倒数第K个节点:转化为删除正数第length-K+1个节点

5.求链表的中间节点:快慢指针


思路都在代码的注释中,做链表的画张图就能更好的关注逻辑,比较直观,所以强烈建议画图来看看指针怎么走。

其中只在一种给出运行的例子,2345要运行验证在1的基础上改一改就好。

代码都已检验过没有问题,上代码:

1.单链表反转


//单链表反转
public class ListReverse {

    public static void main(String[] args) {
        ListNode node1=new ListNode(1);
        ListNode node2=new ListNode(2);
        ListNode node3=new ListNode(3);
        ListNode node4=new ListNode(4);
        ListNode node5=new ListNode(5);
        ListNode node6=new ListNode(6);
        node1.next=node2;
        node2.next=node3;
        node3.next=node4;
        node4.next=node5;
        node5.next=node6;
        reverse(node1);
        System.out.println(node6.next.val);
        System.out.println(node5.next.val);
        System.out.println(node4.next.val);
        System.out.println(node3.next.val);
        System.out.println(node2.next.val);
        System.out.println(node1.next);

    }

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

    public static ListNode reverse(ListNode head){
        //单链表反转
        ListNode pre=null;
        ListNode now=head;
        ListNode next;
        while (now!=null){
            next=now.next;
            now.next=pre;
            pre=now;
            now=next;
        }
        System.out.println("反转成功!");
        return pre;

    }
}

2.链表中环的检测

public class CircleInList {

    /*
     思路:快慢指针,如果有环,进入环以后,快慢指针一定会相遇,画图可验证

     */
    public static boolean hasCircle(ListNode head){
        //先做非空判断,只有一个元素也可以成环...
        if (head==null){
            return false;
        }
        //快慢指针
        ListNode fast=head;
        ListNode slow=head;

        while (fast!=null){
            fast=fast.next.next;
            slow=slow.next;
            //先走了再判断
            if (fast==slow){
                return true;
            }
            System.out.println("走了一次");
        }

        return false;
    }

}

3.两个有序链表的合并

//合并两个有序列表
public class ListMerge {

    /*
    思路:两个list各一个指针,比较大小,小的放到新的list中
          当有一个遍历完,则把另一个的剩下的全都加到result这个list中
     */
    public static ListNode merge(ListNode head1, ListNode head2) {
        if (head2 == null || head1 == null) {
            System.out.println("其中有一个List为空");
            return null;
        }

        ListNode ResultHead = null;
        ListNode current = null;
        ListNode Point1 = head1;
        ListNode Point2 = head2;
        //得到头节点
        if (Point1.val < Point2.val) {
            ResultHead = Point1;
            Point1 = Point1.next;
        } else {
            ResultHead = Point2;
            Point2 = Point2.next;
        }
        current = ResultHead;

        while (Point1 != null && Point2 != null) {
            if (Point1.val < Point2.val) {
                current.next = Point1;
                Point1 = Point1.next;
            } else  {
                current.next = Point2;
                Point2 = Point2.next;
            }
            current = current.next;//当前下标往后移动一个
            System.out.println("合并一次");
        }


        if (Point1 == null) {
            current.next = Point2;
            System.out.println("后面的都合并进去");
        } else {
            current.next = Point1;
            System.out.println("后面的都合并进去");
        }

        return ResultHead;
    }
}

4.删除链表倒数第K个节点

//删除倒数第K个node
public class deleteNode {
    //转化为删除正数length-K+1
    public static void deleteNode(ListNode head, int K){

        if (head==null){
            System.out.println("请勿传入空节点");
            return;
        }
        int length=1;
        int count=1;
        int deleteNumberChanged=0;
        ListNode point=head;

        while(point.next!=null){
            point=point.next;
            length++;
        }

        if (length<K){
            System.out.println("没这么多数字");
            return;
        }

        deleteNumberChanged=length-K+1;
        point=head;
        while (point.next!=null){
            if (count+1==deleteNumberChanged){
                ListNode temp=point.next;
                point.next=null;
                point.next=temp.next;
                System.out.println("删除成功");
                break;
            }
            point=point.next;
            count++;
            System.out.println("往后查找");
        }

    }

}

5.求链表的中间节点

//得到链表的中点
public class getMiddleNode {

    public static ListNode getMiddleNode(ListNode head){

        if (head==null){
            return null;
        }
        /*思路:快慢指针,快的走两步,慢的走一步
         */

        ListNode fast=head;
        ListNode slow=head;

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

}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值