数据结构之单向链表与双向链表-简单介绍与练习
1. 单向链表
-
单向链表中,前一个节点保存着下一个节点的内存地址,下一个节点保存着下下个节点的内存地址,… ,最后一个节点后指向null
-
单向链表在数据的搜寻过程中,只能按顺序单向执行下去
-
创建一个单向链表,一般返回的是头部节点,因为利用头部节点可以顺着单向链获得其他所有节点
-
单向链表节点结构(可实现成泛型):
public class Node { public int value; public Node next; public Node(int data) { value = data; } }
2. 双向链表
-
双向链表中,一个节点保存着前后相邻节点的内存地址,头节点和尾节点的前后分别指向null
-
双向链表在数据的搜寻过程中,能任意进行搜寻方向前后的变化
-
双向链表节点结构(可实现成泛型):
public class DoubleNode { public int value; public DoubleNode pre; public DoubleNode next; public DoubleNode(int data) { value = data; } }
3. 单向链表和双向链表最简单的练习
所使用的链表结构与前面的展示的单双链表节点结构相同
1. 单链表和双链表如何反转
-
代码实现:
public static Node reverseLinkList(Node head) { Node pre = null; // 保存前一节点的值 Node next = null; // 保存后一节点的值 while(head != null) { next = head.next; head.next = pre; pre = head; head = next; } } public static DoubleNode reverseDoubleList(DoubleNode head) { DoubleNode pre = null; // 保存前一节点的值 DoubleNode next = null; // 保存后一节点的值 while(head != null) { next = head.next; head.next = pre; head.pre = next; pre = head; head = next; } }
2. 把单链表或双链表中的指定值都删除
-
代码实现:
// 单链表的指定值都删除 public static Node removeLinkListValue(Node head, int num) { while(head != null) { // 如果头部直接是要删的值,直接丢弃,没有其他引用会自动释放 if(head.value == num) { // 找到要删的值 head = head.next; }else { break; } } // 头部的值不是要删的,所以后面遇到要删的,丢弃后还要将下一节点与上一节点相连 Node pre = head; // 保存前一节点的值 Node cur = head; // 保存当前节点的值,避免原始头部丢失 while(cur != null) { if(cur.value == num) { // 找到要删的值 pre.next = cur.next; // 断开对其的引用 }else { pre = cur; } cur = cur.next; } return head; } // 双链表的指定值都删除 public static DoubleNode removeDoubleListValue(DoubleNode head, int num) { while(head != null) { // 如果头部是要删的值,head直接跳到后一个节点, // 并将此时的前一个节点指向null,要删的值没有其他引用会自动释放 if(head.value == num) { head = head.next; head.pre = null; }else { break; } } // 此时头部不是要删的值,所以后面遇到要删的,丢弃后还要将下一节点与上一节点相连,要删的值没有其他引用会自动释放 Node pre = head; // 保存前一节点的值 Node cur = head; // 保存当前节点的值,避免原始头部丢失 while(cur != null) { if(cur.value == num) { // 找到要删的值 pre.next = cur.next; // 断开前一项的next对其的引用 if(cur.next != null) { // 如果要删的值的后一项不为空 cur.next.pre = pre; // 断开后一项pre对其的引用 }else { // 如果后一项已经为空,可以直接结束了 break; } }else { pre = cur; } cur = cur.next; } return head; }