Java数据结构(4)- 链表

本文深入探讨数据结构的重要性,特别是在提高数据处理效率方面。通过类比,文章解释了合理选择数据结构的原因,并详细介绍了链表这一数据结构的实现与操作,包括节点的添加和遍历过程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、什么是数据结构

定义:计算机存储和组织数据的方式
目的:用来提高数据处理的效率

举个例子,如果你只想喝一口水,你觉得是拿个小杯子喝一点好,还是拿一个200斤的桶喝水好?谁的效率更高一点(如果你执意要拿200斤的桶喝水,当我上面就是放屁。),所以选择一个合理的数据结构来存储数据,能够提高很多的效率。

分类:在Java中为我们提供了八种数据结构来存储数据

队列,堆,栈,二叉树,链表,图,散列图等八种数据结构,不同的数据结构其内部的实现原理不一样。

回顾一下曾经我们所学过的数据容器有哪些
public class Test{
	public static void main(string args[]){
		/*
		1、基本数据类型+变量名
		通过自定一个数据类型+变量名来存储数据
		特点:存储的是一个具体的值,只能赋值一次,
		第二次赋值时就会覆盖掉原先的数据
		*/
		int i = 10;
		/*
		2、数组
		数组:在内存空间中,开辟一块连续的存储空间,有序的
		但是长度固定,而且只能存储同一数据类型,每次扩容
		都需要重新new一个数组对象来增加容量
		*/
		//定义长度为10的整数数组
		int[] arr = new int[10];
	}
}
	/*
	3、自定义类
	通过自定义类,在类中定义字段等,来存储数据,也可以作为
	容器来存储数据
	*/
class Student{
	String name;
	int age;
}
自定义容器链表

分析:什么是链表,从名字上来看。链:铁链,锁链。。都是一环扣着另一环,上一环连接着下一环。如果想在代码上实现来看是怎么样的呢?

class MyLinkedList{
    /*
    *  自定义的一个链表我们需要什么呢?
    *  一条整体的铁链,一条铁链对象是不是需要?
    *  然后我们还需要其中一个环扣另一个环的  环对象是不是?
    *
    *  一条铁链,如何开始?
    *       是不是需要有一个头部来开始?(做任何事情是不是都需要有一个开始)
    *       然后,铁链,一环接着一环是不是?而每个具体的环就称为一个 节点 对象
    *
    * */
    //所以,我们定义一个字段里面保存第一个节点对象的地址
    Node root;
}
//节点类,代表着 铁链内部的每一个环
class Node{
    //链表的目的是什么,存储数据的,而数据 存储在那里? 是不是在每一个具体的节点上,所以我们节点对象里面
    //是不是需要有一个存储数据的字段,这个字段里面可以存储任意的数据类型,我们就定义成Object类型
    Object data;
    
    /**
     * 想一下铁链,是不是一个环扣着一个环,那么一个环是如何连着另一个环呢?
     * 直接将下一个节点的地址保存在当前节点的字段里面是不是就可以了
     */
    //定义一个字段来存储下一个节点的地址
    Node next;

    //定义一个构造方法在创建节点的时候就传入数据
    public Node(Object data){
        this.data = data;
    }
}

