①打印链表中有效数据的个数
public static int len(heroNode head) {
//从头结点的下一个节点开始遍历
//首先判断链表是否为空
if (head.next == null) {
//打印提示
System.out.println("链表为空,无数据");
return 0;
}
int i = 0;
//利用一个节点辅助遍历链表
heroNode temp = head.next;
//若链表不为空则开始后面的操作
while (temp != null) {
i++;
//向下一个节点移动
temp = temp.next;
}
return i;
}
②查找链表中倒数的第k个节点
//查找倒数第k个节点
//参数传入一个链表和一个整数k.
public static void kReciprocal(heroNode head, int y) {
//判断链表是否为空
if (head.next == null) {
//放回提示语句
System.out.println("链表为空无数据");
return;
}
//获得链表的有效长度
int len = print1(head);
//获得节点
heroNode head2 = head.next;
//定义一个游标用来判断向后走多少
for (int i = 0; i < (len - y); i++) {
//判断当前节点是否为空
if(head2 == null){
System.out.println("错误");
return;
}
head2 = head2.next;
}
//打印需求节点
System.out.println(head2.toString());
}
③单链表的反转
//链表的反转
public static heroNode reversal(heroNode head){
//定义一个新的头结点head2方便链表的反转
heroNode head2 = null;
//定义一个节点记录头结点
heroNode node1 = head;
//定义一个空节点作为node1的前一个节点
heroNode node2 = null;
//定义一个while循环在后一个节点不为空前进行向后循环,并进行3反转操作
while(node1 != null){
//定义一个节点node2来记录下一个节点
heroNode node3 = node1.next;
if(node3 == null){
head2 = node1;
}
//新的头结点指向第一个节点
node1.next = node2;
//指向节点后移
node2 = node1;
//头结点后移
node1 = node3;
}
return head2;
}
④链表的反向打印
利用栈实行链表的反向打印
public static void reverPrint(heroNode head) {
//创建一个泛型为heroNode的栈用来存入据
Stack<heroNode> s = new Stack<>();
//判断链表是否为空
if(head.next == null){
System.out.println("链表为空");
}
//定义一个方法
heroNode temp = head.next;
//数据入栈
while(temp != null){
//入栈
s.add(temp);
//下一个数据
temp = temp.next;
}
//判断栈是否为空
while(!s.isEmpty()){
//打印数据
System.out.println(s.pop().toString());
}
}
⑤完整代码实现
import java.util.Scanner;
import java.util.Stack;
public class heroNode {
//编号
int no;
//姓名
String name;
//绰号
String Xname;
//指针域
heroNode next;
public static void main(String[] args) {
//创建头结点
heroNode head = new heroNode(0, "", "");
//实例化扫描仪
Scanner sc = new Scanner(System.in);
//定义一个布尔变量用来控制循环
boolean flag = true;
//定义一个 while循环方便链表结构的使用
while (flag) {
System.out.println("请输入编号");
//接收用户需求编号完成相应操作
int a = sc.nextInt();
//定义switch结构完成操作
switch (a) {
//链表插入
case 1:
//编号
System.out.println("请输入排名");
int no = sc.nextInt();
//输入姓名
System.out.println("请输入姓名");
String name = sc.next();
//输入绰号
System.out.println("请输入绰号");
String xname = sc.next();
//调用方法
add(head, no, name, xname);
break;
//打印链表
case 2:
print(head);
break;
case 3:
//编号
System.out.println("请输入排名");
int no1 = sc.nextInt();
//输入姓名
System.out.println("请输入姓名");
String name1 = sc.next();
//输入绰号
System.out.println("请输入绰号");
String xname1 = sc.next();
addByNo(head, no1, name1, xname1);
break;
case 4:
//请输入要修改的英雄排名
System.out.println("请输入要修改的英雄排名");
int no2 = sc.nextInt();
update(head, no2, sc);
break;
case 5:
//输入删除节点的编号
System.out.println("请输入删除节点的编号");
int x = sc.nextInt();
delete(head, x);
break;
case 6:
System.out.println(len(head));
break;
case 7:
//输入查询位置
System.out.println("输入k的值");
int z = sc.nextInt();
kReciprocal(head,z);
break;
case 8:
//反转链表
System.out.println("反转前:");
print(head);
System.out.println("反转后:");
print(reversal(head));
break;
case 9:
reverPrint(head);
break;
case 0:
flag = false;
break;
default:
System.out.println("无此选项");
}
}
}
//链表构造器
public heroNode(int no, String name, String xname) {
this.no = no;
this.name = name;
this.Xname = xname;
this.next = null;
}
//方便打印重写toString方法
@Override
public String toString() {
return "heroNode{" +
"no=" + no +
", name='" + name + '\'' +
", Xname='" + Xname + '\'' +
'}';
}
//头插法
public static void add(heroNode head, int no, String name, String xname) {
//创建一个新的节点用于插入
heroNode inp = new heroNode(no, name, xname);
//插入时首先要找到链表的最后一个节点
while (true) {
//若节点的下一个节点指向null,则为链表的最后一个节点
if (head.next == null) {
//寻找到直接跳出循环
break;
}
//寻找不到则让节点指向下一个节点
head = head.next;
}
//新建节点默认指向null,所以可省略.
//inp.next = head.next;
//插入接点指向新节点
head.next = inp;
}
//遍历链表
public static void print(heroNode head) {
//从头结点的下一个节点开始遍历
//首先判断链表是否为空
if (head.next == null) {
//打印提示
System.out.println("链表为空,无数据");
return;
}
//利用一个节点辅助遍历链表
heroNode temp = head.next;
//若链表不为空则开始后面的操作
while (temp != null) {
//调用toString方法打印
System.out.println(temp.toString());
//向下一个节点移动
temp = temp.next;
}
}
public static void addByNo(heroNode head, int no, String name, String xname) {
//建立一个辅助节点用来查找英雄排名位置
heroNode temp = head;
//插入的新节点
heroNode inp = new heroNode(no, name, xname);
//判断是否已存在这个排名
//定义一个布尔变量判断是否插入成功
boolean flag = false;
while (true) {
//表明已经到链表的最后
if (temp.next == null) {
break;
}
//判断插入位置
//插入在这个节点的后面
if (temp.next.no > inp.no) {
break;
}
//排名相等表明已经存在
if (temp.next.no == inp.no) {
flag = true;
break;
}
temp = temp.next;
}
if (flag) {
System.out.println("已存在无法插入");
} else {
inp.next = temp.next;
temp.next = inp;
}
}
//修改错误节点
public static void update(heroNode head, int no2, Scanner sc) {
//判断链表是否为空
if (head.next == null) {
System.out.println("链表为空");
return;
}
//定义一个辅助变量来寻找
heroNode temp = head.next;
//定义一个布尔变量用来表示是否查找到
boolean flag = false;
//定义循环完成查找操作
while (true) {
//链表的最后了
if (temp == null) {
break;
}
//查找到编号二对应的节点
if (temp.no == no2) {
flag = true;
break;
}
temp = temp.next;
}
if (flag) {
System.out.println("请输入姓名");
temp.name = sc.next();
System.out.println("请输入绰号");
temp.Xname = sc.next();
} else {
System.out.println("无此节点");
}
}
//删除节点
public static void delete(heroNode head, int x) {
//判断链表是否为空
if (head.next == null) {
System.out.println("链表为空");
return;
}
//定义一个辅助变量来寻找
heroNode temp1 = head.next;
heroNode temp2 = head;
//定义一个布尔变量用来表示是否查找到
boolean flag = false;
//定义循环完成查找操作
while (true) {
//链表的最后了
if (temp1 == null) {
break;
}
//查找到编号二对应的节点
if (temp1.no == x) {
flag = true;
break;
}
temp1 = temp1.next;
temp2 = temp2.next;
}
if (flag) {
temp2.next = temp1.next;
} else {
System.out.println("无此节点,无法删除");
}
}
//获取来拿表中有效数据的个数
public static int len(heroNode head) {
//从头结点的下一个节点开始遍历
//首先判断链表是否为空
if (head.next == null) {
//打印提示
System.out.println("链表为空,无数据");
return 0;
}
int i = 0;
//利用一个节点辅助遍历链表
heroNode temp = head.next;
//若链表不为空则开始后面的操作
while (temp != null) {
i++;
//向下一个节点移动
temp = temp.next;
}
return i;
}
//查找倒数第k个节点
//参数传入一个链表和一个整数k.
public static void kReciprocal(heroNode head, int y) {
//判断链表是否为空
if (head.next == null) {
//放回提示语句
System.out.println("链表为空无数据");
return;
}
//获得链表的有效长度
int len = len(head);
//获得节点
heroNode head2 = head.next;
//定义一个游标用来判断向后走多少
for (int i = 0; i < (len - y); i++) {
//判断当前节点是否为空
if(head2 == null){
System.out.println("错误");
return;
}
head2 = head2.next;
}
//打印需求节点
System.out.println(head2.toString());
}
//链表的反转
public static heroNode reversal(heroNode head){
//定义一个新的头结点head2方便链表的反转
heroNode head2 = null;
//定义一个节点记录头结点
heroNode node1 = head;
//定义一个空节点作为node1的前一个节点
heroNode node2 = null;
//定义一个while循环在后一个节点不为空前进行向后循环,并进行3反转操作
while(node1 != null){
//定义一个节点node2来记录下一个节点
heroNode node3 = node1.next;
if(node3 == null){
head2 = node1;
}
//新的头结点指向第一个节点
node1.next = node2;
//指向节点后移
node2 = node1;
//头结点后移
node1 = node3;
}
return head2;
}
//单链表的反向遍历
//方式1,反向遍历
//方式2,用stack
public static void reverPrint(heroNode head) {
//创建一个泛型为heroNode的栈用来存入据
Stack<heroNode> s = new Stack<>();
//判断链表是否为空
if(head.next == null){
System.out.println("链表为空");
}
//定义一个方法
heroNode temp = head.next;
//数据入栈
while(temp != null){
//入栈
s.add(temp);
//下一个数据
temp = temp.next;
}
//判断栈是否为空
while(!s.isEmpty()){
//打印数据
System.out.println(s.pop().toString());
}
}
}