单链表的五个常见算法

0,链表的结构

public class ListNode {
    int val;
    ListNode next = null;

    ListNode(int val) {
        this.val = val;
    }
}

1,单链表反转
  这里建议画图理解,画图之后,会更加直观

    public ListNode reverse(ListNode head){
        if(head == null)
            return null;
        ListNode temp = null;
        while(head != null){
            ListNode p = head.next;
            head.next = temp;
            temp = head;
            head = p;
        }
        return temp;
    }

2,链表中环的检测
  让较快的指针走两步,较慢的指针走一步,如果存在环,那么它们肯定会相遇

    public boolean checkCircle(ListNode head){
        if(head == null)
            return false;

        ListNode fast = head;
        ListNode slow = head;
	//链表只存在一个节点的情况
        if(head.next == null)
            return false;
	//链表只存在两个节点的情况
        if(head.next.next == null)
            return false;

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

3,两个有序的链表合并
  这里用到递归的思想

    public ListNode mergeList(ListNode head1,ListNode head2) {
        if(head1 == null && head2 == null)
            return null;
        if(head1 == null)
            return head2;
        if(head2 == null)
            return head1;

        ListNode newHead = null;
        if(head1.val <= head2.val){
            newHead = head1;
            newHead.next = mergeList(head1.next,head2);
        }
        else
        {
            newHead = head2;
            newHead.next = mergeList(head1,head2.next);
        }
        return newHead;
    }

4,删除链表中倒数第 k 个节点
  这里可以设两个指针,一个为 fast, 一个为 slow,让 fast 指针先走 k-1 步,然后fast 走一步,slow 走一步。当 fast 走到链表的尾部时,slow 正好走到要删除节点的前一个节点。

    public ListNode deleteKth(ListNode head, int k){
        if(head == null || k <= 0)
            return null;
        ListNode fast = head;
        ListNode slow = head;
        // fast 节点多走一步,使 slow 走在要删除节点的前面一个节点
        while(k >= 0 && fast != null){
            fast = fast.next;
            k--;
        }
        while(fast != null){
            fast = fast.next;
            slow = slow.next;
        }

        slow.next = slow.next.next;
        return head;
    }

5,求链表的中间节点
  这里我用的是比较暴力的算法,直接先用一个节点走到链表的尾部,同时记录链表中节点的个数,这里设为 k 个节点。再重新建一个新的指针,走到 k / 2 处,即找到了链表的中间节点。

public ListNode midNode(ListNode head){
        if(head == null)
            return null;
        int k = 0;
        ListNode count = head;
        ListNode midNode = head;
        while(count != null){
            count = count.next;
            k++;
        }
        k = k / 2;
        while(k > 0){
            midNode = midNode.next;
            k--;
        }
        return midNode;
    }

转载于:https://my.oschina.net/happywe/blog/3051309

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值