Java链表设计的特点

跳出代码实现层面,先从宏观上理解Java链表设计:

  1. 类代替指针:与C语言相对比,Java链表更为简单,因为Java省去了指针这个头疼的概念,把next的数据类型设为类,与指针有异曲同工之妙。
  2. 内部类传递:Java链表的节点类嵌套在链表实现类的里面,把节点类作为内部类,这极大方便了数据的调用,关于内部类的用法这里不再阐述,之前做过总结。
  3. 数据类型可变:Java链表可以采用泛型,适用于种引用数据类型。
  4. 递归算法:方法基本采用递归思想,逻辑清晰明了。
  5. 方法一分为二:方法也就是函数,它在链表实现类(外部类)完成有关根节点的操作,在节点类(内部类)完成其他节点的操作。

下面将在代码中具体讲解这5个设计特点。

Java链表的部分代码讲解

  1. 创建链表 的代码实现
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。

  1. 数据添加 的代码实现
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类的方法规范,仔细看可以发现:

  1. 添加根节点的时候是在Link类中的add方法中完成;
  2. 若根节点已存在要添加其他节点,通过add方法调用内部类中的addNode方法完成;
  3. 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));
	}
}