一.回顾
使用带head头的单向链表实现 –水浒英雄排行榜管理
要求:
1)完成对英雄人物的增删改查操作
2)第一种方法在添加英雄时,直接添加到链表的尾部
2)第二种方式在添加英雄时,根据排名将英雄插入到指定位置 (如果有这个排名,则添加失败,并给出提示)
上一章完成了要求2,即第一种方法,这一张将要完成第二种方法和对英雄人物的增删改查操作即对链表的增删改查操作
二.第二种方法
2.1图解分析
想要按照编号的顺序添加
1) 首先找到新添加的节点(假如为node)的位置, 是通过辅助变量(指针temp), 通过遍历来搞定.判定条件为 temp.next.no>node.no,说明新节点的排名在temp和temp.next的中间,说明这个位置就是它该插入的位置
2) node.next = temp.next
3) 将temp.next = node
2.2代码实现
第二种方法和第一种相比的话就一个方法不同即add方法不同,只需要改该方法就行
public void addByOrder(HeroNode node) {
HeroNode temp = head;
boolean flag = false;//用来判断是否插入一样的排名
while (true) {
if (temp.next == null) {//说明遍历完了链表,也没找到适合的插入点
break;
}
if (temp.next.no > node.no) {//找到了该插入的位置
break;
}
if (temp.next.no == node.no) {
flag = true;
break;
}
temp = temp.next;
}
if (flag) {//重复了不能插入
System.out.printf("排名%d已有了,不能插入",node.no);
System.out.println();
}else {
node.next = temp.next;
temp.next=node;
}
}
2.3验证结果
添加顺序是乱序的
可以看到结果是已经排好序的并且如果有相同的排名的话也会有提示.至此方法二已经完成了,
三.增删改查
3.1改
3.1.1代码展示:
public void update(HeroNode newNode) {
HeroNode temp = head.next;
boolean flag = false;//用来标志是否找到待修改的节点的编号
if (temp == null) {//空链表
System.out.println("链表为空,无法修改");
return;
}
while (true) {
if (temp == null) {//遍历整个链表也没找到
break;
}
if (temp.no == newNode.no) {//找到了
flag = true;
break;
}
temp = temp.next;
}
if (flag) {//表示找到了
temp.name = newNode.name;
temp.nickName = newNode.nickName;
}else {
System.out.printf("遍历整个链表,也没找到排名为%d的英雄,无法修改",newNode.no);
System.out.println();
}
}
3.1.2分析
因为是修改,肯定是根据排名找英雄修改,如果排名也变了,就是新增了,就不归修改了
1)首先先判断是否为空链表,如果为空,则不能修改
2)接着循环遍历要修改的英雄的排名,找到之后把要修改的字段赋给原字段
3.1.3结果展示
现在就是要把排名为3的李逵修改为李鬼
修改成功~~
3.2删
3.2.1代码展示
public void del(int no){
boolean flag = false;
HeroNode temp = head;
if (temp.next == null){
System.out.println("链表为空~");
return;
}
while (true){
if (temp.next==null){
System.out.println("链表为空");
break;
}
if (temp.next.no==no){
flag = true;
break;
}
temp = temp.next;
}
if (flag){
temp.next = temp.next.next;
}else {
System.out.printf("排名为%d的英雄不存在~",no);
System.out.println();
}
}
3.2.2分析
和修改类似
1)首先判断链表是否为空,为空则提示不能删除
2)重要的一点是要找到要删除节点的前一个,让它的next指向它next.next,这样的话,要删除的节点就变成了一个内存垃圾,这样就完成了删除,至于怎么找到前一个节点,用一个临时变量(指针)做循环,找到的判别条件是temp.next.no = no,这样temp就是我们要找到的前一个节点
3.2.3结果展示
可以看出我们要删的是3号英雄
删除成功~
3.3查
3.3.1代码展示
public void check(int no){
HeroNode temp = head.next;
boolean flag = false;
if (temp ==null){
System.out.println("链表为空,无法查询");
return;
}
while (true){
if (temp ==null){
break;
}
if (temp.no==no){
flag =true;
break;
}
temp = temp.next;
}
if (flag){
System.out.println(temp);
}
else {
System.out.printf("没找到排名为%d的英雄",no);
System.out.println();
}
}
3.3.2解析
和删除类似~
1)首先判断链表是否为空,为空则无法查询
2)和删除节点不同的是,删除节点是找到要删除的前一个节点,而我们只需要找到编号一样的节点就行了,找到之后,直接打印这个节点的信息,即完成了查询功能,至于怎么完成,则和删除一样,创建一个临时变量指针temp,循环找temp.no = no,找到之后直接打印temp节点就行了
3.3.3结果展示
可以看到要查询的是排名为2的英雄
查询成功~
至于增功能,前面已经完成了,对应的方法名为addByOrder
四.小结
1)其实这四个功能,都大同小异,都很类似,要说还是删除要注意一下,要找到前一个节点才能删除
2)添加功能也很独特,要先加入后一个节点的 newNode.next=temp .next temp.next=newNode
3)其实这些功能,都离不开遍历循环的功能,都要先创建一个临时变量做指针进行循环操作,因为头节点是不能动的
4)这些还是链表的基础功能,下一节做一些相关链表的题巩固一下