目录
链表的实现可以为后面JAVA的类集框架服务。
链表是一种最简单的数据结构,其主要目的是依靠引用关系实现多个数据的保存。
一:链表的定义
定义一个Node类,保存的数据是String型,同时存储下一个数据的引用。
Node类只负责保存节点关系,但是具体的保存由其他类负责
class Node{ /*链表的属性*/ private String data;//数据 private Node next;//下一个节点 /*链表的构造*/ public Node(String data) {//构造函数,定义数据 this.data=data; } public void setNode(Node next) {//存储下一个节点信息 this.next=next; } /*功能函数:取出数据或下一节点*/ public String getData() { return this.data; } public Node getNode() { return this.next; } }
取数据:主程序法
public static void main(String[] args) { /*第一步:创建链表*/ Node root=new Node("火车头"); Node n1=new Node("车厢A"); Node n2=new Node("车厢B"); root.setNode(n1); n1.setNode(n2); n2.setNode(null); /*第二步:取出所有数据*/ Node curNode=root; while(curNode!=null) { System.out.println(curNode.getData()); curNode=curNode.getNode(); } }
public static void print(Node cur) { if(cur==null) return; System.out.println(cur.getData()); print(cur.getNode());//递归调用print() }
最后程序:
class Node{ /*链表的属性*/ private String data;//数据 private Node next;//下一个节点 /*链表的构造*/ public Node(String data) {//构造函数,定义数据 this.data=data; } public void setNode(Node next) {//存储下一个节点信息 this.next=next; } /*功能函数:取出数据或下一节点*/ public String getData() { return this.data; } public Node getNode() { return this.next; } } public class transfer { public static void main(String[] args) { /*第一步:创建链表*/ Node root=new Node("火车头"); Node n1=new Node("车厢A"); Node n2=new Node("车厢B"); root.setNode(n1); n1.setNode(n2); n2.setNode(null); print(root);//调用函数 } public static void print(Node cur) { if(cur==null) return; System.out.println(cur.getData()); print(cur.getNode());//递归调用print() } }
由于取数据无法知道长度,一般只能用while,但是由于定义函数递归调用会比while更直观更易读。
核心:封装Node类的数据,然后利用Node的引用传递去排序数据。
二:链表的改进
上述定义存在的问题:
1:用户在操作链表功能时没必要知道Node类的存在。
2:节点的引用关系不应该由用户处理,需要一个专门工具类
总之:客户端应该向用户隐藏链表的具体细节,用户只需要知道怎么存数据和取数据
这里选用尾插法,目的是为了在已有节点的最后插入新节点,根节点root不存数据
class Node{//作为隐藏类,用户无需清楚 /*节点的添加:目的找到已有数据的最后一个节点*/ public void addNode(Node newNode) { //第一次调用:Link.root if(this.next==null) {//根节点后为空,直接连 this.next=newNode; } else {//根节点后有数据,递归 this.next.addNode(newNode); } } public void printNode() { System.out.println(this.data); if(this.next!=null) { this.next.printNode(); } } }
在Node类新加入两个函数:addNode()和printNode(),目的在于为用户操作的LinkNode类提供打印和添加节点操作。
class Link{//负责数据的设置和输出 private Node root;//起始标志 /*增加数据*/ public void add(String data) { Node newNode=new Node(data); if(this.root==null) this.root=newNode;//没有根节点时执行,且执行一次 else this.root.addNode(newNode);//根节点已经存在了,采取尾插法 } /*取出数据*/ public void print() { if(this.root!=null) { this.root.printNode(); } } }
创建链表的逻辑:
首先利用new关键字,在内存中开辟出空间(Node newNode=new Node(data);)
然后判断有无根节点,这是链表创建的初始化,如果有了根节点,接下来的操作也就是节点next的指向通过调用Node类的:addNode()
下面进行尾插法:(找到最后一个节点)
1:根节点后无新节点,直接:(this.next=newNode;)
2:根节点有新节点,递归调用addprint()去寻找,找到后执行(this.next=newNode;)
主程序 **:
** Link link=new Link();//创建了根节点
link.add("火车头");
link.add("车厢A");
link.add("车厢B");
link.add("车厢C");总结:
Link类:控制Node类对象的产生和根节点
Node类:主要负责数据的保存和引用关系的分配
最后代码:
class Node{//作为隐藏类,用户无需清楚
/*链表的属性*/
private String data;
private Node next;
/*链表的构造*/
public Node(String data) {
this.data=data;
}
public void setNode(Node next) {
this.next=next;
}
/*功能函数:取出数据或下一节点*/
public String getData() {
return this.data;
}
public Node getNode() {
return this.next;
}
/*节点的添加:目的找到已有数据的最后一个节点*/
public void addNode(Node newNode) {
//第一次调用:Link.root
if(this.next==null) {//根节点后为空,直接连
this.next=newNode;
}
else {//根节点后有数据,递归
this.next.addNode(newNode);
}
}
public void printNode() {
System.out.println(this.data);
if(this.next!=null) {
this.next.printNode();
}
}
}
class Link{//负责数据的设置和输出
private Node root;//起始标志,不保存数据,指向下一个节点
/*增加数据*/
public void add(String data) {
Node newNode=new Node(data);
if(this.root==null) this.root=newNode;//没有根节点时执行,且执行一次
else this.root.addNode(newNode);//根节点已经存在了,采取尾插法
}
/*取出数据*/
public void print() {
if(this.root!=null) {
this.root.printNode();
}
}
}
public class transfer {
public static void main(String[] args) {
Link link=new Link();
link.add("火车头");
link.add("车厢A");
link.add("车厢B");
link.add("车厢C");
link.print();
}
}
\