在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();
}
}