首页 > 编程语言 >Java有关链表的基本操作

Java有关链表的基本操作

时间:2023-09-11 22:35:44浏览次数:59  
标签:Node index Java next 链表 基本操作 preNode 节点

上一篇发表的数组的基本操作,但是数组有优势也有劣势:

·具体的优势是:拥有高效的随机访问能力

·劣势是:由于排列紧密相连,插入和删除元素都会导致大量元素被迫移动,影响效率。

接下来要阐述的数据结构是链表:

·先看看单向链表的结构:

单向链表的每一个节点又包含两个部分,一部分是存放数据的变量data,另一部分是指向下一节点的指针next。

private static class Node{
        int data;
        Node next;
    }

再看看双向链表:

·如果说数组在内存中的存储方式是顺序存储,那链表在内存中的存储方式是随机存储,
链表的每一个节点分布在不同的位置上,依靠next指针练习起来。

进入正题:链表的基本操作!

1.查找节点:
查找元素时,链表只能从头节点开始向后一个一个节点逐一查找
第一步:将查找的指针定位到头节点;
第二步:根据头节点的next指针,定位到第2个节点;
第三步:以此类推。

public Node get(int index) throws Exception{
        if(index<0||index>=size){
            throw new IndexOutOfBoundsException("访问越界!!!");
        }
        //将查找的指针定位到头节点
        Node temp=head;
        for(int i=0;i<index;i++){
            temp=temp.next;
        }
        return temp;
    }

2.更新节点:
链表的更新过程与数组类似,直接将旧数据替换成新数据即可。

public void updateNode(int data,int index) throws Exception{
        if(index<0||index>size){
            throw new IndexOutOfBoundsException("访问越界!!!");
        }
        Node temp=head;
        for(int i=0;i<index;i++){
            temp=temp.next;
        }
        temp.data=data;
    }

3.插入节点:
与数组类似,链表插入节点时,同样分为三种情况:
尾部插入:

把最后一个节点的next指针指向新插入的节点即可。

头部插入:

大致分为两步
第一步:将新节点的next指针指向原先的头节点;
第二步:将新节点变成链表的头节点。

中间插入:

分为两步
第一步:新节点的next指针,指向插入位置的节点;
第二部:插入位置前置节点的next指针,指向新节点。

public void insert(int data,int index) throws Exception{
        //判断是否访问越界
        if(index<0||index>size){
            throw new IndexOutOfBoundsException("访问链表越界!!!");
        }
        //创建一个节点
        Node insertdNode=new Node(data);
        if(size==0){
            //空链表
            head=insertdNode;
            last=insertdNode;
        }else if(index==0){
            //插入头部
            insertdNode.next=head;
            head=insertdNode;
        }else if(index==size){
            //插入尾部
            last.next=insertdNode;
            last=insertdNode;
        }else{
            //插入中间
            Node preNode=get(index-1);//插入位置的前置节点
            insertdNode.next=preNode.next;
            preNode.next=insertdNode;
        }
        size++;
    }

4.删除节点:
分为三种情况

  •      尾部删除:
    
  •      将倒数第二个节点的next指针指向空即可。
    
  •      头部删除:
    
  •      将链表的头节点设为原先头节点的next指针即可。
    
  •      中间删除:
    
  •      将要删除的节点的前置节点的next指针指向要删除节点的下一个节点即可。
    

public Node remove(int index) throws Exception{
        //判断是否访问越界
        if(index<0||index>=size){
            throw new IndexOutOfBoundsException("访问越界!!!");
        }
        //初始化删除节点
        Node removedNode=null;
        if(index==0){
            //删除头节点
            removedNode=head;
            head=head.next;
        }else if(index==size){
            //删除尾节点
            Node preNode=get(index-1);
            removedNode=preNode.next;
            preNode.next=null;
            last=preNode;
        }else{
            //删除中间节点
            Node preNode=get(index-1);//要删除节点的前置节点
            removedNode=preNode.next;
            preNode.next=preNode.next.next;
        }
        size--;
        return removedNode;
    }

5.链表基本操作的完整代码:

点击查看代码
package LiknList;

public class MyLinkList {
    //链表节点
    private static class Node{
        int data;
        Node next;
        Node(int data){
            this.data=data;
        }
    }
    //头节点指针
    private Node head;
    //尾部节点
    private Node last;
    //链表实际长度
    private int size;

    //链表插入元素(int data:要插入的元素,int index:要插入的位置)
    public void insert(int data,int index) throws Exception{
        //判断是否访问越界
        if(index<0||index>size){
            throw new IndexOutOfBoundsException("访问链表越界!!!");
        }
        //创建一个节点
        Node insertdNode=new Node(data);
        if(size==0){
            //空链表
            head=insertdNode;
            last=insertdNode;
        }else if(index==0){
            //插入头部
            insertdNode.next=head;
            head=insertdNode;
        }else if(index==size){
            //插入尾部
            last.next=insertdNode;
            last=insertdNode;
        }else{
            //插入中间
            Node preNode=get(index-1);//插入位置的前置节点
            insertdNode.next=preNode.next;
            preNode.next=insertdNode;
        }
        size++;
    }

