文章目录
链表介绍
应用示例
链表介绍
链表是有序的列表,但是它在内存中是存储是不连续的,如下:
链表是以节点的方式来存储,是链式存储:
①每个节点包含data域存储数据,next域指向下一个节点
②链表的各个节点不一定是连续存储
③链表分带头节点的链表和没有头节点的链表,根据实际的需求来确定
单链表(带头结点)逻辑结构示意图如下:
应用示例
使用带head头的单向链表实现水浒英雄排行榜管理完成对英雄人物的增删改查操作。
①节点类
//定义HeroNode,每个HeroNode就是一个链表节点 class HeroNode { //data域 public int no; //编号排名 public String name; //名字 public String nikeName; //昵称 //next域 public HeroNode next; //构造器 public HeroNode(int no, String name, String nikeName) { this.no = no; this.name = name; this.nikeName = nikeName; } //toString方法 @Override public String toString() { return "HeroNode{" + "no=" + no + ", name='" + name + '\'' + ", nikeName='" + nikeName + '\'' + '}'; } }
②链表类
//定义SingleLinkedList管理英雄人物,相当于是链表 class SingleLinkedList { //先初始化一个头节点,不存放具体数据,注意头节点保持不动,后面不能直接操作它 private HeroNode head = new HeroNode(0,null,null); //添加链表节点 //1、不考虑编号排名(找到最后一个节点,使得最后一个节点的next指向新的节点) public void add1(HeroNode heroNode){ //因为头节点不能动,因此要一个辅助变量temp HeroNode temp = head; //遍历找到最后 while (true){ if (temp.next == null){ break; } temp = temp.next; } //当退出while就意味着找到最后一个节点了 temp.next = heroNode; } //2、考虑编号排名(根据排名编号从小到大,若已存在则添加失败) public void add2(HeroNode heroNode){ //因为头节点不能动,因此要一个辅助变量temp //因为是单链表,temp位于添加位置的前一个节点,否则插入不了 HeroNode temp = head; boolean flag = false; //用来标记排名编号是否存在,默认不存在 while (true){ if (temp.next == null){ //说明temp已经在最后,直接添加 break; } if (temp.next.no > heroNode.no){ //位置找到了,temp即在heroNode前 break; } if (temp.next.no == heroNode.no){ //该排名编号已经存在 flag = true; break; } temp = temp.next; //后移遍历 } if (flag){ System.out.printf("编号%d已经存在,添加失败!\n",heroNode.no); }else { //将heroNode添加进链表,在temp后一个 heroNode.next = temp.next; temp.next = heroNode; } } //根据编号修改节点中的信息,即编号不能改 public void update(HeroNode newHeroNode){ if (head.next == null){ System.out.println("链表为空!"); return; } HeroNode temp = head.next; boolean flag = false; //标记是否在链表中找到该编号 while (true){ if (temp.next == null){ break; } if (temp.no == newHeroNode.no){ flag = true; break; } temp = temp.next; } if (flag){ temp.name = newHeroNode.name; temp.nikeName = newHeroNode.nikeName; }else { System.out.printf("未找到编号为%d的英雄人物",newHeroNode.no); } } //根据编号删除节点 public void remove(HeroNode delHeroNode){ if (head.next == null){ System.out.println("链表为空!"); } HeroNode temp = head; boolean flag = false; //标记是否找到要删除的节点 while (true){ if (temp.next == null){ break; } if (temp.next.no == delHeroNode.no){ //应该找到的是要删除节点的前一个节点 flag = true; break; } temp = temp.next; } if (flag){ temp.next = temp.next.next; } else { System.out.println("未在链表中找到该编号的节点!"); } } //显示链表(遍历) public void list(){ if (head.next == null){ System.out.println("链表为空!"); return; } HeroNode temp = head.next; while (true){ if (temp == null){ break; } System.out.println(temp); temp = temp.next; } } }
③测试类
public class SingleLinkedListDemo { public static void main(String[] args) { //英雄人物 HeroNode heroNode1 = new HeroNode(1, "宋江", "及时雨"); HeroNode heroNode2 = new HeroNode(2, "卢俊义", "玉麒麟"); HeroNode heroNode3 = new HeroNode(3, "吴用", "智多星"); HeroNode heroNode4 = new HeroNode(4, "林冲", "豹子头"); //创建一个列表并采用方式一添加节点 // SingleLinkedList singleLinkedList1 = new SingleLinkedList(); // singleLinkedList1.add1(heroNode1); // singleLinkedList1.add1(heroNode2); // singleLinkedList1.add1(heroNode3); // singleLinkedList1.add1(heroNode4); //创建一个列表并采用方式二添加节点 SingleLinkedList singleLinkedList2 = new SingleLinkedList(); singleLinkedList2.add2(heroNode4); singleLinkedList2.add2(heroNode1); singleLinkedList2.add2(heroNode3); singleLinkedList2.add2(heroNode2); singleLinkedList2.add2(heroNode3); //修改 HeroNode newHeroNode = new HeroNode(3, "吴先生", "智much星"); singleLinkedList2.update(newHeroNode); //删除 singleLinkedList2.remove(heroNode2); //遍历显示链表 singleLinkedList2.list(); } }