数据结构--链表(单向链表)

一.链表的概念

链表是一种物理存储结构上非连续存储结构,数据元素的逻辑顺序是通过链表中的引用链接次序实现的 ,有单向链表和双向链表。

二.单向结构

数据结构--链表(单向链表)_第1张图片

三.单向链表的模拟实现

public class Mylink {
    private ListNode head;
    class ListNode{
        public int value ;
        public ListNode next;

        public ListNode(int value) {
            this.value = value;
        }
    }
    //得到单链表的长度
    public int size(){
        ListNode cur =head;
        int count=0;
        while (cur!=null){
            cur=cur.next;
            count++;
        }
        return count;
    }
    //遍历
    public void display() {
        ListNode cur =head;
        while (cur!=null){
            System.out.print(cur.value+" ");
            cur=cur.next;
        }
        System.out.println();
    }
    //查找是否包含关键字key是否在单链表当中
    public boolean contains(int key){
        ListNode cur =head;
        while (cur!=null){
            if (cur.value==key){
                return true;
            }
            cur=cur.next;
        }
        return false;
    }
    //头插法
    public void addFirst(int data){
        ListNode newnode =new ListNode(data);
        newnode.next=head;
        head=newnode;
    }
    //尾插法
    public void addLast(int data){
        ListNode cur =head;
        ListNode newnode=new ListNode(data);
        if (head==null){
            head=newnode;
            return;
        }
        while (cur.next!=null){
            cur=cur.next;
        }
        cur.next=newnode;
    }
    public void checkPos(int index)throws PostExpect{
        if (index<0||index>size()){
            throw new PostExpect("下标异常");
        }

    }
    //任意位置插入,第一个数据节点为0号下标
    public void addIndex(int index,int data){
       try {
           checkPos(index);
           ListNode cur =head;
           ListNode newnode =new ListNode(data);
           if (index==0){
               addFirst(data);
           }
           if (index==size()){
               addLast(data);
           }else {
               for (int i = index-1; i > 0; i--) {
                   cur=cur.next;
               }
               newnode.next=cur.next;
               cur.next=newnode;
           }
       }catch (PostExpect e){
           e.printStackTrace();
       }
    }
    //删除第一次出现关键字为key的节点
    public void remove(int key){
        if (head==null){
            return;
        }
        ListNode cur =head;
        if (cur.value==key){
            head =cur.next;
            return;
        }
        while (cur.next!=null){
            if (cur.next.value==key){
                ListNode del =cur.next;
                cur.next=del.next;
                return;
            }
            cur=cur.next;
        }
    }
    //删除所有值为key的节点
    public void removeAllKey(int key){
        if (head==null){
            return;
        }
        ListNode cur =head.next;
        ListNode pre =head;
        while (cur!=null){
            if (cur.value==key){
                pre.next=cur.next;
                cur=cur.next;
            }else {
                cur=cur.next;
                pre=pre.next;
            }
        }
        if (head.value==key){
            head=head.next;
        }
    }

   //清空链表
    public void clear() {
        head=null;
    }
}

1.注意事项:

数据结构--链表(单向链表)_第2张图片

2.额外的方法

2.1 反转链表

代码:
    public ListNode reverseList() {
        if(head==null){
            return null;
        }
        ListNode cur =head.next;
        head.next =null;
        while(cur!=null){
            ListNode curt =cur.next;
            cur.next=head;
            head=cur;
            cur=curt;
        }
        return head;
    }
举例:

数据结构--链表(单向链表)_第3张图片

2.2 返回中间节点

代码:
        //方法一
        public ListNode middleNode() {
        if(head==null){
            return null;
        }
        ListNode cur =head;
        int count =0;
        while(cur!=null){
            count++;
            cur=cur.next;
        }
        count=count/2;
        while(count>0){
            count--;
            head=head.next;
        }
        return head;
    }
   //方法二:
    public ListNode middleNode2() {
        if(head==null){
            return null;
        }
        ListNode cur =head;
        ListNode slow =head;
        ListNode fast =head;
        while(fast!=null&&fast.next!=null){
            fast=fast.next.next;
            slow=slow.next;
        }
        return slow;
    }

2.3 放回倒数第K个节点的值

代码:
    //k值有效
    //方法1:
    public int kthToLast(int k) {
        if(head==null){
            return -1;
        }
        ListNode cur =head;
        int count =0;
        while(cur!=null){
            count++;
            cur=cur.next;
        }
        int num =count-k;
        while(num>0){
            num--;
            head=head.next;
        }
        return head.value;
    }
    //方法2:
    public int kthToLast1( int k) {
        if(head==null){
            return -1;
        }
        ListNode fast =head;
        ListNode slow =head;
        while(k-->0){
            fast =fast.next;   //使slow和fast差 k 步
        }
        while(fast!=null){     //当fast为空时slow与fast差 k 个节点,slow为倒数第 k 个节点
            fast=fast.next;
            slow=slow.next;
        }
        return slow.value;
    }

2.4合并俩个有序链表

代码:
public ListNode mergeTwoLists(ListNode headA, ListNode headB) {
        if(headA==null&&headB==null){
            return null;
        }
        ListNode head =new ListNode();
        ListNode cur =head;
        while(headA!=null&&headB!=null){
            if(headA.val>headB.val){
                cur.next=headB;
                headB=headB.next;
                cur=cur.next;
            }else{
                cur.next=headA;
                headA=headA.next;
                cur=cur.next;
            }
        }
        if(headA==null){
            cur.next=headB;
        }
         if(headB==null){
            cur.next=headA;
        }
        return head.next;
    }

2.5 将小于X的节点排在X之前

代码:
    public ListNode partition(int x) {
        if(head==null){
            return null;
        }
        ListNode cur =head;
        ListNode as =null;
        ListNode bs =null;
        ListNode be =null;
        ListNode ae =null;
        while(cur!=null){
            if(cur.value

2.6判断是否回文

代码:
    public boolean chkPalindrome(ListNode head) {
        ListNode cur =head;
        ListNode slow =head;
        ListNode fast =head;
        ListNode last =head;
        while(fast!=null&&fast.next!=null){
            fast=fast.next.next;
            slow=slow.next;
        }
        last=slow.next;
        while(last!=null){
            ListNode tmp =last.next;
            last.next=slow;
            slow=last;
            last=tmp;
        }
        while(head!=slow){
            if(head.val==slow.val){
                if(head.next==slow){
                    return true;
                }
            slow=slow.next;
            head=head.next;
            }else{
                return false;
            }

        }
        return true;

2.7找俩条链表相交得节点

代码:
 public ListNode getIntersectionNode(ListNode listA, ListNode listB) {
        if(listA==null||listB==null){
            return null;
        }
        ListNode as =listA;
        ListNode bs =listB;
        int numA=0;
        int numB=0;
        while(as!=null){
            as=as.next;
            numA++;
        }
        while(bs!=null){
            bs=bs.next;
            numB++;
        }
        if(numA>numB){
            int k=numA-numB;
            while(k>0){
                listA=listA.next;
                k--;
            }
        }else{
            int k=numB-numA;
               while(k>0){
                listB=listB.next;
                k--;
            }
        }

        while(listA!=listB){
            listA=listA.next;
            listB=listB.next;
        }
        if(listA==null){
            return null;
        }
        return listA;
    }

2.8 判断是否有环

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

        }
        return false;

2.9找刚进入环点的节点

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

        }
        if(fast==null||fast.next==null){
            return null;
        }
        while(fast!=head){
            head=head.next;
            fast=fast.next;
        }
        return head;
    }

你可能感兴趣的:(数据结构,链表,java,开发语言,算法)