1. 链表
1.1 链表的概念及结构
链表是一种物理存储结构上非连续存储结构,数据元素的逻辑顺序是通过链表中的引用链接次序实现的 。
实际中链表的结构非常多样,以下情况组合起来就有8种链表结构:
单向、双向
带头、不带头
循环、非循环
无头单向非循环链表:结构简单,一般不会单独用来存数据。实际中更多是作为其他数据结构的子结构,如哈 希桶、图的邻接表等等。另外这种结构在笔试面试中出现很多。
无头双向链表:在Java的集合框架库中LinkedList底层实现就是无头双向循环链表。
1.2 无头单项非循环链表实现
代码如下
class Node {
public int data;
public Node next;
public Node() {
}
public Node(int data) {
this.data = data;
}
}
public class LinkedList {
public Node head;
//头插法
public void addFirst(int data){
Node node = new Node(data);
if(this.head == null) {
this.head = node;
return;
}
node.next =this.head;
this.head = node;
}
//尾插法
public void addLast(int data) {
Node node = new Node(data);
if(this.head == null) {
this.head = node;
return;
}
Node cur = this.head;
while (cur.next != null) {
cur = cur.next;
}
cur.next = node;
}
//任意位置插入数据
public void addIndex(int index, int elem) {
Node node = new Node(elem);
int len = size();
if (index < 0 || index > len) {
return;
}
//1.头插
if (index == 0) {
addFirst(elem);
return;
}
Node cur = this.head;
for (int i = 0; i < index - 1; i++) {
cur = cur.next;
}
Node prev = cur;
//先连右边后连左边
node.next = prev.next;
prev.next = node;
}
//删除关键字key
public void remove(int key) {
//头节点
if (head == null) {
return;
}
if (head.data == key) {
this.head = this.head.next;
return;
}
Node prev = searchPrev(key);
if(prev != null) {
prev.next = prev.next.next;
}
}
//删除所有的key
public void removeAllkey(int key) {
if (head == null) {
return;
}
Node prev = this.head;
Node cur = this.head.next;
while (cur != null) {
if (cur.data == key) {
prev.next = cur.next;
cur = prev.next;
}else {
prev = cur;
cur = cur.next;
}
}
if (head.data == key) {
head = head.next;
}
}
//查找关键字的前驱
private Node searchPrev(int toRemove) {
Node prev = this.head;
while (prev.next != null) {
if (prev.next.data == toRemove) {
return prev;
}
prev = prev.next;
}
return null;
}
//打印链表
public void display() {
System.out.print("[");
for (Node node = this.head; node != null;
node = node.next) {
System.out.print(node.data);
if (node.next != null) {
System.out.print(", ");
}
}
System.out.println("]");
}
//链表长度
public int size() {
int size = 0;
for(Node cur = this.head;cur != null;
cur = cur.next) {
size++;
}
return size;
}
//清空链表
public void clear() {
this.head = null;
}
}