单链表的实现及习题

节点类

class ListNode {
    public int data;
    public ListNode next;

    public ListNode(int data) {
        this.data = data;
        this.next = null;
    }
}

头插法

    public void addFirst(int data) {
       ListNode node=new ListNode(data);
       if(this.head ==null){
           this.head=node;
       }
       else {
           node.next=this.head;
           this.head=node;
       }
    }

尾插法

    public void addLast(int data) {
     ListNode node=new ListNode(data);
     ListNode cur=this.head;
     if(this.head==null){
         this.head=node;
     }else {
         while (cur.next!=null){
             cur=cur.next;
         }
         cur.next=node;
     }
    }

打印

    public void display() {
        ListNode cur = this.head;
      while (cur!=null){
          System.out.print(cur.data+" ");
          cur=cur.next;
      }
        System.out.println();
    }

是否包含key

    public boolean contains(int key) {
        ListNode cur = this.head;
       while (cur!=null){
           if(cur.data==key){
               return true;
           }
           cur=cur.next;
       }
       return false;
    }

获得单链表的长度

 public int getLength() {
       int count=0;
       ListNode cur=this.head;
       while(cur!=null){
           count++;
           cur=cur.next;
       }
       return count;
    }

找第index的节点

 private ListNode searchIndex(int index) {
        ListNode cur = this.head;
        //cur -> index-1
        int count=0;
        while (count<index-1){
            count++;
            cur=cur.next;

        }
        return cur;
    }

任意位置插入

 public boolean addIndex(int index, int data) {
   if(index<0||index>getLength()){
       System.out.println("index位置不合法");
        return false;
    }
    if(index==0){
       addFirst(data);
       return true;
   }
   ListNode node=new ListNode(data);
   ListNode cur=searchIndex(index);
   node.next=cur.next;
   cur.next=node;
   return true;
    }

查找关键字

 private ListNode searchPre(int key) {
    ListNode pre=this.head;
    while (pre.next!=null){
        if(pre.next.data==key){
            return pre;
        }
        pre=pre.next;
    }
    return null;

    }

删除第一次出现关键字为key的节点

 public void remove(int key){
        if(this.head==null){
            System.out.println("单链表为空");
            return;
        }
        //0、删除的节点是否是头结点
        if (this.head.data==key){
            this.head=this.head.next;
            return;
        }
        //1、找到key的前驱  如果返回空
       ListNode pre=searchPre(key);
        if (pre==null){
            System.out.println("没有你要删除的节点");
            return;
        }
        //2、删除节点
       ListNode del=pre.next;
        pre.next=del.next;
    }

删除所有值为key的节点

 public void removeAllKey(int key){
      ListNode pre=this.head;
      ListNode cur=this.head.next;
      while(cur.next!=null){
          if (pre.next.data==key){
              pre.next=cur.next;
              cur=cur.next;
          }
          if(pre.next.data!=key){
              pre=cur;
              cur=cur.next;
          }
      }
      if (this.head.data==key){
          this.head=this.head.next;
      }

    }

反转单链表

 public ListNode reverseList(){
       ListNode pre=null;
       ListNode newHead=null;
       ListNode cur=this.head;
       while (cur!=null){
           ListNode curNext=cur.next;
             if(curNext==null){
                 newHead=cur;
             }
             cur.next=pre;
             pre=cur;
             cur=cur.next;
       }
       return newHead;
    }

单链表的中间节点

public ListNode middleNode(){
    ListNode fast=this.head;
    ListNode slow=this.head;
    while(fast!=null&&fast.next!=null){
        fast=fast.next.next;
        slow=slow.next;
    }
    return slow;
    }

打印2

 public void display2(ListNode newHead) {
        ListNode cur = newHead;
        while (cur != null) {
            System.out.print(cur.data+" ");
            cur = cur.next;
        }
        System.out.println();
    }

输入一个链表,输出该链表中倒数第k个结点

 public ListNode findKthToTail(int k){
        //k>getLength
   if(k<=0){
       System.out.println("没有这个节点");
       return null;
   }
   ListNode fast=this.head;
   ListNode slow=this.head;
   while (k-1>0){
       if(fast.next!=null) {
           fast = fast.next;
           k--;
       }
       else {
           System.out.println("没有你要找的节点");
           return null;
       }
   }
    while (fast.next!=null){
    fast=fast.next;
    slow=slow.next;
    }
    return slow;
        }

以x为基准将链表分割成两部分,所有小于x的结点排在大于或等于x的结点之前

