1、前言
很明显java没有指针,这会使你在理解链表的时候造成一定的困难。起码我在学习的时候很懵,随着慢慢理解和查资料对java的底层可能稍微有了一点的了解。所以分享一下自己的体会,也许可以帮助到大家。
2、链表
(1)节点的描述
package structure.com;
//描述节点
public class Node {
public Object data;//存放节点的数据
public Node next;//存放后继节点
public Node() {
this(null,null);
}
public Node(Object data) {
this(data,null);
}
public Node(Object data, Node next) {
this.data=data;
this.next=next;
}
}
对于节点的描述我在学习的过程中,研究好几天,可能是自己基础差的原因。节点这里的描述涉及到java的构造方法。很明显这里的节点存储数据data和存放后继节点的next。在这里你先这样理解,看下文慢慢理解。
(2)链表的实现
package structure.com;
import java.util.Scanner;
public class LinkList {
public Node head;
public LinkList() {//初始化头结点
head=new Node();
}
}
这里的head是头指针,有人在这里可能问了,java不是没有指针吗?你可以在这里这样理解没有错。接下来我详细解释一下为什么head可以理解为指针呢。在理解这前大家先看一下这张图。(如果你对java的内存没有很好的理解的话,你可以看这片博客:https://blog.csdn.net/baidu_38978508/article/details/89226553)
这张图说明了head就是一个引用,它就是指向堆内存的数据。对于刚才代码,实际是这样。你在链表实现的时候,你会创建一个对象。
LinkList l=new LinkList();//初始化head
在你new一个新的对象l时,那么你已经对head进行实例化。new的时候会执行下面代码的构造方法
public Node head;
public LinkList() {//初始化头结点
head=new Node();
}
而head=new Node();
时同样会执行在描述节点里面对应的构造方法。既下面的构造的方法:
public Node() {
this(null,null);
}
public Node(Object data) {
this(data,null);
}
public Node(Object data, Node next) {
this.data=data;
this.next=next;
}
执行构造方法时,是根据参数而触发对应的构造方法。到这里为止,已经将head指向堆内存中的数据了。完美,你是不就可以head.next了呢?可以,因为现在的head你就可以理解为指针。
这是java底层逻辑实现的过程。我们理解即可,不理解会用即可,不要过于纠结底层的操作。底层的操作可能帮助你更好的理解java吧。
3、完整的j链表java版数据结构
(1)节点
package structure.com;
//描述节点
public class Node {
public Object data;//存放节点的数据
public Node next;//存放后继节点
public Node() {
this(null,null);
}
public Node(Object data) {
this(data,null);
}
public Node(Object data, Node next) {
this.data=data;
this.next=next;
}
}
(2)链表
package structure.com;
import java.util.Scanner;
public class LinkList {
public Node head;
public LinkList() {//初始化头结点
head=new Node();
}
public LinkList(int n,boolean order) {
this();//调用构造方法,初始化头节点
if(order) {
try {
create1(n);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}else {
try {
create2(n);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
public void create1(int n) throws Exception{//头插法
Scanner sc=new Scanner(System.in);
for(int i=0;i<n;i++) {
insert(i,sc.next());
}
}
public void create2(int n) throws Exception {//尾插法
Scanner sc=new Scanner(System.in);
for(int i=n-1;i>=0;i--) {
insert(i,sc.next());
}
}
public void clear() {//将链表置空
head.next=null;
head.next=null;
}
public int length() {//获取链表的长度
Node p=head.next;
int length=0;
while(p!=null) {
p=p.next;
length++;
}
return length;
}
public void insert(int i,Object x) throws Exception{//将元素x插入到i的位置上
Node p=head;
int j=-1;
while(p!=null&&j<i-1) {
p=p.next;
j++;
}
if(j>i-1||p==null) {
throw new Exception("插入的位置不合法");
}
Node s=new Node(x);
s.next=p.next;
p.next=s;
}
public void remove(int i) throws Exception{//删除指定位置的元素
Node p=head.next;
int j=-1;
while(p!=null&&j<i-1) {
p=p.next;
j++;
}
if(p==null&&j>i-1) {
throw new Exception("插入的位置不合法");
}
p.next=p.next.next;
}
public Object get(int i) throws Exception{//获取指定链表的数值
Node p=head.next;
int j;
for(j=0;j<i&&p!=null;j++) {
p=p.next;
}
if(j>i-1||p==null) {
throw new Exception("查找的元素不存在");
}
return p.data;
}
public int indexof(Object x) {//查找指定位置数据元素第一次在链表的出现的位置
Node p=head.next;
int j=0;
while(p!=null&&!p.data.equals(x)) {
p=p.next;
j++;
}
if(p!=null) {
return j;
}else {
return -1;
}
}
public static void main(String[] args) {
// TODO Auto-generated method stub
LinkList l=new LinkList();//初始化head
Scanner sc = new Scanner(System.in);
int n;
int val;
System.out.println("请输入数组的大小:");
n=sc.nextInt();//数组的长度
for(int i=0;i<n;i++) {
Node q=l.head;
System.out.println("请输入数组的值:");
val=sc.nextInt();
Node p=new Node(val);//新建新的节点,同时申请内存空间
while(q!=null&&q.next!=null&&Integer.valueOf(q.next.data.toString())<val) {
q=q.next;
}
p.next=q.next;
q.next=p;
}
Node k=l.head;
for(int i1 = 0;i1<n;i1++) {
k=k.next;
System.out.println(k.data);
}
}
}
这是自己在学习理解和总结,如有不对的地方,还希望大家可以多多指点留言。也可以微信交流学习java学习java的数据结构。v:18847414978