链表

链表(Linked list)是一种常见的基础数据结构,是一种线性表,但是并不会按线性的顺序存储数据,而是在每一个节点里存到下一个节点的指针(Pointer)。使用链表结构可以克服数组链表需要预先知道数据大小的缺点,链表结构可以充分利用计算机内存空间,实现灵活的内存动态管理。但是链表失去了数组随机读取的优点,同时链表由于增加了结点的指针域,空间开销比较大。

在计算机科学中,链表作为一种基础的数据结构可以用来生成其它类型的数据结构。链表通常由一连串节点组成,每个节点包含任意的实例数据(data fields)和一或两个用来指向上一个/或下一个节点的位置的链接(”links”)。链表最明显的好处就是,常规数组排列关联项目的方式可能不同于这些数据项目在记忆体或磁盘上顺序,数据的访问往往要在不同的排列顺序中转换。而链表是一种自我指示数据类型,因为它包含指向另一个相同类型的数据的指针(链接)。链表允许插入和移除表上任意位置上的节点,但是不允许随机存取。链表有很多种不同的类型:单向链表,双向链表以及循环链表引用自博客园-月亮编程

单向链表

单向链表是最简单的链表,它由节点组成,每一个节点,记录了该节点的数据和指向下一个节点的指针,最后一个元素指向为null。如下图:
单链表
代码实现,实例代码为java

  1. class Node{
  2. public String data;//链表的数据先采用简单的String
  3. public Node next;//下一个节点
  4. public Node(String data){
  5. this.data = data;
  6. }
  7. public void setNext(Node node){
  8. this.next = node;
  9. }
  10. public String getData(){
  11. return this.data;
  12. }
  13. public Node getNext(){
  14. return this.next;
  15. }
  16. }
  17. public class TestLink{
  18. public static void main(String[] arg){
  19. //定义head
  20. Node head = new Node("我是head");
  21. Node node1 = new Node("我是node1");
  22. Node node2 = new Node("我是node2");
  23. Node node3 = new Node("我是node3");
  24. head.setNext(node1);//设置head的下一个节点为node1
  25. node1.setNext(node2);//设置node1的下一个节点为node2
  26. node2.setNext(node3);//设置node2的下一个节点为node3
  27. print(head);
  28. }
  29. //递归调用打印链表
  30. public static void print(Node head){
  31. //当最后一个的getNext()返回null,表示链表已经到底了
  32. if(head.getNext() == null){
  33. return;
  34. }
  35. System.out.println(head.getData());
  36. print(head.getNext());
  37. }
  38. }
  39. //java TestLink
  40. //我是head
  41. //我是node1
  42. //我是node2

循环链表

循环链表和单向链表基本相似,也是由节点组成,每一个节点,记录了该节点的数据和指向下一个节点的指针,但不同的是,它的最后一个节点指向不是null,而是指向第一个元素。如下图:
循环链表
代码实现,实例代码为java

  1. class Node{
  2. public String data;//链表的数据先采用简单的String
  3. public Node next;//下一个节点
  4. public Node(String data){
  5. this.data = data;
  6. }
  7. public void setNext(Node node){
  8. this.next = node;
  9. }
  10. public String getData(){
  11. return this.data;
  12. }
  13. public Node getNext(){
  14. return this.next;
  15. }
  16. }
  17. public class TestLink{
  18. public static void main(String[] arg){
  19. //定义head
  20. Node head = new Node("我是head");
  21. Node node1 = new Node("我是node1");
  22. Node node2 = new Node("我是node2");
  23. Node node3 = new Node("我是node3");
  24. head.setNext(node1);//设置head的下一个节点为node1
  25. node1.setNext(node2);//设置node1的下一个节点为node2
  26. node2.setNext(node3);//设置node2的下一个节点为node3
  27. node3.setNext(head);//设置node3的下一个节点为head 此步完成了循环链表
  28. }
  29. }

双向链表

双向链表也叫双链表。双向链表中不仅有指向后一个节点的指针,还有指向前一个节点的指针。这样便于快速访问前一个节点和后一个节点 如下图:
双向链表
实例代码

  1. class Node{
  2. public String data;//链表的数据先采用简单的String
  3. public Node pre;//上一个节点
  4. public Node next;//下一个节点
  5. public Node(String data){
  6. this.data = data;
  7. }
  8. public void setNext(Node node){
  9. this.next = node;
  10. }
  11. public void setPre(Node node){
  12. this.pre = node;
  13. }
  14. public String getData(){
  15. return this.data;
  16. }
  17. public Node getNext(){
  18. return this.next;
  19. }
  20. public Node getPre(){
  21. return this.pre;
  22. }
  23. }
  24. public class TestLink{
  25. public static void main(String[] arg){
  26. //定义head
  27. Node head = new Node("我是head");
  28. Node node1 = new Node("我是node1");
  29. Node node2 = new Node("我是node2");
  30. Node node3 = new Node("我是node3");
  31. head.setNext(node1);//设置head的下一个节点为node1
  32. node1.setPre(head);//设置node1的上一个节点为head
  33. node1.setNext(node2);//设置node1的下一个节点为node2
  34. node2.setPre(node1);//设置node2的上一个节点为node1
  35. node2.setNext(node3);//设置node1的下一个节点为node2
  36. node3.setPre(node2);//设置node3即最后一个节点的前一个节点为node2
  37. node3.setNext(head);//设置node3即最后一个节点的下一个节点为head
  38. head.setPre(node3);//设置head的上一个节点为node3
  39. }
  40. }