public ListNode partition(int x) {
        ListNode cur = this.head;
        ListNode beforeStart = null;
        ListNode beforeEnd = null;
        ListNode afterStart = null;
        ListNode afterEnd = null;
        while (cur != null) {
            //cur.data < x
            if(cur.data < x) {
                //第一次插入
                if(beforeStart==null) {
                    beforeStart=cur;
                    beforeEnd=cur;
                }else {
                    beforeEnd.next=cur;
                    beforeEnd=beforeEnd.next;
                }
                cur=cur.next;
            }
            else {
                //第一次插入
                if(afterStart == null) {
                    afterStart=cur;
                    afterEnd=cur;
                }else {
                    afterEnd.next=cur;
                    afterEnd=afterEnd.next;
                }
            }
            cur=cur.next;
        }


        if(beforeStart==null){
            return  afterStart;
        }
            beforeEnd.next =afterStart;
        if (afterStart!=null){
            afterEnd.next=null;
        }
            return beforeStart;
    }

删除重复的节点

    public ListNode deleteDuplication() {
        ListNode node = new ListNode(-1);
        ListNode cur = this.head;
        ListNode tmp = node;
        while (cur != null) {
            if(cur.next != null &&
                    cur.data == cur.next.data) {
                //1、循环
                while (cur.next != null &&cur.data == cur.next.data){
                    cur=cur.next;
                }
                cur=cur.next;

                //2、退出循环 cur要多走一步
                //
            }else {
                //当前节点 不等于下一个节点的时候
                tmp.next = cur;
                cur = cur.next;
                tmp = tmp.next;
            }
        }
        tmp.next=cur;
        return node.next;

    }

回文

 public boolean chkPalindrome() {
        ListNode fast = this.head;
        ListNode slow = this.head;

        while (fast != null && fast.next!=null) {
            fast = fast.next.next;
            slow = slow.next;
        }
        //反转
        ListNode p = slow.next;
        while (p != null) {
            ListNode pNext = p.next;
            //反转
            p.next = slow;
            slow = p;
            p = pNext;
        }
        while (slow!=head){
            if(slow.data!=head.data){
                return false;
            }//偶数
            if (this.head.next==slow){
                return true;

            }
            slow=slow.next; //slow往前    head 往后
            head=head.next;
        }
       return true;//直到相遇
    }

是否有环

public boolean hasCycle(){
        ListNode fast=this.head;
        ListNode slow=this.head;
        while (fast!=null&&fast .next!=null){
            slow=slow.next;
            fast=fast.next.next;
            if(slow==fast){
                return true;
            }
        }
        return false;
    }

返回链表开始入环的第一个节点如果链表无环,则返回null

 public ListNode detectCycle(){
        ListNode fast=this.head;
        ListNode slow=this.head;
        while (fast!=null&&fast .next!=null){
            slow=slow.next;
            fast=fast.next.next;
            if(slow==fast) {
             break;
            }
            if(fast.next!=null||fast!=null)
                return null;
        }
        fast = this.head;
        while (fast!=slow){
            fast=fast.next;
            slow=slow.next;
        }
        return fast;
    }

环的长度

 public int Listlen(){
        ListNode fast=this.head;
        ListNode slow=this.head;
        while (fast!=null&&fast .next!=null){
            slow=slow.next;
            fast=fast.next.next;
            if(slow==fast) {
                break;
            }
            if(fast.next!=null||fast!=null)
                return -1;
        }
        //slow=fast
            slow=slow.next;
             int count=1;
            while (fast!=slow){
            slow=slow.next;
            count++;
        }
        return count;

    }
    
}

找共同节点返回

public static ListNode  getIntersectionNode
            (ListNode headA,ListNode headB){
        if(headA == null || headB == null) {
            return null;
        }
        //永远指向最长的单链表
        ListNode pL = headA;
        //永远指向最短的单链表
        ListNode pS = headB;

        int lenA = 0;

        int lenB = 0;

        //分别求长度
        while(pL!=null){
            lenA++;
            pL=pL.next;
        }
         while(pS!=null){
            lenA++;
            pS=pS.next;
        }
        pL = headA;
        pS = headB;
        //求长度的差值
        int len = lenA-lenB;
        //如果是负数-》pL = headB;  pS = headA
        if(len<0){
            pL = headB;
            pS = headA;
            len=lenB-lenA;
        }

        //只需要让pL走len步就好了
        while (len>0){
            pL=pL.next;
            len--;
        }
        //走完len步之后  两个同时开始走
        while (pL!= pS&&pL!=null){
            pL= pL.next;
            pS=pS.next;
        }
        if(pL==pS&&pS!=null){
            return pL;
        }
        return null;
        //一直走 走到next值相同时 就是交点
    }

将两个有序链表合并为一个新的有序链表并返回

 public static ListNode mergeTwoLists(
            ListNode headA,ListNode headB) {
        ListNode  node=new ListNode(-1);
        ListNode tmp=null;
        while (headA!=null&&headB!=null){
            if(headA.data<headB.data){
               tmp.next=headA;
               headA=headA.next;
               tmp=tmp.next;
            }
            else {
                tmp.next=headB;
                headB=headB.next;
                tmp=tmp.next;
            }
        }
         if(headA!=null){
          tmp.next=headA;
        }
        if (headB!=null){
            tmp.next=headB;
        }
        return node.next;
    }

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值