实现链表--算法入门

简介: 实现链表--算法入门

1、模板链表

描述

请你实现一个链表。

方法:

insert x y:将y加入链表,插入在第一个值为x的结点之前。若链表中不存在值为x的结点,则插入在链表末尾。保证x,y为int型整数。

delete x:删除链表中第一个值为x的结点。若不存在值为x的结点,则不删除。

class LinkList {
    //利用数组存储链表值
    int[] data;
    //设置链表长度
    int size;
    //设置链表头
    int front = 0;
    //设置链表尾
    int rear = 0;
    //链表构造器
    public LinkList(int size) {
        data = new int[size];
    }
    //重新tostring方法,按照想要的方式输出对象值
    public String toString(){
        String str="";
        for(int j=0;j<rear;j++){
            str+=data[j]+" ";
        }
        return str;
    };
    public boolean isEmpty(){
        return size==0?true:false;
    }
    //往链表中加元素,规则为如果链表中存在x元素,则将y插入到x之前,没有的话就插入到链表尾
    public void insert(int x, int y) {
        //设置一个flag判断是否有x元素在数组中
        int b = -1;
        //表明数组满了,所以要进行数组扩容
        if (size == data.length) {
            //利用Arrays.copyof方法将满的数组赋值到新的数组,并且设置新的数组长度为原来数组长度的两倍
            int[] temp = Arrays.copyOf(data, data.length * 2);
            //将新数组赋值给旧的数组
            data = temp;
        //数组没满,就可以判断是否有x元素在数组内
        } else {
            //遍历链表看是否有x元素,如果有就将元素x的位置赋值给b
            for (int i = 0; i < data.length; i++) {
                if (data[i] == x) {
                    b = i;
                    //找到第一个元素x的位置就退出遍历
                    break;
                }
            }
            //利用b的值判断链表中是否有x元素,如果b==-1就没有
            if (b == -1) {
                //将尾指针的位置赋值y,并且将rear指针后移
                data[rear++] = y;
                //链表大小+1
                size++;
            //b不等于-1就表示链表中有x元素
            } else {
                //遍历链表数组将b位置的元素后移一位
                for (int i = rear; i > b; i--) {
                    data[i] = data[i - 1];
                }
                data[b] = y;
                rear++;
                size++;
            }
        }
    }
    //删除第一个指定元素
    public void delete (int x) {
        //设置一个flag判断链表中是否有x
        int b = -1;
        //判断链表是否为空
        if (size == 0) {
            return;
        } else {
            //遍历链表数组,看是否有x元素
            for (int i = 0; i < rear; i++) {
                //如果存在就保存x的位置给b,然后跳出遍历
                if (data[i] == x) {
                    b = i;
                    break;
                }
            }
            //判断是否操作x元素值,如果b不等于-1就表示有
            if(b!=-1){
                //遍历元素将元素前移动一个位置
                 for(int i=b;i<rear;i++){
                    data[i]=data[i+1];
                 }
                 //尾指针-1和链表大小-1
                 rear--;
                 size--;
            }
        }
    }
}

2、思想

本次数组存储实现链表的关键是用数组来存储链表节点的值,在实现插入方法的时候要判断链表是不是已经满了,如果满了就进行扩容,就是通过扩大一倍数组,然后将原来数据存储在新的数组中,如果不是满的,那么根据要求还得判断链表中是否有x元素,如果有的话就得将y元素存储在x元素之前,这就是要求对x元素及其以后的元素要往后移动一位,如果没有的话就直接存储在链表的尾部。在实现删除的方法的时候,要判断x元素是否存在数组中,如果存在的话要对该元素后面的元素进行往前移动一位,如果不存在就不用操作。

