单链表:
package com.example.algorithm;
import java.util.LinkedList;
import java.util.Stack;
/* [data|next] [data|next] [data|null]
head --> node1 --> node2 --> node3
1.链表是以节点的方式链式存储的
2.每个节点包含data域,next域
3.链表的各个节点不是连续存储的
4.链表分为带头节点的链表和没有头节点的链表
*/
public class SingleLinkedList {
public static void main(String[] args) {
LinkedListNode node1 = new LinkedListNode(1);
LinkedListNode node2 = new LinkedListNode(3);
LinkedListNode node3 = new LinkedListNode(5);
LinkedListNode node4 = new LinkedListNode(7);
LinkedListNode node5 = new LinkedListNode(2);
LinkedListNode node6 = new LinkedListNode(6);
LinkedListNode node7 = new LinkedListNode(8);
LinkedList linkedList = new LinkedList();
LinkedList linkedList2 = new LinkedList();
linkedList.addNodeOrder(node1);
linkedList.addNodeOrder(node2);
linkedList.addNodeOrder(node3);
linkedList.addNodeOrder(node4);
linkedList2.addNodeOrder(node5);
linkedList2.addNodeOrder(node6);
linkedList2.addNodeOrder(node7);
// System.out.println("反转前~~~");
// linkedList.showLinkedList();
linkedList.updateNode(node1,12);
// linkedList.deleteNode(node4);
// reverseLinkedListNode(linkedList.head);
// System.out.println("反转后~~~");
linkedList.showLinkedList();
// showReverseLinkedList(linkedList.head);
System.out.println("合并前:\n head1:");
linkedList.showLinkedList();
System.out.println("head2:");
linkedList2.showLinkedList();
System.out.println("合并后:");
System.out.println(mergerLinkedListNode(linkedList.head, linkedList2.head));
}
static class LinkedListNode {
public int data;
public LinkedListNode next;
public LinkedListNode(int data) {
this.data = data;
}
@Override
public String toString() {
return "LinkedListNode{" +
"data=" + data +
", next=" + next +
'}';
}
}
static class LinkedList {
// 先初始化一个头结点,不要动
private LinkedListNode head = new LinkedListNode(0);
// 添加节点到单向链表
public void addNodeAtLast(LinkedListNode node) {
LinkedListNode temp = head; // 新建一个节点指向头结点,通过这个节点遍历找尾结点
while (true) {
if (temp.next == null) {
break;
}
// 如果没有找到,将temp后移
temp = temp.next;
}
// 退出while循环时,此时temp为尾结点
temp.next = node;
}
public void addNodeOrder(LinkedListNode node) {
LinkedListNode temp = head; // 新建一个节点指向头结点,通过这个节点遍历找尾结点
while (true) {
if (temp.next == null) {
break;
}
if (temp.next.data > node.data) {
break;
}
temp = temp.next;
}
node.next = temp.next;
temp.next = node;
}
public void showLinkedList() {
if (head.next == null) {
System.out.println("链表为空!");
return;
}
// 链表头结点不能动,同样声明一个辅助节点
LinkedListNode temp = head.next;
while (true) {
if (temp == null) {
break;
}
System.out.println(temp.data);
temp = temp.next;
}
}
public void updateNode(LinkedListNode node, int data) {
if (head.next == null) {
System.out.println("链表为空!");
return;
}
node.data = data;
LinkedListNode temp = head;
LinkedListNode nodePre = head;
// 如果修改完毕后,需要保证链表排序
while (true) {
if (nodePre.next == node) {
break;
}
nodePre = nodePre.next;
}
while (true) {
if (temp.next == null) {
break;
}
if (temp.next.data > node.data) {
break;
}
temp = temp.next;
}
// 判断node是否更换位置
if (temp.next != node.next) {
nodePre.next = node.next;
node.next = temp.next;
temp.next = node;
}
}
public void deleteNode(LinkedListNode node) {
if (head.next == null) {
System.out.println("链表为空!");
return;
}
LinkedListNode temp = head;
boolean flag = false;
while (true) {
if (temp.next == node) {
flag = true;
break;
}
if (temp.next == null) {
break;
}
temp = temp.next;
}
if (!flag) {
throw new RuntimeException("未找到节点" + node);
}
temp.next = temp.next.next;
}
}
/**
* 新浪微博面试题
*/
// 获取单链表的节点的个数(如果是头结点,不统计头结点)
public static int getSingleLinkedListLength(LinkedListNode head) {
if (head.next == null) {
return 0;
}
int length = 0;
LinkedListNode temp = head.next;
while (temp != null) {
length++;
temp = temp.next;
}
return length;
}
// 查找单链表中的倒数第k个节点,size已经计算好
public static LinkedListNode findLastNodeSizeExist(LinkedListNode head, int index) {
if (head.next == null) {
return null;
}
int size = getSingleLinkedListLength(head);
if (index <= 0 || index > size) {
throw new RuntimeException("indexIllegalException");
}
LinkedListNode temp = head.next;
for (int i = 0; i < size - index; i++) {
temp = temp.next;
}
return temp;
}
// 查找单链表中的倒数第k个节点,size未计算好
public static LinkedListNode findLastNode(LinkedListNode head, int index) {
if (head.next == null) {
return null;
}
LinkedListNode temp = head.next;
// 获取单链表长度
int length = 0;
while (temp != null) {
length++;
temp = temp.next;
}
temp = head.next;
for (int i = 0; i < length - index; i++) {
temp = temp.next;
}
return temp;
}
/**
* 腾讯面试题
*/
// 反转链表
public static void reverseLinkedListNode(LinkedListNode head) {
// 当单链表为空时,或者只有一个节点时,不需要反转
if (head.next == null || head.next.next == null) {
return;
}
LinkedListNode temp = head.next;
LinkedListNode next;
LinkedListNode reverseHead = new LinkedListNode(0);
while (temp != null){
next = temp.next;
temp.next = reverseHead.next;
reverseHead.next = temp;
temp = next;
}
head.next = reverseHead.next;
}
/**
* 百度面试题
*/
// 从尾到头打印单链表
public static void showReverseLinkedList(LinkedListNode head){
if (head.next == null){
return;
}
// 创建一个栈,将节点加进栈中
Stack<LinkedListNode> stack = new Stack<>();
LinkedListNode temp = head.next;
while (temp != null){
stack.push(temp);
temp = temp.next;
}
while (stack.size() > 0){
System.out.println(stack.pop());
}
}
// 将两个有序数组合并成一个数组
public static LinkedListNode mergerLinkedListNode(LinkedListNode head1,LinkedListNode head2){
LinkedListNode mergerNode = new LinkedListNode(0); // 新建第三个单链表,用来存放最终数据,不能动,需要借助辅助节点
LinkedListNode temp = mergerNode;
LinkedListNode node1 = head1.next;
LinkedListNode node2 = head2.next;
while (node1 != null && node2 != null){
if (node1.data < node2.data){
temp.next = node1;
temp = temp.next;
node1 = node1.next;
}else {
temp.next = node2;
temp = temp.next;
node2 = node2.next;
}
}
if (node1 != null){
temp.next = node1;
}
if (node2 != null){
temp.next = node2;
}
return mergerNode.next;
}
}
双链表:
package com.example.algorithm;
import java.util.NoSuchElementException;
public class DoubleLinkedList {
public static void main(String[] args) {
DoubleLinkedListNode node1 = new DoubleLinkedListNode(1);
DoubleLinkedListNode node2 = new DoubleLinkedListNode(3);
DoubleLinkedListNode node3 = new DoubleLinkedListNode(5);
DoubleLinkedListNodeList linkedList = new DoubleLinkedListNodeList();
linkedList.addDoubleLinkedListNodeOrder(node1);
linkedList.addDoubleLinkedListNodeOrder(node3);
linkedList.addDoubleLinkedListNodeOrder(node2);
// System.out.println("修改前:");
// System.out.println("删除前:");
linkedList.showDoubleLinkedList();
// linkedList.updateDoubleLinkedListNode(node1, 4);
// System.out.println("修改后:");
// linkedList.showDoubleLinkedList();
//
// linkedList.deleteDoubleLinkedListNode(node1);
// linkedList.deleteDoubleLinkedListNode(node3);
// System.out.println("删除后:");
// linkedList.showDoubleLinkedList();
}
static class DoubleLinkedListNode {
public int data;
public DoubleLinkedListNode pre;
public DoubleLinkedListNode next;
public DoubleLinkedListNode(int data) {
this.data = data;
}
@Override
public String toString() {
return "DoubleLinkedListNode{" +
"pre=" + pre +
", data=" + data +
", next=" + next +
'}';
}
}
static class DoubleLinkedListNodeList {
private DoubleLinkedListNode head = new DoubleLinkedListNode(0);
public DoubleLinkedListNode getHead() {
return head;
}
public void addDoubleLinkedListNode(DoubleLinkedListNode node) {
DoubleLinkedListNode temp = head;
while (true) {
if (temp.next == null) {
break;
}
temp = temp.next;
}
temp.next = node;
node.pre = temp;
}
public void addDoubleLinkedListNodeOrder(DoubleLinkedListNode node) {
DoubleLinkedListNode temp = head;
while (true) {
if (temp.next == null) {
break;
}
if (temp.next.data > node.data) {
break;
}
temp = temp.next;
}
if (temp.next != null) {
temp.next.pre = node;
node.next = temp.next;
}
node.pre = temp;
temp.next = node;
}
public void showDoubleLinkedList() {
if (head.next == null) {
System.out.println("链表为空!");
return;
}
// 链表头结点不能动,同样声明一个辅助节点
DoubleLinkedListNode temp = head.next;
while (true) {
if (temp == null) {
break;
}
System.out.println(temp.data);
temp = temp.next;
}
}
public void updateDoubleLinkedListNode(DoubleLinkedListNode node, int data) {
if (head.next == null) {
System.out.println("链表为空!");
return;
}
node.data = data;
DoubleLinkedListNode temp = head;
while (true) {
if (temp.next == null) {
break;
}
if (temp.next.data > node.data) {
break;
}
temp = temp.next;
}
if (temp.next == null && temp.next != node.next) {
// 1.节点更新了位置,移动到最后一位
node.pre.next = node.next;
if (node.next!=null){
node.next.pre = node.pre;
}
node.pre = temp;
node.next = null;
temp.next = node;
}else if (temp.next != node.next && temp.next != null) {
// 2.节点更新了位置,没有移动到最后一位
node.pre.next = node.next;
if (node.next != null){
node.next.pre = node.pre;
}
temp.next.pre = node;
node.next = temp.next;
node.pre = temp;
temp.next = node;
}
// 3.节点没有更新位置,什么也没发生
}
public void deleteDoubleLinkedListNode(DoubleLinkedListNode node) {
DoubleLinkedListNode temp = head;
if (temp.next == null) {
System.out.println("当前链表为空!");
return;
}
// 如果node为头结点或者空节点
if (node == null) {
System.out.println("当前节点不需要删除");
return;
}
// while (true){
// if (temp.next == null){
// break;
// }
// if (temp.next)
// }
node.pre.next = node.next;
if (node.next != null) {
node.next.pre = node.pre;
}
}
}
}