Java链表设计的特点
跳出代码实现层面,先从宏观上理解Java链表设计:
- 类代替指针:与C语言相对比,Java链表更为简单,因为Java省去了指针这个头疼的概念,把next的数据类型设为类,与指针有异曲同工之妙。
- 内部类传递:Java链表的节点类嵌套在链表实现类的里面,把节点类作为内部类,这极大方便了数据的调用,关于内部类的用法这里不再阐述,之前做过总结。
- 数据类型可变:Java链表可以采用泛型,适用于种引用数据类型。
- 递归算法:方法基本采用递归思想,逻辑清晰明了。
- 方法一分为二:方法也就是函数,它在链表实现类(外部类)完成有关根节点的操作,在节点类(内部类)完成其他节点的操作。
下面将在代码中具体讲解这5个设计特点。
Java链表的部分代码讲解
- 创建链表 的代码实现
class Link<T> {
private class Node{
private T data;
private Node next;
public Node(T t) {
this.data = t;
}
}
private Node root;
}
实现了节点类Node,节点类中有data数据,有存储下一个节点的next。还实现了根节点root。
- 数据添加 的代码实现
interface ILink<T>{
public void add(T t);
}
class Link<T> implements ILink<T>{
private class Node{
private T data;
private Node next;
public Node(T t) {
this.data = t;
}
public void addNode(Node newNode) {
if(this.next == null) {
this.next = newNode;
}else {
this.next.addNode(newNode);
}
}
}
private Node root;
private int count;
public void add(T t) {
if(this.root == null) {
Node newNode = new Node(t);
this.root = newNode;
// this.root.data = t; //这样不可以
}else {
Node newNode = new Node(t);
this.root.addNode(newNode);
}
this.count++;
}
接口ILink规定Link类的方法规范,仔细看可以发现:
- 添加根节点的时候是在Link类中的add方法中完成;
- 若根节点已存在要添加其他节点,通过add方法调用内部类中的addNode方法完成;
- addNode方法采用了递归算法;
或许你在疑惑为什么将addNode方法放在内部类中实现,这是为了访问和使用递归的方便。
Java链表设计的整体代码
import java.util.Arrays;
import java.util.Scanner;
interface ILink<T>{
public void add(T t);
public int size();
public boolean isEmpty();
public Object[] toArray();
public T get(int num);
public void set(int num,T data);
public boolean contains(T data);
public void remove(T data);
}
class Link<T> implements ILink<T>{
private class Node{
private T data;
private Node next;
public Node(T t) {
this.data = t;
}
public void addNode(Node newNode) {
if(this.next == null) {
this.next = newNode;
}else {
this.next.addNode(newNode);
}
}
public void toArrayNode() {
Link.this.returndata[Link.this.foot++] = this.data;
if(this.next !=null) {
this.next.toArrayNode();
}
}
public T getNode(int num) {
if(Link.this.foot++ == num) {
return this.data;
}else {
return this.next.getNode(num);
}
}
public void setNode(int num,T data) {
if(Link.this.foot++ == num) {
this.data = data;
}else {
this.next.setNode(num, data);
}
}
public boolean containsNode(T data) {
if(this.data.equals(data)) {
return true;
}else {
if(this.next != null) {
return this.next.containsNode(data);
}else {
return false;
}
}
}
public void removeNode(Node pre,T data) {
if(this.data.equals(data)) {
pre.next = this.next;
System.out.println("删除成功");
}else {
if(this.next != null) {
this.next.removeNode(this, data);
}
}
}
}
private Node root;
private int count;
private int foot;
private Object[] returndata;
public void add(T t) {
if(this.root == null) {
Node newNode = new Node(t);
this.root = newNode;
// this.root.data = t; //这样不可以
}else {
Node newNode = new Node(t);
this.root.addNode(newNode);
}
this.count++;
}
public int size() {
return this.count;
}
public boolean isEmpty() {
return this.count == 0;
}
public Object[] toArray() {
if(this.count == 0) {
return null;
}else {
this.foot = 0;
this.returndata = new Object[this.count];
this.root.toArrayNode();
}
return this.returndata;
}
public T get(int num) {
if(num < 0 ||num >= this.count) {
return null;
}else {
this.foot = 0;
return this.root.getNode(num);
}
}
public void set(int num,T data) {
if(num < 0 || num >= this.count) {
System.out.println("索引不合法");
return;
}else {
this.foot = 0;
this.root.setNode(num,data);
}
}
public boolean contains(T data) {
if(data == null) {
return false;
}
return this.root.containsNode(data);
}
public void remove(T data) {
if(this.contains(data)) {
if(this.root.data == data) {
this.root = this.root.next;
System.out.println("删除成功");
}else {
this.root.next.removeNode(root,data);
}
}
}
}
public class Demo5{
public static void main(String[] args) {
Link<String> in = new Link<String>();
in.add("申公豹");
in.add("姜子牙");
in.add("黄飞虎");
System.out.println("链表长度:"+in.size());
System.out.println("链表是否为空:"+in.isEmpty());
System.out.println("链表数据:"+Arrays.toString(in.toArray()));
Scanner on = new Scanner(System.in);
System.out.print("输入查询序列号:");
int num = on.nextInt();
System.out.println("序列号"+num+"的数据:"+in.get(num));
System.out.print("修改序列号:");
int num1 = on.nextInt();
System.out.print("序列号"+num1+"数据改为:");
String data = on.next();
// String data = on.nextLine(); //无法输入
in.set(num1, data);
System.out.print("输入查询数据:");
String data1 = on.next();
System.out.println("数据"+data1+"是否存在:"+in.contains(data1));
System.out.print("删除节点:");
String data11 = on.next();
in.remove(data11);
System.out.print("输入查询序列号:");
int num111 = on.nextInt();
System.out.println("序列号"+num111+"的数据:"+in.get(num111));
}
}