【JAVA】 单链表的基本操作(增删查改)代码详解

目录

1.链表:

2.链表的整体结构设计

3.显示打印链表中的val数值

4.查找关键字key是否在单链表当中,获取单链表长度size

5.头插法、尾插法

6.在任意位置(给定任意下标)插入节点node

7.删除第一次出现关键字为key的节点

8.删除所有值为key的节点


1.链表:

物理上不一定连续,逻辑上一定连续的

head里面存储的是第一个节点(头结点)的地址

head.next存储的下一个节点的地址

尾结点的next域为null

2.链表的整体结构设计

//ListNode  代表一个节点
class ListNode {    //在链表mylinkedlist里定义一个类:节点,包括两个属性数据域:val和节点域next
    public int val;
    public ListNode next;    //next存储的是节点的地址,所以类型为ListNode
    
    public ListNode(int val) {   //构造函数(带一个参数val),构造函数名与类相同:ListNode
        this.val= val;   //节点的引用
        this.next = next;     // next域默认值null
    }
}
public class MyLinkedList {     //head属于链表的属性,只能定义在链表里
   //成员变量
    public ListNode head;    //链表 的 头引用,head一致指向我的链表mylinkedlist的头部分,  因为head指向的是第一个节点的地址

//========================以上为链表结构的基本结构,===========================//

//方法的实现

    public void creatList() {     //创建一个方法  枚举法     创建链表(数组)数据
        ListNode listnode1 = new ListNode(12);     //创建一个链表下的各个节点
        ListNode listnode2 = new ListNode(23);    //实例化节点对象
        ListNode listnode3 = new ListNode(34);    //每个节点的数据val已知,但是next未给出,所以是默认null
        ListNode listnode4 = new ListNode(45);     //对象存放在堆里,包含属性val,next
        ListNode listnode5 = new ListNode(56);    //listnode1-5存放的是该节点的地址
        listnode1.next = listnode2;
        listnode2.next = listnode3;
        listnode3.next = listnode4;
        listnode4.next = listnode5;      //尾结点next为null,因为尾节点之后无节点了
        listnode5.next = null;   //可以不写,因为默认值就是null
        this.head = listnode1;    //head指向第一个节点
    }



}

3.显示打印链表中的val数值

显示打印链表中的val    head一直在移动会导致最后找不到head,因此用cur指代head
    public void display() {
        ListNode cur = this.head;   //用cur临时引用,来指向this.head所指向的对象
        while(cur != null) {        //当遍历到尾结点null之后,结束遍历  要最后一个尾结点地址不为null,尾节点的next域为null
            System.out.println(cur.val+" ");
            cur = cur.next;
        }
        System.out.println();
    }

4.查找关键字key是否在单链表当中,获取单链表长度size

  //查找是否包含关键字key是否在单链表当中   需要遍历链表的各个关节点(直至节点为null)
    public boolean contains(int key) {
        ListNode cur = this.head;        //用cur临时引用  ,来遍历链表各个节点
        while(cur != null) {    //cur遍历结束即停止
           if(cur.val == key) {
               return true;
           }
           cur = cur.next;    //继续遍历节点向后走
        }
        return false;      //没有找到关键字key
    }
//===============================================================================//
    //得到单链表的长度    //求多少个数据节点
    public int size() {
        int count = 0;
        ListNode cur = this.head;
        while(cur != null) {    //遍历到节点为null截止
            count++;
            cur = cur.next;
        }
        return count;
    }

5.头插法、尾插法

   //头插法   头插法属于倒序,因为后一个数要插在已有数的前面
// 用cur来遍历节点   头部插入之后,head发生变化要变为插入的那个节点
// node.next=head ,head=node
    public void addFirst(int data) {
        ListNode node = new ListNode(data);     //  new一个节点,   node 引用了对象,指代插入的节点
        node.next = head;
        this.head = node;      //若链表为空 this.head= node    把插入的节点给作为头节点
//        if(this.head == null) {   //若链表为空 this.node= head
//            this.head = node;
//        }     //也可
    }


//===================================================================================//
    //尾插法
    //寻找尾节点的方式:cur.next==null,cur所指向的节点即尾节点: cur.next = node
    //若链表为空null,没有节点,尾插法第一次插入必须判断,若为空head=node
    public void addLast(int data) {
        ListNode node = new ListNode(data);    //new一个节点node,指代插入的节点
        if(this.head == null) {   //判断链表是否为空 为空head就是node
            head = node;
        } else {
            ListNode cur = this.head;     //定义一个cur,遍历链表的各个节点
            while(cur.next != null) {     //cur.next = null,即找到尾结点,当前cur即尾结点
                cur = cur.next;
            }
            cur.next = node;   //找到尾节点之后便可插入给定节点node
        }
    }

