编程导航算法通关村 - 第一关 原来链表这么有用
单链表
创建单链表
public class LinkNode {
int val;
LinkNode next;
LinkNode(int data) {
val = data;
}
}
遍历链表
/**
* 遍历链表
* @param head 头指针
* @return 链表长度
*/
public static int getLength(LinkNode head) {
int len = 0;
LinkNode node = head;
while (node != null) {
len++;
node = node.next;
}
return len;
}
链表插入
/**
* 链表插入
* @param head 头指针
* @param position 插入的位置
* @param insertNode 插入的节点
* @return 链表头指针
*/
public static LinkNode addNode(LinkNode head, int position, LinkNode insertNode){
// 判断不可插入的情况
if (position < 1 || position > getLength(head) + 1){
System.out.println("该位置不可插入");
return null;
}
// 链表为空
if (head == null){
insertNode.next = null;
return insertNode;
}
// 头插
if (position == 1){
insertNode.next = head;
head = insertNode;
return head;
}
// 两结点点中插入及尾插
int count = 1;
LinkNode node = head;
while (count < position - 1){
count++;
node = node.next;
}
insertNode.next = node.next;
node.next = insertNode;
return head;
}
链表删除
/**
* 删除结点
* @param head 头结点
* @param position 删除的位置
* @return 删除的结点
*/
public static LinkNode removeNode(LinkNode head, int position){
// 位置错误
if (position < 1 || position > getLength(head)){
return null;
}
// 链表为空
if (head == null){
return null;
}
// 删除头结点
if (position == 1){
return head.next;
}
// 删除中间和尾结点
int count = 1;
LinkNode node = head;
while (count < position - 1){
count++;
node = node.next;
}
node.next = node.next.next;
return head;
}
双向链表
创建双向链表
public class DoubleLinkNode {
public int val;
public DoubleLinkNode prev;
public DoubleLinkNode next;
DoubleLinkNode(int data){
val = data;
}
}
遍历双向链表
/**
* 从头遍历链表
* @param head 头结点
* @return 链表长度
*/
public static int getLengthFromFirst(DoubleLinkNode head){
DoubleLinkNode node = head;
int len = 0;
while (node != null){
len++;
node = node.next;
}
return len;
}
/**
* 从尾遍历链表
* @param last 尾结点
* @return 链表长度
*/
public static int getLengthFromLast(DoubleLinkNode last){
DoubleLinkNode node = last;
int len = 0;
while (node != null){
len++;
node = node.prev;
}
return len;
}
插入元素
/**
* 头插
*
* @param data 插入的数据
*/
public void insertFirst(int data) {
DoubleLinkNode newNode = new DoubleLinkNode(data);
// 链表为空
if (isEmpty()) {
last = first;
}
first.prev = newNode;
newNode.next = first;
first = newNode;
}
/**
* 尾插
*
* @param data 插入的数据
*/
public void insertLast(int data) {
DoubleLinkNode newNode = new DoubleLinkNode(data);
// 链表为空
if (isEmpty()) {
first = newNode;
}
last.next = newNode;
newNode.prev = last;
last = newNode;
}
/**
* 前后有元素插入
*
* @param data 插入的数据
* @param key 插入的key值
*/
public void insertAfter(int key, int data) {
DoubleLinkNode newNode = new DoubleLinkNode(data);
DoubleLinkNode current = first;
while (current != null && current.val != key) {
current = current.next;
}
// 找不到key值,插入的位置是最后一个
if (current == null) {
// 链表为空
if (isEmpty()) {
first = newNode;
last = newNode;
} else {
// 在最后插入
newNode.prev = last;
last.next = newNode;
last = newNode;
}
} else {
// 找到了key值, 但和最后一位一样
if (current == last) {
last = newNode;
} else {
// 在两结点中插入
current.next.prev = newNode;
newNode.next = current.next;
}
current.next = newNode;
newNode.prev = current;
}
}
删除元素
/**
* 删除结点
* @param key 要删除结点的key值
* @return 删除的结点
*/
public DoubleLinkNode deleteFromBetween(int key) {
DoubleLinkNode cur = first;
// 寻找删除结点所在的位置
while (cur != null && cur.val != key) {
cur = cur.next;
}
// 找不到删除的结点
if (cur == null) {
return null;
}
// 删除的是头结点
if (cur == first) {
first = first.next;
first.prev = null;
} else if (cur == last) {
// 删除的是尾结点
last = last.prev;
last.next = null;
} else {
// 删除的结点位于两结点中间
cur.next.prev = cur.prev;
cur.prev.next = cur.next;
}
return cur;
}