前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >java——单链表方法实现

java——单链表方法实现

作者头像
小雨的分享社区
发布2022-10-26 15:10:58
4270
发布2022-10-26 15:10:58
举报
文章被收录于专栏:小雨的CSDN
代码语言:javascript
复制
/**
 * 单链表
 */
class Node{
    public int data;
    public Node next;
    public Node(int data){
        this.data = data;
        this.next = null;
    }
}

public class MyLinkedList {
    public Node head;//保存头节点的引用

    // 1、无头单向非循环链表实现---------------------------------------------------------
    //头插法
    public void addFirst(int data){
        Node node = new Node(data);//有了一个节点
        if (this.head == null){
            //第一次插入节点
            this.head = node;
            return;
        }
        node.next = this.head;
        this.head = node;
    }

    //尾插法
    public void addLast(int data){
        Node node = new Node(data);
        Node cur = this.head;
        if (cur == null){
            this.head = node;
            return;
        }
        while (cur.next != null){
            cur = cur.next;
        }
        cur.next = node;
    }

    //2.任意位置插入,第一个数据节点为0号下标-------------------------------------------------
    public void addIndex(int index,int data){
        Node node = new Node(data);
        if (index == 0){
            addFirst(data);
            return ;
        }
        if (index == this.size()){
            addLast(data);
            return;
        }
        Node cur = searchIndex(index);
        node.next = cur.next;
        cur.next = node;
    }
    private Node searchIndex(int index){
        if (index < 0 || index > this.size()){
            throw new RuntimeException("index位置不合法");
        }
        Node cur = this.head;
        while (index - 1 != 0){
            cur = cur.next;
            index--;
        }
        return cur;
    }

    //查找是否包含关键字key是否在单链表当中-------------------------------------------------------
    public boolean contains(int key){
        Node cur = this.head;
        while (cur != null){
            if (cur.data == key){
                return true;
            }
            cur = cur.next;
        }
        return false;
    }

    //删除第一次出现关键字为key的节点------------------------------------------------------------
    public void remove(int key){
        if (this.head == null){
            return;
        }
        //如果是头节点,直接删除
        if (this.head.data == key){
            this.head = this.head.next;
        }
        Node prev = findPast(key);
        if (prev == null){
            System.out.println("没有这个节点");
        }
        Node del = prev.next;
        prev.next = del.next;
    }
    //找目标节点的前一个节点
    public Node findPast(int key){
        Node prev = this.head;
        while (prev.next != null){
            if(prev.next.data == key){
                return prev;
            }
        }
        return null;
    }

    //删除所有值为key的节点------------------------------------------------------------------
    public void removeAllKey(int key){
        Node prev = this.head;
        Node cur = prev.next;
        while (cur != null){
            if (cur.data == key){
                prev.next = cur.next;
                cur = cur.next;
            }else {
                prev = cur;
                cur = cur.next;
            }
        }
        //如果刚开始的头节点重复了,就删除头节点
        if (this.head.data == key){
            this.head = this.head.next;
        }
    }


    //得到单链表的长度-------------------------------------------------------------------
    public int size(){
        int count = 0;
        Node cur = this.head;
        while (cur != null){
            count++;
            cur = cur.next;
        }
        return count;
    }

    //打印------------------------------------------------------------------------------
    public void display(){
        Node cur = this.head;
        while (cur != null){
            System.out.print(cur.data + " ");
            cur  = cur.next;
        }
    }

    public void clear(){
        this.head = null;
    }
}

主函数

代码语言:javascript
复制
 public static void main(String[] args) {
        MyArrayList myArrayList = new MyArrayList();
        myArrayList.add(0,0);
        myArrayList.add(1,1);
        myArrayList.add(2,2);
        myArrayList.add(3,3);
        myArrayList.add(4,4);
        myArrayList.add(5,5);
        myArrayList.add(6,6);
//        也可以这样赋值:
//        for (int i = 0; i < 10; i++){
//            myArrayList.add(i, i);
//        }
        myArrayList.add(7,19);
        myArrayList.display();

        System.out.println(myArrayList.search(19));

        System.out.println(myArrayList.getPos(5));

        myArrayList.setPos(2,64);
        myArrayList.display();

    }