3、节点实现链表

 public static class ListNode {
        //节点值
        public int val;
        //下一个节点的位置
        public ListNode next;
        //节点构造器
        public ListNode(int val){
            this.val=val;
        }
    }
    //创建一个头结点,头结点值为-1
    public static ListNode head=new ListNode(-1);
    //往链表插入节点
    public static void insert(int x,int y){
        //创建一个值为y的新节点
        ListNode newNode=new ListNode(y);
        //将头节点赋值给名为node的节点
        ListNode node=head;
        //设置一个标志
        int sign=0;
        //如果node的下一个节点不是null
        while(null!=node.next){
            //如果下一个节点的节点值是x
            if(node.next.val==x){
                //将新建的节点的下一个节点设置为node的下一个节点
                newNode.next=node.next;
                //
                node.next=newNode;
                //将标志设置为1,表示已经插入了
                sign=1;
                //跳出循环
                break;
            }
            //将下一个节点设置为下一次循环的节点
            node=node.next;
        }
        //判断flag,如果flag==0表示上面的代码没有插入节点
        if(sign==0){
            //将新建的节点赋值给节点尾
            node.next=newNode;
        }
    }
    //删除节点值为x的节点
    public static void delete(int x){
        //创建一个头结点
        ListNode node=head;
        //如果下一个节点不是null的条件实现遍历链表
        while(node.next!=null){
            //判断下一个节点的节点值是否为x
            if(node.next.val==x){
                //如果是的话就将node的下一个节点设置为node的下一个的下一个节点
                node.next=node.next.next;
                //跳出循环
                break;
            }
            //将node设置为下一个节点
            node=node.next;
        }
    }

4、思想:本次利用节点实现链表主要是利用while语句实现对链表的遍历,在此前提是节点类要设置节点值和下一个节点,然后利用下一个节点不是null实现对链表的遍历,每次遍历最后都得将节点设置为下一个节点,在遍历也可以实现对节点值的访问。本次实现利用static将头节点固定了!!!

5、对比:数组实现和节点实现链表相比,数组实现的代码更多,也更加需要维护,链表实现的话每次加一个节点就是new了一个节点对象。个人感觉数组实心对于初学者更容易理解,但是个人推荐节点实现链表,因为数组实现插入和删除时可能要移动多个数据,节点实现的话就不需要这么麻烦。


相关文章
|
2月前
|
算法
【❤️算法笔记❤️】-每日一刷-19、删除链表的倒数第 N个结点
【❤️算法笔记❤️】-每日一刷-19、删除链表的倒数第 N个结点
71 1
|
2月前
|
算法 索引
❤️算法笔记❤️-(每日一刷-141、环形链表)
❤️算法笔记❤️-(每日一刷-141、环形链表)
51 0
|
2月前
|
算法
【❤️算法笔记❤️】-(每日一刷-876、单链表的中点)
【❤️算法笔记❤️】-(每日一刷-876、单链表的中点)
49 0
|
1月前
|
算法 安全 搜索推荐
2024重生之回溯数据结构与算法系列学习之单双链表精题详解(9)【无论是王道考研人还是IKUN都能包会的;不然别给我家鸽鸽丢脸好嘛?】
数据结构王道第2.3章之IKUN和I原达人之数据结构与算法系列学习x单双链表精题详解、数据结构、C++、排序算法、java、动态规划你个小黑子;这都学不会;能不能不要给我家鸽鸽丢脸啊~除了会黑我家鸽鸽还会干嘛?!!!
|
1月前
|
存储 Web App开发 算法
2024重生之回溯数据结构与算法系列学习之单双链表【无论是王道考研人还是IKUN都能包会的;不然别给我家鸽鸽丢脸好嘛?】
数据结构之单双链表按位、值查找;[前后]插入;删除指定节点;求表长、静态链表等代码及具体思路详解步骤;举例说明、注意点及常见报错问题所对应的解决方法
|
1月前
|
机器学习/深度学习 算法 Python
机器学习入门:理解并实现K-近邻算法
机器学习入门:理解并实现K-近邻算法
35 0
|
2月前
|
存储 缓存 算法
经典算法之链表篇(三)
经典算法之链表篇(三)
|
2月前
|
算法
经典算法之链表篇(二)
经典算法之链表篇(二)
|
2月前
|
算法 索引
经典算法之链表篇
经典算法之链表篇
|
2月前
|
算法
❤️算法笔记❤️-(每日一刷-160、相交链表)
❤️算法笔记❤️-(每日一刷-160、相交链表)
18 1