什么是链表?
链表(LinkedList)是一种常见的数据结构,用于存储和组织数据。它由一系列节点(Node)组成,每个节点包含数据元素和一个指向下一个节点的引用(指针或链接)。
链表中的节点在内存中可以分散存储,每个节点通过指针连接到下一个节点,从而形成一个链式结构。
相比于数组等连续存储结构,链表的插入、删除操作一般情况下更加高效,因为它不需要进行元素的移动。
链表的分类?
单向链表(Singly Linked List):每个节点只有一个指向下一个节点的指针。最后一个节点指向空(null),表示链表的结束。
双向链表(Doubly Linked List):每个节点有两个指针,一个指向前一个节点,一个指向后一个节点。双向链表可以从头到尾或从尾到头遍历。
单链表节点的构造方法:
public class LinkedNode() {
int data;
LinkedNode next;
public LinkedNode(int data) {
this.data = data;
this.next = null;
}
}
创建简单链表:
LinkedNode head = new LinkedNode(1);
LinkedNode sec = new LinkedNode(2);
LinkedNode thr = new LinkedNode(3);
head.next = sec;
sec.next = thr;
遍历链表:
//使用循环遍历
LinkedNode current = head; //指向头节点
while(current.next != null) {
System.out.println(current.data());
current = current.next;
}
//使用递归
public void trav(LinkedNode node) {
if(node == null) {
return; //终止
}
System.out.println(node.data());
trav(node.next);
}
链表插入:
public LinkedNode insertNode(Node head, Node newInsert, int position) {
if(head == null) {
return newInsert;
}
int size = getLength(head);
if(position <= 0 || position > size + 1) {
System.out.println("越界");
return head;
}
//头插
if(position == 1) {
newInsert.next = head;
head = newInsert;
return head;
}
LinkedNode flag = new LinkedNode();
int count = 1;
while(count < position) {
count++;
flag = flag.next;
}
newInsert.next = flag.next;
flag.next = newInsert;
return head;
}
链表删除
public LinkedNode deleteNode(LinkedNode head, int position) {
if (head == null) {
return head;
}
int size = getLength(head);
if(position <= 0 || position > size - 1) {
System.out.println("越界");
return head;
}
if(postion == 1) {
return new LinkedNode();
}
int count = 1;
while(count < position - 1) {
head= head.next;
count++;
}
head.next = head.next.next;
return head;
}
双向链表节点的构造方法:
public class DLinkedNode() {
int data;
DlinkedNode prev;
DlinkedNode next;
public DlinkedNode(int data) {
this.data = data;
this.prev = null;
this.next = null;
}
}
双向链表的遍历:
class DLinkedNode {
int data;
Node prev;
Node next;
public DLinkedNode(int data) {
this.data = data;
this.prev = null;
this.next = null;
}
}
class DLinkedList() {
Node head;
Node tail;
//从头到尾遍历
public void travList() {
Node cur = head;
while(cur != null) {
System.out.println(cur.data);
}
cur = cur.next;
}
//从尾到头遍历
public void retravList() {
Node cur = tail;
while(cur != null) {
System.out.println(cur.data);
}
cur = cur.prev;
}
}
双向链表的插入:
public class DLinkedList() {
DLinkedNode head;
DLinkedNode tail;
//头插
public class insertHead(int data) {
DLinkedNode node = new DLinkedNode(data);
node.next = head;
head.prev = node;
head = node;
}
//尾插
public class insertTail(int data) {
DLinkedNode node = new DlinkedNode(data);
node.prev = tail;
tail.net = node;
tail = node;
}
//中间插入
public class insertAft(int data, int position) {
DLinkedNode node = new DLinkedNode(data);
int count = 1;
DLinkedNode cur = head;
while (count < postion) {
cur = cur.next;
count++;
}
node.prev = cur.prev;
cur.prev = node;
node.next = cur;
}
}
双向链表的删除:
public class DLinkedList() {
DLinkedNode first;
DLinkedNode last;
DLinkedNode temp = null;
//删除头节点
public DLinkedNode deleteNodeFirst() {
temp = first;
temp.next.prev = null;
first = temp.next;
return temp;
}
//删除尾节点
public DLinkedNode deleteNodeLast() {
temp = last;
temp.prev.next = null;
last = temp.prev;
return temp;
}
//删除中间节点
public DLinkedNode deleteKey(int key) {
temp = first;
while(temp.next != null) {
if(temp.data == key) {
temp.prev.next = temp.next;
temp.next.prev = temp.prev;
return temp;
}
}
}
}