上面我们自定义链表容器的基础已经准备好了,接下来就是看如何往里面添加元素了

 /**
     *  接下来就是如何添加元素了
     *  首先我先定义一个添加方法
     */
    public void add(Object obj){
        //每次调用该方法,我们就new一个节点对象,接收外面传进来的数据
        Node node = new Node(obj);
        //先进行判断,看看我们的头部,也就是查看有没有第一个节点
        if(root  == null){
            //如果没有,那么就将当前的节点赋值给root
            root = node;
        }else{
            //使用循环来遍历整个链表,来查找最后一个元素
            //将root第一个节点赋值给一个临时变量
            Node temp = root;
            //判断第一个节点是否存有下一个节点的地址
            while(temp.next != null){
                //如果不为空,那么就将下一个节点的地址赋值给temp
                //这样就可以循环的查找,直到找到最后一个节点
                temp = temp.next;
            }
            //如果找到了最后一个就将当前节点的地址赋值给next
            temp.next = node;
        }
	//覆toString方法来打印链表中的值
	    @java.lang.Override
	    public java.lang.String toString() {
	        return "MyLinkedList{" +
	                "root=" + root +
	                '}';
	    }

注意toString方法在Node类中也需要覆写一次,这是为了打印链表中具体的值,不然打印的出来就会是地址值。

//最后检查一下成果
public class LinkedList{
    public static void main(String args[]){
    //先创建一条链表对象
        MyLinkedList ml = new MyLinkedList();
        //调用add方法
        ml.add("asd");
        ml.add("123");
        ml.add("asd");
        ml.add("asd");
		//打印ml链表
        System.out.println(ml);

    }
}

在这里插入图片描述
元素成功的添加进去了。。。

总结一下,链表,就是对字段进行操作,每一个节点分为上下两个部分,上部分为存储数据,下部分为指向下一个节点的地址,操作链表,就是对每一个节点的地址进行操作

### Java 数据结构 链表 实现教程 #### 单链表的定义与基本实现 在 Java 中,单链表可以通过自定义类来实现。以下是基于引用的内容构建的一个完整的单链表实现方案。 ```java public class LinkedList { // 定义内部节点类 public static class Node { public int data; // 假设节点存储的数据类型为 int public Node next; public Node(int data) { this.data = data; this.next = null; } } private Node head = null; // 初始化头节点为空 // 添加节点的方法 public void addNode(int data) { Node newNode = new Node(data); if (head == null) { // 如果链表为空,则新节点作为头节点 head = newNode; } else { Node temp = head; while (temp.next != null) { // 找到最后一个节点 temp = temp.next; } temp.next = newNode; // 将新节点连接到最后一个节点之后 } } // 获取链表长度(不统计头节点) public int getLength() { if (head == null) { // 空链表返回 0 return 0; } int length = 0; Node current = head; while (current != null) { // 遍历整个链表 length++; current = current.next; } return length; } // 输出链表内容 public void displayList() { Node node = head; while (node != null) { System.out.print(node.data + " -> "); node = node.next; } System.out.println("null"); } } ``` 上述代码实现了单链表的基本功能,包括添加节点、计算链表长度以及打印链表内容的功能[^1]。 --- #### 链表的特点及其存储方式 链表是一种物理存储单元上非连续、非顺序的存储结构。它的特点是数据元素之间的逻辑顺序通过链表中的指针链接次序实现。具体来说,链表由一系列结点组成,每个结点包含两部分:一部分用于存储数据元素(即数据域),另一部分用于存储下一个结点地址(即指针域)。这种特性使得链表能够在运行时动态生成新的结点[^2]。 --- #### 计算链表的有效节点数量 为了获取单链表中有效节点的数量,可以采用以下方法: ```java public static int countNodes(Node head) { if (head == null || head.next == null) { // 判断是否为空链表或者只有一个头节点 return 0; } int count = 0; Node currentNode = head.next; // 不统计头节点本身 while (currentNode != null) { count++; currentNode = currentNode.next; } return count; } ``` 此函数能够有效地忽略头节点并仅统计实际有效的数据节点[^3]。 --- #### 遍历环形链表 如果需要处理的是环形链表,则其遍历方式略有不同。通常情况下,会利用辅助指针 `cur` 来完成这一操作。例如,在环形链表中找到某个特定条件下的节点或执行其他复杂操作时,可按照如下方式进行: ```java // 创建环形链表 public static void createCircularLinkedList(Node[] nodes) { for (int i = 0; i < nodes.length - 1; i++) { nodes[i].next = nodes[i + 1]; } nodes[nodes.length - 1].next = nodes[0]; // 形成闭环 } // 遍历环形链表 public static void traverseCircularList(Node first) { if (first == null) { return; } Node cur = first; do { System.out.print(cur.id + " -> "); cur = cur.next; } while (cur != first); // 当回到起点时停止 System.out.println(first.id); // 补充最后一个节点输出 } ``` 这段代码展示了如何创建和遍历环形链表的过程[^4]。 --- #### 总结 以上介绍了单链表基础概念及其实现细节,并进一步探讨了如何计算链表长度以及遍历环形链表的具体方法。这些知识点构成了理解 Java 数据结构链表的核心基础
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值