欢迎关注我的B站账号:卍卍子非鱼卍卍
链表
单链表
链表节点LinkedNode
// 链表节点LinkedNode
class LinkedNode<T> {
public T val;
public LinkedNode<T> next;
public LinkedNode() {
this(null);
}
public LinkedNode(T val) {
this.val = val;
this.next = null;
}
}
链表MyLinkedList
LinkedNode<T> getHead()
获取表头
boolean isEmpty()
判断链表是否为空
void add(T val)
向链表末尾添加元素
void add(int index, T val)
向链表指定位置添加元素
T remove()
移除链表末尾元素
T remove(int index)
移除链表指定位置元素
T get(int index)
获取链表指定位置元素
int size()
获取链表长度
String toString()
输出链表
class MyLinkedList<T> {
public LinkedNode<T> head;
public MyLinkedList() {
this.head = new LinkedNode<T>();
head.next = null;
}
// 获取表头
public LinkedNode<T> getHead() {
if (this.isEmpty()) {
throw new NullPointerException();
}
return head.next;
}
// 判断链表是否为空
public boolean isEmpty() {
return head.next == null;
}
// 向链表末尾添加元素
public void add(T val) {
this.add(this.size(), val);
}
// 向链表指定位置添加元素
public void add(int index, T val) {
if (index < 0 || index > this.size()) {
throw new NullPointerException();
}
LinkedNode<T> p = head;
int n = 0;
while (n < index) {
p = p.next;
n++;
}
LinkedNode<T> node = new LinkedNode<T>(val);
node.next = p.next;
p.next = node;
}
// 移除链表末尾元素
public T remove() {
return this.remove(this.size() - 1);
}
// 移除链表指定位置元素
public T remove(int index) {
if (index < 0 || index >= this.size()) {
throw new NullPointerException();
}
LinkedNode<T> p = head;
int n = 0;
while (n < index) {
p = p.next;
n++;
}
T val = p.next.val;
p.next = p.next.next;
return val;
}
// 获取链表指定位置元素
public T get(int index) {
if (index < 0 || index >= this.size()) {
throw new NullPointerException();
}
LinkedNode<T> p = head;
int n = 0;
while (n < index) {
p = p.next;
n++;
}
return p.next.val;
}
// 获取链表长度
public int size() {
LinkedNode<T> p = head;
int n = 0;
while (p.next != null) {
p = p.next;
n++;
}
return n;
}
// 输出链表
public String toString() {
LinkedNode<T> p = head;
String str = "";
if (p.next == null) {
return "";
}
while (p.next.next != null) {
p = p.next;
str += p.val + "->";
}
str += p.next.val;
return str;
}
}
双链表
双链表节点DlinkedNode
class DLinkedNode<T> {
public T val;
public DLinkedNode<T> next;
public DLinkedNode<T> pre;
public DLinkedNode() {
this(null);
}
public DLinkedNode(T val) {
this.val = val;
this.next = null;
this.pre = null;
}
}
双链表MyDLinkedList
DLinkedNode<T> getHead()
获取表头
boolean isEmpty()
判断链表是否为空
void add(T val)
向链表末尾添加元素
void add(int index, T val)
向链表指定位置添加元素
T remove()
移除链表末尾元素
T remove(int index)
移除链表指定位置元素
T get(int index)
获取链表指定位置元素
int size()
获取链表长度
String toString()
输出链表
class MyDLinkedList<T> {
public DLinkedNode<T> head;
public MyDLinkedList() {
this.head = new DLinkedNode<T>();
}
// 获取表头
public DLinkedNode<T> getHead() {
return head.next;
}
// 判断链表是否为空
public boolean isEmpty() {
return head.next == null;
}
// 向链表末尾添加元素
public void add(T val) {
this.add(this.size(), val);
}
// 向链表指定位置添加元素
public void add(int index, T val) {
if (index < 0 || index > this.size()) {
throw new NullPointerException();
}
DLinkedNode<T> p = head;
int n = 0;
while (n < index) {
p = p.next;
n++;
}
DLinkedNode<T> node = new DLinkedNode<T>(val);
node.next = p.next;
if (p.next != null) {
p.next.pre = node;
}
p.next = node;
node.pre = p;
}
// 移除链表末尾元素
public T remove() {
return this.remove(this.size() - 1);
}
// 移除链表指定位置元素
public T remove(int index) {
if (index < 0 || index >= this.size()) {
throw new NullPointerException();
}
DLinkedNode<T> p = head;
int n = 0;
while (n < index) {
p = p.next;
n++;
}
DLinkedNode<T> node = p.next;
p.next = p.next.next;
if (p.next != null) {
p.next.pre = p;
}
return node.val;
}
// 获取链表指定位置元素
public T get(int index) {
if (index < 0 || index >= this.size()) {
throw new NullPointerException();
}
DLinkedNode<T> p = head;
int n = 0;
while (n < index) {
p = p.next;
n++;
}
return p.next.val;
}
// 获取链表长度
public int size() {
DLinkedNode<T> p = head;
int n = 0;
while (p.next != null) {
p = p.next;
n++;
}
return n;
}
// 输出链表
public String toString() {
DLinkedNode<T> p = head;
String str = "";
if (p.next == null) {
return "";
}
while (p.next.next != null) {
p = p.next;
str += p.val + "<->";
}
str += p.next.val;
return str;
}
}
链表排序
输入待排序链表头节点,输出排序后链表头节点
算法思路
现有如下链表:
将其进行升序排序:
思路如下:
1.定义虚拟头节点preHead
,将其next
指针指向真正的头节点head
2.定义指针p
指向preHead
,指针q
指向链表中的第二个节点,并切断第一,二个节点之间的连接
3.当q != null
时,进行循环:
4.用临时指针temp
指向q.next
,指针p
指向preHead
, 当p指针指向的下一个节点的值小于等于q指针指向节点的值,即p.next.val <= q.val
时,p指针向右移动。直到下一个节点的值大于q指针指向节点的值或到达表尾。
5.此时说明q
节点应插入p
节点之后
6.令q = temp
,返回第3步
7.循环结束,返回preHead.next
代码
/**
* 链表排序
*
* @param head 待排序链表头节点
* @return 排序后链表头节点
*/
public LinkedNode<Integer> sort(LinkedNode<Integer> head) {
if (head == null) {
return null;
}
LinkedNode<Integer> preHead = new LinkedNode<Integer>(-1);
preHead.next = head;
LinkedNode<Integer> p = preHead, q = head.next;
head.next = null;
while (q != null) {
LinkedNode<Integer> temp = q.next;
p = preHead;
while (p.next != null && p.next.val <= q.val) {
p = p.next;
}
q.next = p.next;
p.next = q;
q = temp;
}
return preHead.next;
}
合并有序链表
输入两个有序链表头节点,输出合并后的链表头节点
算法思路
两个有序链表:
将其合并为一个有序链表:
思路如下:
1.定义指针p1
,p2
分别指向两个链表的表头,定义虚拟头节点preHead
,定义遍历指针index
指向preHead
2.当p1
和p2
至少有一个不为null
时,进行循环:
3.首先判断其中一个是否为null
,若其中一个为null
,index
节点的next
指针就指向另一个不为null
的节点,并结束循环
4.若p1
,p2
均不为null
,比较两节点的值,令index
节点的next
指针指向小的那一方,并且让对应的指针(p1
或p2
)向右移动,最后,让index
指针也向右移动
5.返回第2步
6.循环结束,返回preHead.next
代码
/**
* 合并有序链表
*
* @param LA 有序链表头节点
* @param LB 有序链表头节点
* @return 合并后的链表头节点
*/
public LinkedNode<Integer> UnionList(LinkedNode<Integer> LA, LinkedNode<Integer> LB) {
LinkedNode<Integer> p1 = LA, p2 = LB;
LinkedNode<Integer> preHead = new LinkedNode<Integer>(-1);
LinkedNode<Integer> index = preHead;
while (p1 != null || p2 != null) {
if (p1 == null) {
index.next = p2;
break;
} else if (p2 == null) {
index.next = p1;
break;
} else {
if (p1.val < p2.val) {
index.next = p1;
p1 = p1.next;
} else {
index.next = p2;
p2 = p2.next;
}
}
index = index.next;
}
return preHead.next;
}