Java中链表的储存

本文详细介绍了Java中链表的表示方式,包括内存分配原理,以及如何使用Node类创建单链表并实现插入、删除和打印操作。还探讨了如何拓展链表结构,如双向链表和二叉树构造。
摘要由CSDN通过智能技术生成

 在Java中链表是如何表示的呢?

首先我们来看此代码

Node node = new Node();//node引用储存在虚拟机栈中,其创建的对象储存在堆中

Java中内存的分配方式有两种,一种是在堆中分配,一种是在栈中分配,所有new出来得到对象都是在堆中分配的,函数中参数的传递是在栈中分配的。


想象一下Java中链表的储存形式

请看下图:

使用Java代码将此图实现

package linked_test1;

/*链表类*/
class Node{
	public int val;
	public Node next;
}

public class linkedlist {

	public static void main(String[] args) {
		int[] a = {1, 2, 3, 4, 5, 6};//创建此数组的链表
		
		//Node node = new Node();node引用储存在虚拟机栈中,其创建的对象储存在堆中
		
		Node node = initLinkedList(a);//静态引用此方法
		
		System.out.println(node);
	}
	/*使用枚举创建链表*/
	private static Node initLinkedList(int[] a) {
		Node head = null;//创建链表头节点
		Node cur = null;
		
		/*创建链表节点,并将每个节点的值输入*/
		Node newNode5 = new Node();
		newNode5.val = a[5];
		Node newNode4 = new Node();
		newNode4.val = a[4];
		Node newNode3 = new Node();
		newNode3.val = a[3];
		Node newNode2 = new Node();
		newNode2.val = a[2];
		Node newNode1 = new Node();
		newNode1.val = a[1];
		Node newNode0 = new Node();
		newNode0.val = a[0];
		
		/*依次将每个节点连接起来*/
		head = newNode0;
		newNode0.next = newNode1;
		newNode1.next = newNode2;
		newNode2.next = newNode3;
		newNode3.next = newNode4;
		newNode4.next = newNode5;
	
		return head;
	}
}

对代码中的System.out.println(node);此句做断点调试后node的结构如下所示

可以看到此代码生成的链表呈链状

根据此问题还可拓展出双向链表的构造,二叉树的构造,n叉数的构造


更好的方法创建出链表

class Node{
    int data;
    Node next;
    public Node(int data){
        this.data = data;
    }
}
class MyLinkedList{
    Node head;
    int size;

    //尾插法插入节点
    public void addNode(int data){
        //在第一次调用时创建头节点
        if(head == null){
            head = new Node(data);
            size++;

        }
        else {
            //寻找尾节点
            Node temp = head;//定义临时节点遍历作为尾节点
            while (temp.next != null) {
                temp = temp.next;
            }

            Node pre = new Node(data);//创建新节点-要插入的节点
            temp.next = pre;
        }   size++;
    }

	//使用主函数测试
	public static void main(String[] args){
	        MyLinkedList mylist = new MyLinkedList();
	        mylist.addNode(1);
	        mylist.addNode(2);
	        mylist.addNode(3);
	        mylist.addNode(4);
	        mylist.addNode(5);
	        mylist.printList();
	       
	}
}

程序运行结果

我们成功创造出了一个简单链表

将此代码拓展

就成了一个单链表的增删查改操作

package linked_test;

class Node{
    int data;
    Node next;
    public Node(int data){
        this.data = data;
    }
}

public class MyLinkedList{
    Node head;
    int size;

    //尾插法插入节点
    public void addNode(int data){
        //在第一次调用时创建头节点
        if(head == null){
            head = new Node(data);
            size++;

        }
        else {
            //寻找尾节点
            Node temp = head;//定义临时节点遍历作为尾节点
            while (temp.next != null) {
                temp = temp.next;
            }

            Node pre = new Node(data);//创建新节点-要插入的节点
            temp.next = pre;
        }   size++;
    }

    //删除节点
    public void deleteNode(int index){//index为要删除的索引下标
        //处理空链表
        if(size == 0){
            return ;
        }
        //处理异常
        if(index < 0 || index >= size){
            return ;
        }
        //删除头节点
        if(index == 0) {
            head = head.next;
            return ;
        }
        Node temp = head;//临时节点遍历链表
        for(int i = 0; i < index - 1; i++){
            temp = temp.next;
        }
        temp.next = temp.next.next;

    }

    /*
     在第 index 个节点之前插入一个新节点,例如index为0,那么新插入的节点为链表的新头节点。
     如果 index 等于链表的长度,则说明是新插入的节点为链表的尾结点
     如果 index 大于链表的长度,则返回空
     */
    //插入节点
    public void insertData(int index, int data) {

        if (index > size) {
            return;
        }
        if (index < 0) {
            index = 0;
        }

        size++;
        //找到要插入节点的前驱
        Node temp = head;
        for (int i = 0; i < index - 1; i++) {
            temp = temp.next;
        }
        Node pre = new Node(data);
        pre.next = temp.next;
        temp.next = pre;
    }

    //打印链表
    public void printList(){
        Node temp = head;//临时节点遍历链表
        while(temp != null){
            System.out.print(temp.data + " ");
            temp = temp.next;
        }
        System.out.println();
    }

    public static void main(String[] args){
        MyLinkedList mylist = new MyLinkedList();
        mylist.addNode(1);
        mylist.addNode(2);
        mylist.addNode(3);
        mylist.addNode(4);
        mylist.addNode(5);
        mylist.printList();
        mylist.deleteNode(4);
        mylist.printList();
        mylist.insertData(4,1);
        mylist.printList();

    }
}
  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值