Hey,我是寒水,一名大二学生,电子商务专业在读,正在学习Java中。我试图将在Java学习中遇到的一些困惑和最终的解答发在这个账号上,希望以此来激励我不要放弃学习!
链表是一种数据元素按照链式存储结构进行存储的数据结构,物理上具有非连续的特点。链表有一系列的数据结点组成,每个结点又包含数据域和应用域两部分。
同时连式存储不仅可用来表示线性表,而且可用来表示各种非线性的数据结构。链表还可以细分为如下几类。
-
单链表:每个节点只包含1个引用
-
双向链表:若每个结点包含两个引用,一个指向下一个结点,另一个指向上一个结点,这就是双向链表。
-
单循环链表:终端结点的引用域null改为指向表头结点或开始结点即可构成单循环链表。
-
多重链的循环链表:如果将表中节点链在多个环上,将构成多重链的循环链表。
我所写的第一个链表如下,即创建一个联盟,通过输入联盟成员的ID,hp,level加入成员,最后可通过代码实现追加成员、插入头成员(盟主)、查找成员、插入成员、删除成员、计算人数、显示所有成员等功能。代码如下:
- 建立成员类
class character{ //建立角色类,角色拥有ID、生命值、等级
String ID;
int hp;
int level;
}
- 建立联盟类,并实现在链尾追加成员
class union{ //链式表需要角色信息和引用
character player=new character();
union nextNum;
union playerAddEnd(union head,character player) { //追加结点
union num,robot;
if((num=new union())==null) { //分配内存失败,无法插入
System.out.println("Sorry, you cannot do it now! ");
return null;
}
else { //头引用
num.player=player;
num.nextNum=null;
if(head==null) {
head=num;
return head;
}
robot=head; //寻找表尾
while(head.nextNum!=null) {
robot=robot.nextNum;
}
robot.nextNum=num;
return head;
}
}
- 插入头成员
union playerAddFirst(union head,character player) {
union num;
if((num=new union())==null) { //分配内存失败,无法插入
System.out.println("Sorry, you cannot do it this way");
return null;
}
else {
num.player=player; //插入内容
num.nextNum=head; //指向头引用
head=num; //头引用指向新增结点
return head;
}
}
- 查找成员
union playerFind(union head,String ID) { //查找结点
union robot=head;
while(robot!=null) {
if((robot.player.ID.compareTo(ID))==0) { //信息有效,进行查找
return robot; //返回查找信息
}
robot=robot.nextNum; //查找下一成员
}
return null;
}
- 添加成员
union playerAdd(union head,String key,character player) {
union num,robot;
if((num=new union())==null) { //插入失败
System.out.println("Sorry, you can not do it this way! ");
return null;
}
num.player=player;
robot=playerFind(head,key);
if(robot!=null) { //查找需要插入的点,并将该点的引用指向插入结点,插入结点继承原有结点引用
num.nextNum=robot.nextNum;
robot.nextNum=num;
}
else { //无法寻到,报错。
System.out.println("Sorry, The system cannot find the place. ");
return null;
}
return head;
}
- 删除成员
int playerDelete(union head,String key){ //删除结点
union num=head,robot=head;
while(robot!=null) {
if(robot.player.ID.compareTo(key)==0) { //num为前一个结点,robot为删除结点,当搜寻到删除结点时,删除结点的引用传递给num,删除结点被删除
num.nextNum=robot.nextNum;
robot=null;
return 1;
}
else {
num=robot;
robot=robot.nextNum;
}
}
return 0; //返回0值,表示未被删除
}
- 计算成员人数(计算总结点)
int playerLen(union head) { //计算联盟人数
union robot=head;
int Len=0;
while(robot!=null) {
Len++;
robot=robot.nextNum;
}
return Len; //返回结点数量,即返回联盟人数
}
- 输出所有成员
void playerAll(union head) { //遍历结点,并输出结点的信息
union robot=head;
character player;
System.out.printf("现在联盟一共有%d人,人员名单如下:\n",playerLen(head));
while(robot!=null) {
player=robot.player;
System.out.printf("角色ID:%s 生命值:%d 等级:%d\n",player.ID,player.hp,player.level);
robot=robot.nextNum;
}
}
}
完整代码与实例如下:
import java.util.*;
class character{ //建立角色类,角色拥有ID、生命值、等级
String ID;
int hp;
int level;
}
class union{ //链式表需要角色信息和引用
character player=new character();
union nextNum;
/*
*
*/
union playerAddEnd(union head,character player) { //追加结点
union num,robot;
if((num=new union())==null) { //分配内存失败,无法插入
System.out.println("Sorry, you cannot do it now! ");
return null;
}
else { //头引用
num.player=player;
num.nextNum=null;
if(head==null) {
head=num;
return head;
}
robot=head; //寻找表尾
while(head.nextNum!=null) {
robot=robot.nextNum;
}
robot.nextNum=num;
return head;
}
}
/*
*
*/
union playerAddFirst(union head,character player) {
union num;
if((num=new union())==null) { //分配内存失败,无法插入
System.out.println("Sorry, you cannot do it this way");
return null;
}
else {
num.player=player; //插入内容
num.nextNum=head; //指向头引用
head=num; //头引用指向新增结点
return head;
}
}
/*
*
*/
union playerFind(union head,String ID) { //查找结点
union robot=head;
while(robot!=null) {
if((robot.player.ID.compareTo(ID))==0) { //信息有效,进行查找
return robot; //返回查找信息
}
robot=robot.nextNum; //查找下一成员
}
return null;
}
/*
*
*/
union playerAdd(union head,String key,character player) {
union num,robot;
if((num=new union())==null) { //插入失败
System.out.println("Sorry, you can not do it this way! ");
return null;
}
num.player=player;
robot=playerFind(head,key);
if(robot!=null) { //查找需要插入的点,并将该点的引用指向插入结点,插入结点继承原有结点引用
num.nextNum=robot.nextNum;
robot.nextNum=num;
}
else { //无法寻到,报错。
System.out.println("Sorry, The system cannot find the place. ");
return null;
}
return head;
}
/*
*
*/
int playerDelete(union head,String key){ //删除结点
union num=head,robot=head;
while(robot!=null) {
if(robot.player.ID.compareTo(key)==0) { //num为前一个结点,robot为删除结点,当搜寻到删除结点时,删除结点的引用传递给num,删除结点被删除
num.nextNum=robot.nextNum;
robot=null;
return 1;
}
else {
num=robot;
robot=robot.nextNum;
}
}
return 0; //返回0值,表示未被删除
}
/*
*
*/
int playerLen(union head) { //计算联盟人数
union robot=head;
int Len=0;
while(robot!=null) {
Len++;
robot=robot.nextNum;
}
return Len; //返回结点数量,即返回联盟人数
}
/*
*
*/
void playerAll(union head) { //遍历结点,并输出结点的信息
union robot=head;
character player;
System.out.printf("现在联盟一共有%d人,人员名单如下:\n",playerLen(head));
while(robot!=null) {
player=robot.player;
System.out.printf("角色ID:%s 生命值:%d 等级:%d\n",player.ID,player.hp,player.level);
robot=robot.nextNum;
}
}
}
public class linklist{
public static void main(String[] args) {
Scanner input=new Scanner(System.in);
union num=null,head=null;
union union=new union();
String name;
System.out.println("请输入联盟成员信息"); //输入联盟成员信息
do {
character player=new character();
System.out.println("请输入联盟成员ID,输入‘0’退出");
player.ID=input.next();
if(player.ID.compareTo("0")==0) {
break;
}
else {
System.out.println("请输入联盟成员生命值");
player.hp=input.nextInt();
System.out.println("请输入联盟成员等级");
player.level=input.nextInt();
num=union.playerAddEnd(num, player); //在链尾增加结点
}
}while(true);
// name=input.next(); 删除某结点
// union.playerDelete(head, name);
union.playerAll(num); //输出所有成员信息
System.out.println("请输入想要查找的成员ID");
name=input.next();
num=union.playerFind(num, name); //找到的是一个结点,无法直接输入,故传值给num
if(num!=null) {
character player = num.player;
System.out.printf("该成员ID为%s,生命值为%d,等级%d",player.ID,player.hp,player.level);
}
else {
System.out.printf("查无此人");
}
}
}
不过目前存在1个bug,只能输入2个结点,输入3个就报错,大家可以帮我看一看问题在哪里吗?日后我发现错误了我会对这篇博客进行更正:-),感谢阅读!
(错误可能是未分配内存造成,如需截图分析,请联系我,真的万分感谢!)