1、链表
所谓链表就是相对顺序存储而言的一种无连续,无顺序的存储结构,因此需要占用每个节点的一些空间来存储下一个节点的指针域(Java中即为索引地址)。
2、单链表
单链表是指:每个节点只存储下一个节点的索引地址,最开始的节点称之为头节点,最后的节点的指向NULL,代表着该链表结束,
如下图所示:
3、单链表模型
4、单链表的代码实现
4.1、节点的类的创建
/** * 节点,单链表的节点 * */ public class Node<T> { //节点的数据 public T data; //指向下一个节点的引用(c++中的指针) public Node next; public Node(T data) { this.data = data; } }
4.2、单链表的实现
/** * 单链表的实现类 */ public class SingleLinkList { private Node<Object> header = null; public SingleLinkList() { header = new Node<Object>(0); } //添加节点在头节点之后,头插法(又称倒序插入法) public void addNodeToHead(Node<Object> node) { Node<Object> temp = header; int length = (int)header.data; if(temp.next != null) { temp = temp.next; header.next = node; node.next = temp; header.data = ++length; } else { header.next = node; node.next = null; header.data = ++length; } } //添加节点在尾节点之后,尾巴插法(又称正序插入法) public void addNodeToTail(Node<Object> node) { Node<Object> temp = header; int length = (int)header.data; while(temp.next != null) { temp = temp.next; } temp.next = node; node.next = null; header.data = ++ length; } //根据索引值插入节点 public void addNodeByIndex(int index, Node<Object> node) { int length = (int)header.data; if(index < 0 && index > length) { throw new IndexOutOfBoundsException("索引越界或者为负值"); } Node<Object> temp = header; for(int i = 0; i < index; i++) { temp = temp.next; } if(temp.next == null) { temp.next = node; node.next = null; } else { //将插入节点的下一个索引指向要插入链表index的节点。 node.next = temp.next; //将要插入索引的节点位置的前一个节点的节点索引指向要插入的节点。 temp.next = node; } header.data = ++ length; } //根据索引删除节点 public void delNodeByIndex(int index) { int length = (int)header.data; if(index < 0 && index > length) { throw new IndexOutOfBoundsException("索引越界或者为负值"); } Node<Object> temp = header; for(int i = 0; i < index; i++) { temp = temp.next; } if(temp.next == null) { temp = null; } else { Node<Object> delNode = temp.next; temp.next = delNode.next; delNode = null; } header.data = -- length; } //根据索引查询某个节点的值 public Object getDataByIndex(int index) { int length = (int)header.data; if(index < 0 && index > length) { throw new IndexOutOfBoundsException("索引越界或者为负值"); } Node<Object> temp = header; for(int i = 0; i < index; i++) { temp = temp.next; } return temp.next.data; } //打印单链表 public void print() { Node<Object> temp = header; while(temp.next != null) { temp = temp.next; System.out.print(temp.data + " "); } System.out.println(); } //批量添加节点在头节点之后,头插法(又称倒序插入法) public void addNodeListToHead(List<Node<Object>> list) { if(list == null || list.size() == 0) { return; } for (int i = 0; i < list.size(); i++) { addNodeToHead(list.get(i)); } } //批量添加节点在尾巴节点之后,头插法(又称倒序插入法) public void addNodeListToTail(List<Node<Object>> list) { if(list == null || list.size() == 0) { return; } for (int i = 0; i < list.size(); i++) { addNodeToTail(list.get(i)); } }
4.3、测试
public class Test { public static void main(String[] args) { System.out.println("Hello World!"); SingleLinkList linkList = new SingleLinkList(); //头插法插入节点 linkList.addNodeToHead(new Node<Object>(123)); linkList.addNodeToHead(new Node<Object>(1.11)); //尾插法插入节点 linkList.addNodeToTail(new Node<Object>("你好!")); linkList.addNodeToTail(new Node<Object>(56L)); //根据索引插入节点 linkList.addNodeByIndex(0, new Node(5)); linkList.addNodeByIndex(0, new Node(7.5)); linkList.addNodeByIndex(1, new Node(true)); //打印 linkList.print(); //根据索引查找节点 Object object = linkList.getDataByIndex(1); //打印出所查找的节点数据 System.out.println(object); //根据索引删除节点 linkList.delNodeByIndex(1); //打印 linkList.print(); } }
5、测试结果
Hello World! 7.5 true 5 1.11 123 你好! 56 true 7.5 5 1.11 123 你好! 56
6、结束