目录
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,Boolean
list.addFirst(2);//头插2
System.out.println(list);
list.addLast(3);//尾插3
System.out.println(list);
list.add(1,4);//1坐标插入4
System.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坐标元素改为3
System.out.println(list);
System.out.println(list.contains(3));//是否含5
System.out.println(list.contains(6));//是否含6
System.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;
}
}