文章目录
- 链表介绍
- 应用示例
链表介绍
链表是有序的列表,但是它在内存中是存储是不连续的,如下:
链表是以节点的方式来存储,是链式存储:
①每个节点包含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方法@Overridepublic 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){//因为头节点不能动,因此要一个辅助变量tempHeroNode 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();}
}