对于链表的介绍在之前的博客中已经有所介绍,这里就不介绍了,直接进入使用案例
一、单链表的应用实例
使用带 head 头的双向链表实现 - 水浒英雄排行榜管理完成对英雄任务的增删改查操作。
1)添加节点:在添加英雄时,根据排名将英雄插入到指定的位置(如果链表中已经存在此排名,则添加失败,给出提示信息),思路如下:
代码如下:
public void add2(HeroNode node){
HeroNode temp = head;
boolean flag = false;//如果为true,便是节点已经存在
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.println("此编号已经存在,不能添加~~~");
}else{
node.next = temp.next;
temp.next = node;
temp.next.pre = node;
node.pre = temp;
}
}
其余的功能都是比较简单的,我就直接把代码贴上去了:
public class DoubleLinkedListDemo {
public static void main(String[] args) {
DoubleLinkedList list = new DoubleLinkedList();
HeroNode hero1 = new HeroNode(1,"宋江","及时雨");
HeroNode hero2 = new HeroNode(2,"卢俊义","玉麒麟");
HeroNode hero3 = new HeroNode(3,"吴用","智多星");
HeroNode hero4 = new HeroNode(4,"林冲","豹子头");
/*list.add(hero1);
list.add(hero4);
list.add(hero3);
list.add(hero2);*/
list.add2(hero1);
list.add2(hero2);
list.add2(hero3);
list.add2(hero4);
list.delete(hero2);
System.out.println("删除之后的链表为~");
list.list();
}
}
//创建 DoubleLinkedList,管理我们的英雄
class DoubleLinkedList{
//先创建一个头节点,头节点不能动,不存放具体的数据
private HeroNode head = new HeroNode(0,"","");
//添加节点到双向链表
//思路:当不考虑编号顺序时
//1.找到当前链表的最后节点
//2.将最后这个节点的 next 域指向新的节点
//3.将新的节点的 pre 域指向最后的这个节点
public void add(HeroNode node){
//因为 head 节点不能动,所以我们需要一个辅助节点 temp
HeroNode temp = head;
//通过遍历找到链表的最后节点
while (temp.next != null){
temp = temp.next;
}
//让链表的最后节点的 next 域指向新的节点
temp.next = node;
node.pre = temp;
}
//第二种方式在添加英雄时,根据排名将英雄添加到指定位置
//(如果有这个排名,则添加失败,并给出提示)
public void add2(HeroNode node){
HeroNode temp = head;
boolean flag = false;//如果为true,便是节点已经存在
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.println("此编号已经存在,不能添加~~~");
}else{
node.next = temp.next;
temp.next = node;
temp.next.pre = node;
node.pre = temp;
}
}
//遍历显示链表
public void list(){
//如果链表为空
if(head.next == null){
System.out.println("链表为空!!!");
return;
}
//因为 head 节点不能动,所以我们需要一个辅助节点 temp
HeroNode temp = head;
while (temp.next != null){
//输出节点信息
System.out.println(temp.next);
//将 temp 后移
temp = temp.next;
}
}
//修改节点,根据 no 修改,即 no 不能改
public void update(HeroNode node){
//判断链表是否为空
if(head.next == null){
System.out.println("链表为空");
return;
}
//因为 head 节点不能动,所以我们需要一个辅助节点 temp
HeroNode temp = head.next;
boolean flag = false;//表示是否找到该节点
while (true){
if(temp == null){//说明 temp 已经在链表的最后
break;
}
if(temp.no == node.no){
flag = true;//找到了
break;
}
temp = temp.next;//将 temp 后移
}
if(flag){
temp.name = node.name;
temp.nickName = node.name;
}else{
System.out.printf("没有找到编号 %d 的节点,不能修改\n",node.no);
}
}
//删除节点,根据节点的 no 进行删除
public void delete(HeroNode node){
//因为 head 节点不能动,所以我们需要一个辅助节点 temp
HeroNode temp = head.next;
boolean flag = false;//表示是否找到该节点
while (true){
if(temp == null){//说明 temp 已经在链表的最后
break;
}
if(temp.no == node.no){
flag = true;
break;
}
temp = temp.next;//将 temp 后移
}
if(flag){//找到该节点
temp.pre.next = temp.next;//将 temp 前一个节点的 next 域指向 temp 的下一个节点
temp.next.pre = temp.pre;//将 temp 下一个节点的 pre 域指向 temp 的前一个节点
}else{
System.out.printf("没有找到编号 %d 的节点,不能删除\n",node.no);
}
}
}
class HeroNode{
public int no;
public String name;
public String nickName;
public HeroNode pre;//pre 指向上一个节点
public HeroNode next;//next指向下一个节点
public HeroNode(int no,String name,String nickName){
this.no = no;
this.name = name;
this.nickName = nickName;
}
@Override
public String toString() {
return "HeroNode{" +
"no=" + no +
", name='" + name + '\'' +
", nickName='" + nickName + '\'' +
'}';
}
}
双链表的使用