    //链表删除元素(index:删除的位置)
    public Node remove(int index) throws Exception{
        //判断是否访问越界
        if(index<0||index>=size){
            throw new IndexOutOfBoundsException("访问越界!!!");
        }
        //初始化删除节点
        Node removedNode=null;
        if(index==0){
            //删除头节点
            removedNode=head;
            head=head.next;
        }else if(index==size){
            //删除尾节点
            Node preNode=get(index-1);
            removedNode=preNode.next;
            preNode.next=null;
            last=preNode;
        }else{
            //删除中间节点
            Node preNode=get(index-1);//要删除节点的前置节点
            removedNode=preNode.next;
            preNode.next=preNode.next.next;
        }
        size--;
        return removedNode;
    }

    //链表查找元素(index:查找的位置)
    public Node get(int index) throws Exception{
        if(index<0||index>=size){
            throw new IndexOutOfBoundsException("访问越界!!!");
        }
        //将查找的指针定位到头节点
        Node temp=head;
        for(int i=0;i<index;i++){
            temp=temp.next;
        }
        return temp;
    }

    //更新节点(data:更新的数据,index:更新的位置)
    public void updateNode(int data,int index) throws Exception{
        if(index<0||index>size){
            throw new IndexOutOfBoundsException("访问越界!!!");
        }
        Node temp=head;
        for(int i=0;i<index;i++){
            temp=temp.next;
        }
        temp.data=data;
    }

    //输出链表
    public void output(){
        Node temp=head;
        while(temp!=null){
            System.out.print(temp.data+" ");
            temp=temp.next;
        }
    }

    public static void main(String[] args) throws Exception {
        MyLinkList myLinkList=new MyLinkList();
        myLinkList.insert(3,0);
        myLinkList.insert(7,1);
        myLinkList.insert(9,2);
        myLinkList.insert(5,3);
        myLinkList.insert(6,1);
        myLinkList.remove(0);
        myLinkList.updateNode(4,1);
        myLinkList.output();
    }
}

6.数组和链表的好与坏:
数组:查找和更新都是O(1),插入和删除是O(n);
链表:查找是O(n),其余都是O(1)。

标签:Node,index,Java,next,链表,基本操作,preNode,节点
From: https://www.cnblogs.com/whoami000/p/17694713.html

相关文章

  • 3. Java数据类型
    Java数据类型:基本数据类型和引用数据类型前面我们提到 Java 语言是强类型语言,编译器存储在变量中的数值具有适当的数据类型。学习任何一种编程语言都要了解其数据类型,本文将详细介绍Java中的数据类型。Java语言支持的数据类型分为两种:基本数据类型(PrimitiveType)和引用数据......
  • Java实现简易论文查重
    https://github.com/stopyc/3121005018Java实现简易论文查重软件工程https://edu.cnblogs.com/campus/gdgy/CSGrade21-12作业要求https://edu.cnblogs.com/campus/gdgy/CSGrade21-12/homework/13014作业目标学习使用Java建立工程项目,学会论文查重的具体实现步骤......
  • 2.1 Java程序设计基础
    1Java程序设计基础1.1要想编写规范、可读性高的Java程序,就必须对Java基本语法有所了解。基本语法是所有编程语言都必须掌握的基础知识,也是整个程序代码不可缺少的重要部分。一个Java程序通常由数据类型、变量、运算符和控制流程语句4部分组成。其中数据类型和运算符不仅......
  • 重排链表
     解题思路:采用快慢指针的方法将单链表分成两半,再对两部分的链表进行合并voidreorderList(structListNode*head){  if(head==NULL||head->next==NULL){    return;  }    //找到链表中间节点  structListNode*slow=head; ......
  • Java集合
    集合框架单列集合:双列集合:集合和数组的区别长度:数组固定长度内容:集合只能是引用类型元素:数组只能存储同一类型Collection接口实现类有些可以重复,有些有序,没有直接实现,而是子接口//常用方法list.add(true)//可以添加不同类型 .remove(true)//可以按索引也可以直接删......
  • 无涯教程-JavaScript - ODDFPRICE函数
    描述ODDFPRICE函数返回面值为$100的第一期奇数(短期或长期)证券的价格。语法ODDFPRICE(settlement,maturity,issue,first_coupon,rate,yld,redemption,frequency,[basis])争论Argument描述Required/OptionalSettlement证券的结算日期。证券结算日期是指在......
  • Java(day10):注释
    Java注释前言在编写代码时,注释一直被认为是良好编程实践的一部分。注释可以帮助提高代码的可读性,减少代码的维护成本,同时也是文档化代码的一种方式。本文将介绍Java中的注释类型及其用法。摘要本文将讨论Java中的三种注释类型:单行注释,多行注释和文档注释,并提供一些最佳实践和示......
  • 《Java编程思想第四版》学习笔记27
    //:DirList2.java//UsesJava1.1anonymousinnerclassesimportjava.io.*;publicclassDirList2{publicstaticFilenameFilterfilter(finalStringafn){//Creationofanonymousinnerclass:returnnewFilenameFilter(){St......
  • 1. Java语言概述
    1.Java语言概述1.Java技术体系JavaSE(JavaStandardEdition)标准版JavaEE(JavaEnterpriseEdition)企业版JavaME(JavaMicroEdition)小型版2.Java开发环境介绍‍JDK(javaDevelopmentkit):是Java程序开发工具包,包含JRE和开发人员使用的工具。JRE(JavaRun......
  • JAVA集合框架体系
    集合框架--容器包容JAVA集合框架中的类可以用于存储多个队系那个,还可用于保存具有映射关系的关联数组。Collection接口单列数据集合。存储一个一个的数据。#常用方法:增add(Eobj)-->加的是一个addall(Collectionother)-->加基本单元,五个小单元组成的中单元放进......