链表常用

 

链表是由节点构成的,这个节点我们可以通过建立一个类来实现它。这个类我们通常选用内部类。

class TestLink{
    class Entry{
        int data;
        Entry next;
        public Entry() {
            next = null;
        }
        public Entry(int data) {
            this.data = data;
            next = null;
        }
    }
}

链表分为有头结点的链表和无头节点的链表,头结点不储存数据。本篇博客用的是头结点的链表。 
注意链表要创建一个构造方法初始化头节点,否则会产生空指针异常

    Entry head;//成员变量
    public TestLink() {//构造函数
        head = new Entry();
    }

1.头插

    public void insertHead(int val) {
        Entry cur = new Entry(val);//插入的点
        cur.next = head.next;//把插入的点next指向head的下一个节点
        head.next=cur;//head的next指向插入的点
    }

2.尾插

    public void insertTail(int val) {
        Entry goal = new Entry(val);//要插入的点
        Entry cur = head;//用来遍历链表
        while(cur.next!=null) {//当cur.next为null即cur已经在链表尾部,退出循环
            cur = cur.next;
        }
        cur.next=goal;//尾插

    }

3.获得链表长度

    public int getLength() {
        Entry cur = head;//用来遍历链表
        int count = 0;//计数器
        while(cur.next != null) {
            cur =cur.next;
            count++;
        }
        return count;
    }

4.任意位置插入

    public void insert(int val,int post) {
        Entry cur = head;//用来遍历链表
        if(post >= 0 && post <= this.getLength()) {//找到插入的位置前的的那一个节点
            for(int i=0;i<post;i++) {
                cur = cur.next;
            }
        }
        Entry entry = new Entry(val);
         entry.next=cur.next;//插入
         cur.next=entry;
    }

5.返回下标

public int valueOf(int val) {
        Entry cur = head.next;
        int count = 0;
        while(cur != null) {
            if(cur.val == val) {
                count++;
                return count;
            }
            count++;
            cur = cur.next;
        }
        return -1;
    }

6.删除指定元素

public void remove(int val) {
        int j = valueOf(val);
        if(j < 1) {
            return; 
        }
        Entry cur = head.next;
        Entry pr = head;
        for (int i = 1; i < j; i++) {
            cur = cur.next;
            pr =pr.next;
        }
        pr.next = cur.next;

    }

7.链表的逆置

    public Entry reverse(){
        Entry pre = null;//
        Entry newHead = null;//用来存放逆置后链表的头结点
        Entry cur = head;//用来遍历链表
        while(cur != null) {//当cur.next==null时即cur到尾部时再循环一次把cur变成头指针。
            Entry curNext = cur.next;
            if(curNext == null){
                newHead = cur;
            }
            cur.next = pre;
            pre = cur;
            cur = curNext;
        }
        return newHead;
    }

8.求倒数第k个元素

    public Entry getPost(int k) {
        Entry cur = head;//用来遍历链表
        if(k < 0 || k > this.getLength()) {//如果插入的位置小于零或大于链表长度返回null
            return null;
        }
        for(int i=0;i<this.getLength()-k+1;i++) {//找到倒数第k个位置
            cur =cur.next;
        }
        return cur;

    }

9.求两个链表是否相交

public boolean isCut(TestLink t1,TestLink t2) {
        TestLink.Entry head1 = t1.head;
        TestLink.Entry head2 = t2.head;
        int len1 = t1.getLength();
        int len2 = t2.getLength();
        int myLen = len1-len2;//两条链表的长度差
        if(myLen < 0) {//head1指向长链表表头
            head1 = t2.head;
            head2 = t1.head;
        }
        for(int i=0;i< myLen;i++) {//head1到在长链表上移动至和端链表对齐
            head1 = head1.next;
        }
        while(head1 != null && head2 !=null && head1 != head2) {//两个遍历节点同时向后移,如果到尾部结束循环或两个节点相交结束循环
            head1 = head1.next;
            head2 = head2.next;
        }
        if(head1 == head2) {//相交返回true
            return true;
        }
        return false;
    }

10.判断链表是否有环,并且求入口点和环长

public boolean judgeLoop() {
        Entry fast = head;//快节点
        Entry slow = head;//慢节点
        while(fast.next != null && fast.next.next != null) {//当快节点到尾部的时候循环结束,因为快节点每次要后移两格所以要加上fast.next.next不等于空的条件,否则会产生空指针异常
            fast = fast.next.next;
            slow = slow.next;
            if(fast == slow) {//相交返回true
                return true;
            }
        }
        return false;
    }

入口点

public int intoLoop(){
         Entry fast = head;
         Entry slow = head;
         while(fast.next != null && fast.next.next != null){
             fast = fast.next.next;
             slow = slow.next;
             if(fast == slow) {
                 break;
             }
         }
         slow = head;
         while(fast != slow){
             fast = fast.next;
             slow = slow.next;
         }
         return slow.data;
     }

环长

当快慢节点第二次相遇时,慢节点从第一次到第二次相遇走的距离即环长。

public int getLoopLength() {
        Entry fast = head;
        Entry slow = head;
        boolean  tag = false;
        int length = 0;
        while(fast.next != null && fast.next.next != null) {
            fast = fast.next.next;
            slow = slow.next;
            if(fast == slow && tag == true) {
                break;
            }
            if(fast == slow && tag == false) {
                tag =true;
            }
            if(tag == true ) {
                length++;
            }
        }
        return length;
    }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值