实现链表及相关的方法 1


本篇博客主要是自己实现一下链表。

链表的节点:

//节点类
class ListNode {
    public int data;
    public ListNode next;
    public ListNode random;
	//构造方法
    public ListNode(int data) {
        this.data = data;
        this.next = null;
        this.random=null;
    }
}

创建链表的类:

该链表为不带头结点的单链表,并且里边有很多链表基本操作的实例方法,下面一一介绍。

public class MySignalList {
    //此时的头随时可能变化
    public ListNode head;
	//构造方法
    public MySignalList() {
        this.head = null;
    }
}

插入元素:头插法

    public void addFirst(int data) {
        //创建一个新的节点
        ListNode node = new ListNode(data);
        //判断头是否为空(即判断是否为第一次插入,新的单链表的head是空)
        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 int getLength() {
        int count = 0;
        ListNode cur = this.head;
        if (this.head == null)
            return 0;
        while (cur != null) {
            count++;
            cur = cur.next;
        }
        return count;
    }


    

在任意位置插入(第一个数据节点的下标为0)

    public boolean addIndex(int index, int data) {
        //先判断index的位置是否合法
        if (index < 0 || index > this.getLength()) {
            System.out.println("该位置不合法!!");
            return false;
        }
        //如果在0号下标插,即第一个位置,直接调用头插法的方法
        if (index == 0) {
            addFirst(data);
            return true;
        }
        int count = 0;
        ListNode cur = this.head;
        ListNode node = new ListNode(data);
        while (count < index - 1) {
            cur = cur.next;
            count++;
        }
        node.next = cur.next;
        cur.next = node;
        return true;
    }

打印链表

    public void display1() {
        //从头开始
        ListNode cur = this.head;
        while (cur != null) {
            System.out.print(cur.data + " ");
            cur = cur.next;
        }
        System.out.println();
    }


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

查找前驱


    public ListNode searchPrev(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;
        }

        //删除的节点是否是头结点
        if (this.head.data == key) {
            this.head = this.head.next;
            return;
        }

        //1.找到key的前驱
        ListNode prev = searchPrev(key);
        if (prev == null) {
            return;
        }

        //2.删除节点
        prev.next = prev.next.next;
    }

查找关键字key是否在单链表中

    public boolean contains(int key) {

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


    //删除所有值为key的节点
    public ListNode removeAllKey(int key) {
        //判断链表是否为空
        if (this.head == null) {
            return null;
        }
        ListNode pre = this.head;
        ListNode cur = pre.next;
        while (cur != 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;
        }

        return this.head;
    }

删除所有值为key的节点

    public ListNode removeAllKey(int key) {
        //判断链表是否为空
        if (this.head == null) {
            return null;
        }
        ListNode pre = this.head;
        ListNode cur = pre.next;
        while (cur != 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;
        }

        return this.head;
    }

反转一个单链表——头插法

 //反转一个单链表
    //发一:头插法
    //法二:三个引用改变指向
    public ListNode reverseList() /**/{
        ListNode prev = null;
        ListNode cur = this.head;

        ListNode NewHead = null;
        if (this.head == null) {
            return null;
        }
        while (cur != null) {
            ListNode curNext = cur.next;
            if (curNext == null) {
                NewHead = cur;
            }
            cur.next = prev;
            prev = cur;
            cur = curNext;
            // curNext=cur.next;

        }
        return NewHead;
    }
  

反转一个单链表——三个引用改变指向法

  public void reverseList2()
    {
        ListNode cur=this.head;
        ListNode tmp=new ListNode(-1);
        while(cur!=null)
        {
            ListNode curNext=cur.next;
            curNext.next=cur;
            cur=curNext;
        }
    }

查找链表中间节点(快慢指针法)

思路:慢指针一次走一步,快指针一次走两步

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


    

查找链表中倒数第k个节点

思路:快慢指针,快指针先走k步,再一人一步向前走,直到快指针为空

//查找链表中倒数第k个节点:快慢指针
    public ListNode FindKthKey(int k) {
        if (k < 0) {
            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) {
            slow = slow.next;
            fast = fast.next;
        }
        return slow;
    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值