相关练习题如下

代码语言:javascript
复制
class ListNode {
    public int val;
    public ListNode next;
    public ListNode(int val){
        this.val = val;
        this.next = null;
    }
}

public class TestDemo1025_1 {
    public ListNode head;

    //给定一个头结点为 head 的非空单链表,返回链表的中间结点。
//
//如果有两个中间结点,则返回第二个中间结点。
//
//
    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;
    }


    //链表中倒数第k个节点
    public ListNode findLastK(int k){
        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){
            slow = slow.next;
            fast = fast.next;
        }
        return slow;
    }

    //现有一链表的头指针 ListNode* pHead,给一定值x,
    // 编写一段代码将所有小于x的结点排在其余结点之前,且不能改变原来的数据顺序,返回重新排列后的链表的头指针。
    public ListNode partition(int x){
        ListNode bs = null;
        ListNode be = null;
        ListNode as = null;
        ListNode ae = null;
        ListNode cur = this.head;
        while (cur != null) {
            if (cur.val < x){
                //第一次插入
                if (bs == null){
                    bs = cur;
                    be = bs;
                }else {
                    be.next = cur;
                    be = be.next;
                }
            }else {
                //第一次插入
                if (as == null){
                    as = cur;
                    ae = as;
                }else {
                    ae.next = cur;
                    ae = ae.next;
                }
            }
            cur = cur.next;
        }
        //1.判断bs是否为空,如果为空,返回as
        if (bs == null){
            return as;
        }
        //2.如果bs不为空,需要进行拼接
        be.next = as;
        //3.如果ae不为空,则需要吧ae.next置为空
        if (ae != null){
            ae.next = null;
        }
        return bs;
    }

    //在一个排序的链表中,存在重复的结点,请删除该链表中重复的结点,重复的结点不保留,返回链表头指针。
    // 例如,链表1->2->3->3->4->4->5 处理后为 1->2->5
    public ListNode deleteDuplication(ListNode pHead) {
        ListNode cur = this.head;
        ListNode newHead = new ListNode(-1);
        ListNode tmp = newHead;
        while (cur != null){
            if (cur.next != null && cur.val == cur.next.val){
                while (cur.next != null && cur.val == cur.next.val){
                    cur = cur.next;
                }
                cur = cur.next;
            }else {
                tmp.next = cur;
                tmp = tmp.next;
                cur = cur.next;
            }
        }
        tmp.next = null;
        return newHead.next;
    }
    //反转单链表
    public ListNode change(){
        ListNode prev = null;
        ListNode cur = this.head;
        ListNode curNext = null;
        ListNode newHead = null;

        while (cur != null){
            curNext = cur.next;
            if (curNext == null){
                newHead = cur;
            }
            cur.next = prev;
            prev = cur;
            cur = curNext;
        }
        return newHead;
    }


    //对于一个链表,请设计一个时间复杂度为O(n),额外空间复杂度为O(1)的算法,判断其是否为回文结构。
    //
    //给定一个链表的头指针A,请返回一个bool值,代表其是否为回文结构。保证链表长度小于等于900。
    //
    //测试样例:
    //1->2->2->1
    //返回:true
    public boolean chkPalindrome() {
        // write code here
        ListNode fast = this.head;
        ListNode slow = this.head;

        if (this.head == null){
            return false;
        }
        if (this.head.next == null){
            //只有头节点自己,必然是回文
            return true;
        }
        //找到中间
        while (fast != null && fast.next != null){
            fast = fast.next.next;
            slow = slow.next;
        }
        //反转后半段
        ListNode cur =slow.next;
        while (cur != null){
            ListNode curNext = cur.next;
            cur.next = slow;
            slow = cur;
            cur = curNext.next;
        }
        //此时slow是最后一个了
        while (slow != this.head){
            if (this.head.val != slow.val){
                return false;
            }
            if (this.head.next == slow){
                return true;
            }
            slow = slow.next;
            this.head = this.head.next;
        }
        return true;
    }
    
}
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2021-02-10,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 相关练习题如下
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档