目录
1.概念
2.链表
2.1 单链表概念及结构
2.2双链表的概念及结构
2.3 循环链表
3.链表的具体使用
4.自己实现链表及方法:
双链表:
单链表:
1.概念
链式存储是常用的动态存储方式,相对于顺序表,可以更好的任意插入与删除,而采用链式存储的结构叫做链表。
链表是一种物理存储结构上非连续存储结构,数据元素的逻辑顺序是通过链表中的引用链接次序实现的 。
从链接方式的角度:链表分为单链表、双链表及循环链表;
从实现方式的角度:链表分为动态链表和静态链表;
2.链表
2.1 单链表概念及结构
概念:
单链表是通过一个一个结点进行连接,而链表并不像顺序表一样存储的是一组地址连续的存储单元,而是非连续的。因此,链表中的结点不仅需要存储自己的数据元素值(数据域),还需要存储下一个结点的地址(指针域)。
结构:
单链表的每个结点的地址都存储在其前驱结点的指针域中,因此第一个结点无前驱,这个时候我们可以设置一个头指针Head指向第一个结点。而最后一个结点后面没有结点,所以最后一个结点指针域为空(Null)。
单链表结构:
2.2双链表的概念及结构
概念:
每个结点相对与单链表多了一个指针域,其它与单链表基本相同。
结构:
2.3 循环链表
概念:
循环链表是建立在单链表和双链表的基础上,将头尾相连,形成一个环,这就是循环链表,可分为:循环单链表、循环双链表。
3.链表的具体使用
方法 | 解释 |
add(E e) | 尾插 e |
add(int i, E e) | 把e插在i位置 |
addAll(Collection<? extends E> c) | 尾插c |
addFirst(E e) | 头插e |
remove(int i) | 删除i坐标元素 |
remove(int i) | 删除i坐标元素 |
get(int i) | 获得i坐标元素 |
set(int i , E e) | 将i坐标元素换为e |
clear() | 清空 |
contains(object o ) | 判定o是否存在 |
indexOf(object o) | 返回第一个o所在位置的下标 |
lastIndexOf(object o) | 返回最后一个o下标 |
subList(int f, int t) | 截取f坐标到t坐标list |
代码实现:
public class Test1 {public static void main(String[] args) {System.out.println(list.add(1));//尾插1,Booleanlist.addFirst(2);//头插2System.out.println(list);list.addLast(3);//尾插3System.out.println(list);list.add(1,4);//1坐标插入4System.out.println(list);list.remove(2);//删除2坐标元素System.out.println(list);System.out.println(list.get(2));//获得2坐标元素System.out.println(list);list.set(1,3);//将1坐标元素改为3System.out.println(list);System.out.println(list.contains(3));//是否含5System.out.println(list.contains(6));//是否含6System.out.println(list.indexOf(3));//第一个3的下标System.out.println(list.lastIndexOf(3));//最后一个3的下标System.out.println(list.subList(0,1));//截取[0,1)的list,前闭后开System.out.println(list.isEmpty());//list中是否有元素list.clear();//清空System.out.println(list.isEmpty());}
}
运行结果:
true
[2, 1]
[2, 1, 3]
[2, 4, 1, 3]
[2, 4, 3]
3
[2, 4, 3]
[2, 3, 3]
true
false
1
2
[2]
false
true
4.自己实现链表及方法:
注意:
上面这些方法的实现,我们可以直接用,但是我们也可以创建自己的链表,实现自己的方法,让我们更好的理解,提升我们的代码能力。
代码的实现我放在了下面,但是最好自己实现一遍。
双链表:
public class MyLinkedList {static class ListNode{public int val;public ListNode prev;public ListNode next;public ListNode(int val) {this.val = val;}}public ListNode head;public ListNode last;//头插法public void addFirst(int data){ListNode listNode = new ListNode(data);if (head == null){head = listNode;last = listNode;}else{head.prev = listNode;listNode.next = head;head = listNode;}}//尾插法public void addLast(int data){ListNode listNode = new ListNode(data);if(last == null){last = listNode;head = listNode;}else{last.next = listNode;listNode.prev = last;last = listNode;}}//任意位置插入,第一个数据节点为0号下标public void addIndex(int index,int data){ListNode listNode = new ListNode(data);if(index < 0 || index > size()){System.out.println("不合法");return;}if(index == 0){addFirst(data);return;}if (index == size()){addLast(data);return;}ListNode cur = head;for (int i = 0; i < index; i++) {cur = cur.next;}listNode.next = cur;cur.prev.next = listNode;listNode.prev = cur.prev;cur.prev = listNode;}//查找是否包含关键字key是否在单链表当中public boolean contains(int key){ListNode cur = head;while (cur != null){if(cur.val == key){return true;}}return false;}//删除第一次出现关键字为key的节点public void remove(int key){ListNode cur = head;while (cur != null){if(cur.val == key){if(cur == head){head = head.next;}else{if (cur.next == null) {cur.prev.next = null;last = cur.prev;}else{cur.prev.next = cur.next;cur.next.prev = cur.prev;}}return;}else{cur = cur.next;}}System.out.println("没有这个节点");}//删除所有值为key的节点public void removeAllKey(int key){ListNode cur = head;while (cur != null){if(cur.val == key){if(cur == head){head = head.next;}else{if (cur.next == null) {cur.prev.next = null;last = cur.prev;}else{cur.prev.next = cur.next;cur.next.prev = cur.prev;}}}cur = cur.next;}}//得到单链表的长度public int size(){int count = 0;ListNode cur = head;while (cur != null){count++;cur = cur.next;}return count;}public void display(){ListNode cur = head;while (cur != null){System.out.print(cur.val + " ");cur = cur.next;}System.out.println();}public void clear(){head = null;}
}
单链表:
public class SingleLinkedList {class ListNode{public int val;public ListNode next;public ListNode(int val) {this.val = val;}}public void createNode(){ListNode listNode1 = new ListNode(12);ListNode listNode2 = new ListNode(23);ListNode listNode3 = new ListNode(34);ListNode listNode4 = new ListNode(45);ListNode listNode5 = new ListNode(45);head = listNode1;listNode1.next = listNode2;listNode2.next = listNode3;listNode3.next = listNode4;listNode4.next = listNode5;}public ListNode head;//打印public void show(){ListNode cur = head;for (int i = 0; i < size(); i++) {System.out.print(cur.val + " ");cur = cur.next;}System.out.println();}//长度public int size(){ListNode cur = head;int count = 0;while(cur != null){cur = cur.next;count++;}return count;}//查找public boolean contains(int key){ListNode cur = head;if(cur == null){return false;}while (cur.val != key){if(cur.next == null){return false;}cur = cur.next;}return true;}//头插public void addFirst(int data){ListNode newNode = new ListNode(data);newNode.next = head;head = newNode;}//尾插public void addLast(int data){ListNode newNode = new ListNode(data);ListNode cur = head;while (cur.next != null){cur = cur.next;}cur.next = newNode;}//随意插public void addIndex(int index,int data){ListNode cur = head;ListNode newNode = new ListNode(data);if(index == 0){addFirst(data);return;}if(index < 0 || index > size() || cur == null){throw new IndexOutOfBounds("数组不合法,越界: " + index);}if(index == size()){addLast(data);return;}for (int i = 1; i < index; i++) {cur = cur.next;}newNode.next = cur.next;cur.next = newNode;}//删除第一次出现关键字为key的节点public void remove(int key){ListNode cur = head;ListNode pver = head;if(cur == null){System.out.println("链表无节点");return;}if(cur.val == key){head = head.next;}while(cur.val != key){if(cur.next == null){System.out.println("无此节点");return;}pver = cur;cur = cur.next;}if(cur.val == key){pver.next = cur.next;return;}}//删除所有值为key的节点public void removeAllKey(int key){if(head == null) {return;}ListNode cur = head.next;ListNode prev = head;while (cur != null) {if(cur.val == key) {prev.next = cur.next;cur = cur.next;}else {prev = cur;cur = cur.next;}}if(head.val == key) {head = head.next;}}//清除所有数据public void clear(){head = null;}
}