一、基本介绍
二、应用实例(单链表)
package linkedlist;
import java.util.Scanner;
import java.util.Stack;
public class SingleLinkedList {
public static void main(String[] args) {
// 以下两个链表主要用于链表合并
LinkedList head1 = new LinkedList(0);
LinkedList head2 = new LinkedList(0);
insert(head1, 1);
insert(head1, 2);
insert(head1, 3);
insert(head2, 4);
insert(head2, 5);
insert(head2, 6);
LinkedList head = new LinkedList(0);
Scanner scanner = new Scanner(System.in);
boolean loop = true;
char op;
int pos;
int val;
while(loop) {
System.out.println("\n链表插入~(i)");
System.out.println("链表删除~(d)");
System.out.println("链表修改~(u)");
System.out.println("链表翻转~(r)");
System.out.println("链表合并~(m)");
System.out.println("链表打印~(p)");
System.out.println("反向打印~(f)");
System.out.println("链表插入指定位置~(c)");
System.out.println("链表删除指定位置~(s)");
System.out.println("链表有效节点个数~(n)");
System.out.println("链表倒数第k个节点~(g)");
System.out.println("退出程序(q)~");
System.out.print("请选择你要执行的操作:");
op = scanner.next().charAt(0);
switch (op) {
case 'i':
System.out.print("请输入要插入的值:");
val = scanner.nextInt();
insert(head, val);
break;
case 'd':
delete(head);
break;
case 'u':
System.out.print("请输入要更新的值:");
val = scanner.nextInt();
System.out.print("请输入元素的位置:");
pos =scanner.nextInt();
update(head, pos, val);
break;
case 'r':
reverse(head);
break;
case 'm':
merge(head1, head2);
break;
case 'p':
System.out.print("单链表元素:");
print(head);
break;
case 'f':
System.out.print("单链表元素(反向遍历):");
reversePrint(head);
break;
case 'c':
System.out.print("请输入要插入的值:");
val = scanner.nextInt();
System.out.print("请输入元素的位置:");
pos =scanner.nextInt();
insertByPosition(head, val, pos);
break;
case 's':
System.out.print("请输入元素的位置:");
pos =scanner.nextInt();
deleteByPosition(head, pos);
break;
case 'n':
count(head);
break;
case 'g':
System.out.print("请输入k的值:");
pos =scanner.nextInt();
get(head, pos);
break;
default:
scanner.close();
loop = false;
break;
}
}
}
public static void insert(LinkedList head, int insertVal) {
LinkedList node = new LinkedList(insertVal);
LinkedList temp = head;
if (head.next == null) {
head.next = node;
System.out.println("结点插入成功~");
} else {
while (temp.next != null) {
temp = temp.next;
}
temp.next = node;
System.out.println("结点插入成功~");
}
}
public static void delete(LinkedList head) {
if (isEmpty(head)) {
throw new RuntimeException("单链表没东西啦~");
}
LinkedList temp = head;
int deleteVal = temp.next.data;
head.next = temp.next.next;
System.out.println("结点删除成功~");
System.out.println("删除结点元素值:" + deleteVal);
}
public static void update(LinkedList head, int pos, int updateVal) {
LinkedList temp = head;
int count = 0;
while (temp.next != null && count < pos) {
count++;
temp = temp.next;
}
if (temp != null) {
temp.data = updateVal;
} else {
throw new RuntimeException("该元素不存在~");
}
}
public static void reverse(LinkedList head) {
if (isEmpty(head)) {
throw new RuntimeException("链表没东西,臣妾很难做到啊~");
}
LinkedList pre = null;
LinkedList curr = head.next; // 从首结点开始翻转
while (curr != null) {
LinkedList next = curr.next;
curr.next = pre;
pre = curr;
curr = next;
}
head.next = pre;
print(head);
}
// 链表合并
private static void merge(LinkedList head1, LinkedList head2) {
if (isEmpty(head1) || isEmpty(head2)) {
throw new RuntimeException("有个么东西啊~");
}
LinkedList p1 = head1.next;
LinkedList p2 = head2.next;
LinkedList newHead = new LinkedList(0); // 新节点的头结点
LinkedList temp = newHead;
while (p1 != null && p2 != null) {
if (p1.data < p2.data) {
temp.next = p1;
p1 = p1.next;
} else {
temp.next = p2;
p2 = p2.next;
}
temp = temp.next;
}
if (p1 != null) {
temp.next = p1;
} else {
temp.next = p2;
}
System.out.print("合并后的链表:");
print(newHead);
}
public static void print(LinkedList head) {
if (isEmpty(head)) {
throw new RuntimeException("单链表没东西~");
}
LinkedList temp = head.next;
while (temp != null) {
System.out.print(temp.data+ " ");
temp = temp.next;
}
System.out.println();
}
private static void reversePrint(LinkedList head) {
if (isEmpty(head)) {
throw new RuntimeException("单链表没东西~");
}
Stack<LinkedList> stack = new Stack<>();
LinkedList temp = head;
while (temp.next != null) {
temp = temp.next;
stack.add(temp);
}
while (stack.size() > 0) {
System.out.print(stack.pop().data+" ");
}
System.out.println();
}
// 指定位置插入
public static void insertByPosition(LinkedList head, int insertVal, int pos) {
LinkedList temp = head;
LinkedList node = new LinkedList(insertVal);
int count = 0;
while (temp.next != null && count < pos - 1) {
count++;
temp = temp.next;
}
node.next = temp.next; // temp指向的是插入位置的前一个位置
temp.next = node;
}
// 指定位置删除
public static void deleteByPosition(LinkedList head, int pos) {
LinkedList temp = head;
int count = 0;
while (temp.next != null && count < pos - 1) {
count++;
temp = temp.next;
}
temp.next = temp.next.next;
}
private static int count(LinkedList head) {
if (isEmpty(head)) {
throw new RuntimeException("链表没东西,臣妾很难做到啊~");
}
LinkedList temp = head;
int count = 0;
while (temp.next != null) {
temp = temp.next;
count++;
}
System.out.println("链表有效节点个数:" + count);
return count;
}
private static void get(LinkedList head, int index) {
if (isEmpty(head)) {
throw new RuntimeException("链表没东西,臣妾很难做到啊~");
}
// 1、获取链表长度
int size = count(head);
// 2、边界判断
if (index <= 0 || index > size) {
System.out.println("越界了~朋友");
}
// 3、遍历到size-index位置,就是倒数第k个节点
LinkedList temp = head.next;
for (int i = 0; i < size-index; i++) {
temp = temp.next;
}
System.out.println("倒数第"+ index + "个节点的值:" + temp.data);
}
public static boolean isEmpty(LinkedList head) {
if (head.next == null) {
return true;
}
return false;
}
}
class LinkedList{
public int data;
public LinkedList next;
public LinkedList(int data) {
this.data = data;
this.next = null;
}
}