6.在任意位置(给定任意下标)插入节点node


 // 当遍历的cur节点走到需要插入节点的下标号node.next=cur.next(node替代了当前的cur)
   //  要插入到目标位置,必须先找到目标位置的前一个位置index-1的位置
    
    public ListNode FindIndex(int index) {
        ListNode cur = this.head;
        while(index-1 != 0) {    //只要没走到需要插入的点,就需要一直遍历
            cur = cur.next;
            index--;
        }
        return cur;
    }
    //任意位置插入节点node,第一个数据节点为0号下标
    public void addIndex(int index,int data) {
        if(index < 0 || index > size()) {    //插入位置需要合法
            System.out.println("index位置不合法");
            return;
        }
        if(index == 0) {      //如果索引为0,即头插方式
            addFirst(data);
            return;
        }
        if(index == size()) {  //如果索引为size大小,即尾插方式
            addLast(data);
            return;
        }
        ListNode cur = FindIndex(index);
        ListNode node = new ListNode(data);
        node.next = cur.next;  //当遍历的cur节点走到需要插入节点的下标号node.next=cur.next(node替代了当前的cur)
        cur.next= node;
    }

7.删除第一次出现关键字为key的节点

 //需要先找删除节点key的前驱cur寻找前驱,因此定义一个cur
    public ListNode searchPerv(int key) {
        ListNode cur = this.head;    //定义cur,用于遍历链表各个节点
        while(cur.next != null) {     //判断结束条件
            if(cur.next.val == key) {
                return cur;    //如果找到删除的关键字,返回cur(此时指向要删除节点的前一个节点)
            }
            cur = cur.next;  //没找到则继续遍历
        }
        return  null;   //cur.next == null 结束遍历,到达尾结点,cur为空
    }
    //删除第一次出现关键字为key的节点       要考虑头、尾、中间情况
    public void remove(int key) {    //指向跳过关键字可以,也即是不指向就跳过了
        if(this.head == null) {      //头节点为空不能删除
            System.out.println("单链表为空,不能删除");
            return;
        }
        if(this.head.val == key) {   //判断头节点, 因为cur.next.val指的是第二个节点的val域,没有包含第一个头节点
            this.head = this.head.next;
            return;
        }
        ListNode cur = searchPerv(key);  //如果前驱没找到
        if(cur == null) {
            System.out.println("没有需要删除的节点!");
            return;
        }
        ListNode del = cur.next;
        cur.next = del.next;

    }

8.删除所有值为key的节点

 //删除所有值为key的节点   只需要遍历一遍就可删除所有点
    public ListNode removeAllKey(int key) {       //删除当前节点cur,指代地址,,必须知道前一节点prev  prev.next = cur.next,cur = cur.next
        if(this.head == null) return null;

        ListNode prev = this.head;     //pre为cur的前一个节点
        ListNode cur = this.head.next;    //cur为当前需要删除的节点

        while(cur != null) {    //循环条件
            if(cur.val == key) {
                prev.next = cur.next;  //删除之后prev指向cur.next
                cur = cur.next;    //  cur继续遍历,向后移动
            }else {
                prev = cur;  //  不需要删除prev需要和cur一起向后移动,继续遍历
                cur = cur.next;
            }
        }
        if(this.head.val == key) {    //最后处理头
            this.head = this.head.next;
        }
        return this.head;
    }
 //====================================================================================
   //清空链表   //使每一个链表节点没有被引用
    public void clear() {
        while(this.head != null) {
            ListNode curnext =head.next;
            this.head.next = null;    //挨个释放节点  把cur置空null
            this.head = curnext;
        }
    }

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Java和MySQL是广泛使用的编程语言和数据库管理系统。Java可以使用MySQL来存储、访问和操作数据。以下是Java和MySQL中最常用的增删改查操作的中文详解: 1. 添加数据 添加数据通常使用INSERT语句。例如,如果要向名为“students”的表中添加一条记录,具有“id”、“name”和“age”三个字段,可以使用以下Java代码: ``` String sql = "INSERT INTO students (id, name, age) VALUES (1, '张三', 20)"; Statement stmt = conn.createStatement(); stmt.executeUpdate(sql); ``` 2. 删除数据 删除数据通常使用DELETE语句。例如,如果要从名为“students”的表中删除所有年龄小于18岁的学生记录,可以使用以下Java代码: ``` String sql = "DELETE FROM students WHERE age < 18"; Statement stmt = conn.createStatement(); stmt.executeUpdate(sql); ``` 3. 修改数据 修改数据通常使用UPDATE语句。例如,如果要将名为“students”的表中所有年龄小于18岁的学生的姓名改为“未成年人”,可以使用以下Java代码: ``` String sql = "UPDATE students SET name = '未成年人' WHERE age < 18"; Statement stmt = conn.createStatement(); stmt.executeUpdate(sql); ``` 4. 查询数据 查询数据通常使用SELECT语句。例如,如果要从名为“students”的表中检索所有学生记录,可以使用以下Java代码: ``` String sql = "SELECT * FROM students"; Statement stmt = conn.createStatement(); ResultSet rs = stmt.executeQuery(sql); while(rs.next()) { int id = rs.getInt("id"); String name = rs.getString("name"); int age = rs.getInt("age"); System.out.println("ID:" + id + ",姓名:" + name + ",年龄:" + age); } ``` 以上是Java和MySQL中最常用的增删改查操作的中文详解。在实际应用中,还可以使用各种条件语句、排序和分组等操作来更精细地查询、修改和删除数据。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值