单链表的实现

定义一个类Node,表示链表的节点

class Node{
    public int date;
    public Node next;
    public Node(int date){
        this.date=date;
    }

构造链表

public class MyList {
 public Node head = null;

1.使用头插法插入节点

public void addFirst(int date) {
        Node node= new Node(date);
        node.next = this.head;
        this.head = node;
    }

2.使用尾插法插入节点

public void addLast(int date) {
        Node node = new Node(date);
        Node node2 = this.head;
        //这里需要判断头节点是否为空
        if (this.head == null) {
            this.head = node;
        }
        while (node2.next != null) {
            node2 = node2.next;
        }
        node2.next = node;
    }

3.任意位置插入

public boolean addIndex(int index,int date){
        if (index<0||index>size()){
            System.out.println("index不合法");
            return false;
        }
        //第一个节点用头插法
        if (index==0){
            addFirst(date);
            return true;
        }
        //最后一个节点用尾插法
        if (index==size()){
            addLast(date);
            return true;
        }
        //在中间
        Node node=new Node(date);
        node.next=prev(index).next;
        prev(index).next=node;
        return true;
    }

二、基本方法的实现

1.遍历节点进行打印

public void show() {
        Node node = this.head;
        while (node != null) {
            System.out.print(node.date + " ");
            node = node.next;
        }
        System.out.println();
        System.out.println("==========================");
    }

2.从指定结点开始打印

public void show2(Node newHead){
        Node node=newHead;
        while(node!=null){
            System.out.print(node.date + " ");
            node = node.next;
        }
        System.out.println();
        System.out.println("==========================");

3.找第n-个节点位置

public Node prev(int index){
        Node node=this.head;
        while(index-1-1!=0){
            node=node.next;
            index--;

        }
        return node;
    }

4.求链表长度

public int  size(){
        int count=0;
        if (this.head==null){
            return 0;
        }
        Node node=this.head;
        while (node!=null){
            count++;
            node=node.next;
        }
        return count;
    }

5.查找是否有关键字key

public boolean contains(int key){
        Node node=this.head;
        while(node!=null){
            if (node.date==key){
                return true;
            }
            node=node.next;
        }return false;
    }

6.删除关键字key

这里需要先找到key节点的前置节点,用到了另外一个方法

public void remove(int key){
        Node node=this.head;
        if (this.head.date==key){
            this.head=this.head.next;
            return;
        }
        Node cur=keyWard(key);
        if (cur==null){
            return;
        }
        cur.next=cur.next.next;

7.找key的前置节点

public Node keyWard(int key){
        Node node=this.head;
        while(node.next!=null){
            if (node.next.date==key){
               return node;
            }node=node.next;
        }return null;
    }

8.删除所有key

public void removeAkey(int key){
        Node prev=this.head;
        Node cur=this.head.next;
        while(cur!=null){
            if (cur.date==key){
                prev.next=cur.next;
                cur=cur.next;
            }else if (cur.date!=key){
                prev=prev.next;
                cur=cur.next;
            }
            if (this.head.date==key){
                this.head=this.head.next;
            }
        }

    }

9.反转链表

这里用两种方法

A.

遍历链表,将头节点的下一个节点置为新的头节点

public Node reverList(){
        if (this.head==null){
            return null;
        }
        Node cur=this.head;
        Node curNest=this.head.next;
        cur.next=null;
        cur=curNest;
        while (cur != null) {
            curNest=cur.next;
        cur.next=this.head;
        this.head=cur;
        cur=curNest;
        }
        return this.head;
        }

B.

构造一个傀儡节点,遍历链表将所有的节点置于傀儡节点之前

public Node reverList2() {
        Node prev = null;
        Node cur = this.head;
        Node newHead=null;
        while(cur!=null){
            Node curNext=cur.next;
            if (curNext==null){
               newHead=cur;

            }
            cur.next=prev;
            prev=cur;
            cur=curNext;
        }
        return newHead;

10.求中间节点

如果有两个中间节点,则返回第二个
快慢指针法

public int  middle(){
        Node fast=this.head;
        Node slow=this.head;
        while(fast!=null&&fast.next!=null){
            fast=fast.next.next;
            slow=slow.next;
        }
        return slow.date;
    }

11.将所有小于x的值放于其余值之前

public Node daXiao(int k){
        Node bs=null;
        Node be=null;
        Node as=null;
        Node ae=null;
        Node cur=this.head;
        while(cur!=null){
            if (cur.date<k){
                if (bs==null) {
                    bs = cur;
                    be = cur;
                }else{
                 be.next=cur;
                 be=be.next;
                }
            }else{
                if (as==null){
                    as=cur;
                    ae=cur;
                }else{
                    ae.next=cur;
                    ae=ae.next;
                }
            }cur=cur.next;
        }

        if (bs==null){
            return as;
        }
        be.next=as;
        if (as!=null){
            ae.next=null;
        }
        return bs;
    }

12.删除所有重复节点

public Node  removeDuo(){
        Node tmpHead=new Node(-1);//定义一个傀儡节点用来链接链表
        Node cur=this.head;
        Node node= tmpHead;
        while(cur!=null){//只有一个节点的情况和正常情况
            if(cur.next!=null&&cur.date==cur.next.date){
                while(cur.next!=null&&cur.date==cur.next.date){
                    cur=cur.next;
                }cur=cur.next;
            }else{
                tmpHead.next=cur;
                tmpHead=tmpHead.next;
                cur=cur.next;
            }
            tmpHead.next=null;
        }
        return node.next;
    }

13.判断是否为回文结构

 public boolean huiWen(){
        if (this.head==null) {
            return false;}
        if (this.head.next==null){
            return true;
        }
        Node fast=this.head;
        Node slow=this.head;
        while(fast!=null&&fast.next!=null){
            fast=fast.next.next;
            slow=slow.next;
        }
        //slow是中间节点
        Node cur=slow.next;
        while(cur!=null){
            Node curNext=cur.next;
            cur.next=slow;
            slow=cur;
            cur=curNext;
        }
        while(this.head!=slow){
            if (slow.date!=this.head.date){
                return false;
            }if (this.head.next==slow){
                return true;
            }slow=slow.next;
            this.head=this.head.next;
        }
        return true;
    }

14.判断一个链表是否成环链表

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

15.找到环链表的入环点

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

            slow=this.head;
            while(fast!=slow){
                slow=slow.next;
                fast=fast.next;

            }
            return slow;
    }

16.输出倒数第k个节点

public Node 倒数k节点(int k){
        if (k<=0||k>this.size()){
            System.out.println("k值不合法");
            return null;
        }
        Node node=this.head;
        int count=this.size()-k;
        while(count!=0){
            node=node.next;
            count--;
        }
        return node;
    }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值