单链表
插入与删除
反转
代码实现
package com.linkedlist;
import java.util.Scanner;
import java.util.Stack;
/**
* @program: DataStructures
* @description: 单链表
* @author: XuDeming
* @date: 2019-12-28 00:16:40
**/
public class SingleLinkedListDemo {
public static void main(String[] args) {
System.out.println("***单链表测试***");
Scanner scanner = new Scanner(System.in);
boolean flag = true;
// 创建单链表
SingleLindedList list = new SingleLindedList();
// 创建头节点
Node head = new Node(null);
while (flag) {
System.out.println("***单链表操作菜单***");
System.out.println("0: 退出程序");
System.out.println("1: 打印链表");
System.out.println("2: 显示链表长度");
System.out.println("3: 添加数据");
System.out.println("4: 插入数据");
System.out.println("5: 查看数据(by位置)");
System.out.println("6: 查看数据(by值)");
System.out.println("7: 删除数据(by位置)");
System.out.println("8: 删除数据(by值)");
System.out.println("9: 修改数据");
System.out.println("10: 清空链表");
System.out.println("11: 反转链表");
System.out.println("12:逆序打印");
System.out.println("请输入操作数:");
int i = scanner.nextInt();
int index;
String value;
switch (i) {
case 0:
flag = false;
break;
case 1:
list.showList(head);
break;
case 2:
System.out.println("链表长度:" + list.length(head));
break;
case 3:
System.out.println("请输入添加的数据:");
value = scanner.next();
list.addNode(head, value);
break;
case 4:
System.out.println("请输入插入的位置:");
index = scanner.nextInt();
System.out.println("请输入插入的数据:");
value = scanner.next();
list.addNodeByIndex(head, index, value);
break;
case 5:
System.out.println("请输入查看的位置:");
index = scanner.nextInt();
Node node = list.findValueByIndex(head, index);
if (node != null) {
System.out.println("该位置对应的值是" + node.value);
}
break;
case 6:
System.out.println("请输入查看的值:");
value = scanner.next();
index = list.findIndexByValue(head, value);
if (index != -1 && index != 0) {
System.out.println("该值第一次出现的位置是:" + index);
}
break;
case 7:
System.out.println("请输入删除的位置:");
index = scanner.nextInt();
list.deleteNodeByIndex(head, index);
break;
case 8:
System.out.println("请输入删除的值:");
value = scanner.next();
list.deleteNodeByValue(head, value);
break;
case 9:
System.out.println("请输入更新的位置:");
index = scanner.nextInt();
System.out.println("请输入更新的值:");
value = scanner.next();
list.updateNodeByIndex(head, index, value);
break;
case 10:
list.clean(head);
break;
case 11:
list.reversetList(head);
break;
case 12:
list.resersetPrint(head);
break;
default:
break;
}
}
}
}
// 节点
class Node {
public String value;// 值
public Node next;// 指向下一个节点
public Node(String value) {
this.value = value;
}
}
// 单链表(带头节点)
class SingleLindedList {
// 添加节点(最后一个节点之后)
public void addNode(Node head, String value) {
Node temp = head;// 创建一个指向头节点的指针
while (temp.next != null) {// 如果有下一个节点
temp = temp.next;// 将指针指向下一个节点
}
// 循环结束 指针已指到最后一个节点
temp.next = new Node(value);
}
// 插入节点(根据index)
public void addNodeByIndex(Node head, int index, String value) {
if (index < 1 || index > length(head) + 1) {
System.out.println("插入位置有误");
return;
}
Node temp = head;// 创建一个指向头节点的指针
// 头指针移动(n-1)个位置
// 寻找插入位置的前一个元素
for (int i = 0; i < index - 1; i++) {
temp = temp.next;
}
Node node = new Node(value);
node.next = temp.next;
temp.next = node;
}
// 查找节点(根据index)
public Node findValueByIndex(Node head, int index) {
if (isNotIndex(head, index)) {
System.out.println("查找位置有误");
return null;
}
Node temp = head;// 创建一个指向头节点的指针
for (int i = 0; i < index; i++) {
temp = temp.next;
}
return temp;
}
// 判断索引位置
private boolean isNotIndex(Node head, int index) {
return index < 1 || index > length(head);
}
// 查找节点(查找第一次出现value的位置)
public int findIndexByValue(Node head, String value) {
if (value == null) {
throw new RuntimeException();
}
if (length(head) == 0) {
System.out.println("空链表");
return 0;
}
int index = 1;
Node temp = head.next;
for (int i = 0; i < length(head); i++) {
if (value.equals(temp.value))
break;
temp = temp.next;
index++;
}
if (index > length(head)) {
System.out.println("查无此值");
return -1;
}
return index;
}
// 删除节点(根据index)
public void deleteNodeByIndex(Node head, int index) {
if (isNotIndex(head, index)) {
System.out.println("删除位置有误");
return;
}
Node temp = head;// 创建一个指向头节点的指针
for (int i = 0; i < index - 1; i++) {
temp = temp.next;
}
temp.next = temp.next.next;
}
// 删除节点(删除第一次出现value的节点)
public void deleteNodeByValue(Node head, String value) {
if (findIndexByValue(head, value) > 0) {
int index = findIndexByValue(head, value);
deleteNodeByIndex(head, index);
}
}
// 修改节点(根据index)
public void updateNodeByIndex(Node head, int index, String newValue) {
if (findValueByIndex(head, index) == null) {
return;
}
Node node = findValueByIndex(head, index);
node.value = newValue;
}
// 遍历链表
public void showList(Node head) {
if (length(head) == 0) {
System.out.println("链表为空");
return;
}
Node node = head.next;
while (node != null) {
System.out.print(node.value + "\t");
node = node.next;
}
System.out.println();
}
// 有效节点个数
public int length(Node head) {
Node node = head;
int size = 0;
while (node.next != null) {
size++;
node = node.next;
}
return size;
}
// 清空链表
public void clean(Node head) {
if (head == null) return;
head.next = null;
}
// 反转链表
public void reversetList(Node head) {
if (length(head) == 0) {
System.out.println("空链表");
return;
}
// 新建一个反转节点(作为反转链表头节点)
Node reverNode = new Node(null);
Node node = head.next;
while (node != null) {// 遍历每一个节点,依次插入反转链表的第一个位置
addNodeByIndex(reverNode, 1, node.value);
node = node.next;
}
head.next = reverNode.next;
}
// 逆序打印链表
// 方法一:反转链表 打印 但会破坏表结构
// 方法二:利用用栈
public void resersetPrint(Node head) {
if (head == null) return;
if (head.next == null) {
System.out.println("空链表");
return;
}
Node node = head.next;
Stack<Node> stack = new Stack<>();
while (node != null) {
stack.push(node);
node = node.next;
}
while (stack.size() > 0) {
System.out.print(stack.pop().value + "\t");
}
System.out.println();
}
}
还缺一个合并有序链表没实现