链表(Linked List)介绍
链表是有序的列表,但是它在内存中是存储如下:
链表是以节点的方式来存储的,是链式存储。
每个节点包含data域,next域:指向下一个节点。
如图:链表的各个节点不一定是连续存储的。
链表分带头节点的链表和没有头节点的链表,根据实际需求来确定。
单链表(带头结点)逻辑结构示意图:
单链表的应用实例 使用带head头的单向链表实现-水浒英雄排行榜管理完成对英雄人物的增删改查操作。
第一种方法在添加英雄时,直接添加到链表的尾部。
第二种方法在添加英雄时,根据排名将英雄插入到指定位置(如果有这个排名,则添加失败,并给出提示)
单链的创建示意图 添加(创建)先创建一个head头节点,作用就是表示单链表的头。
后面我们每添加一个节点,就直接加入到链表的最后。
遍历:通过一个辅助遍历,帮助遍历整个链表。
代码实现(直接添加到链表的尾部) /** * @Author Fu~Qiang * @Time 2021-3-13 19:06:46 * @Version 1.0 * <p>Description:单链表</p> */ 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 singleLinkedList = new SingleLinkedList(); //加入 singleLinkedList.add(heroNode2); singleLinkedList.add(heroNode1); singleLinkedList.add(heroNode3); singleLinkedList.add(heroNode4); singleLinkedList.list(); } } //定义一个SingleLinkedList来管理英雄 class SingleLinkedList { //先初始化一个头节点 private HeroNode head = new HeroNode(0,"",""); //添加节点到单向链表方法 //当不考虑编号的顺序时,找到当前链表最后的节点,将最后这个节点的next指向新的节点 public void add(HeroNode heroNode) { HeroNode temp = head; //遍历链表,找到最后 while(true) { if(temp.next == null) { break; } temp = temp.next; } //当退出while循环时,temp就指向了链表的最后 temp.next = heroNode; } //显示链表 public void list() { //判断链表是否为null if(head.next == null) { System.out.println("链表为空~~"); return; } HeroNode temp = head.next; while(true) { //是否到链表最后 if(temp == null) { break; } //输出节点信息 System.out.println(temp); //将next后移 temp = temp.next; } } } //定义一个heroNode,每个heroNode对象就是一个节点 class HeroNode{ public int no; public String name; public String nickName; public HeroNode next;//指向下一个节点 //构造器 public HeroNode(int no,String name,String nickName) { this.no = no; this.name = name; this.nickName = nickName; } //重写toString @Override public String toString() { // TODO Auto-generated method stub return "HeroNode [no="+no+",name="+name+",nickName="+nickName+"]"; } } 运行截图 按照编号的顺序添加首先找到新添加的节点的位置,是通过辅助变量(指针)
新的节点.next=temp.next
让temp.next=新的节点
代码实现(按照编号顺序添加) /** * @Author Fu~Qiang * @Time 2021-3-13 19:06:46 * @Version 1.0 * <p>Description:单链表</p> */ 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 singleLinkedList = new SingleLinkedList(); //加入 singleLinkedList.add(heroNode2); singleLinkedList.add(heroNode1); singleLinkedList.add(heroNode3); singleLinkedList.add(heroNode4); singleLinkedList.list(); // singleLinkedList.addByOrder(heroNode2); // singleLinkedList.addByOrder(heroNode1); // singleLinkedList.addByOrder(heroNode4); // singleLinkedList.addByOrder(heroNode3); // singleLinkedList.list(); } } //定义一个SingleLinkedList来管理英雄 class SingleLinkedList { //先初始化一个头节点 private HeroNode head = new HeroNode(0,"",""); //添加节点到单向链表方法 //当不考虑编号的顺序时,找到当前链表最后的节点,将最后这个节点的next指向新的节点 public void add(HeroNode heroNode) { HeroNode temp = head; //遍历链表,找到最后 while(true) { if(temp.next == null) { break; } temp = temp.next; } //当退出while循环时,temp就指向了链表的最后 temp.next = heroNode; } //第二种添加英雄的方法 public void addByOrder(HeroNode heroNode) { HeroNode temp = head; boolean flag = false; while(true) { if(temp.next == null) {//链表最后 break; } if(temp.next.no > heroNode.no) { break; }else if(temp.next.no == heroNode.no) {//编号已存在 flag = true; break; } temp = temp.next; } if(flag) {//flag=true,编号已存在,不能添加 System.out.printf("准备插入的英雄的编号 %d 已经存在",heroNode.no); }else { //插入到链表中 heroNode.next = temp.next; temp.next = heroNode; } } //显示链表 public void list() { //判断链表是否为null if(head.next == null) { System.out.println("链表为空~~"); return; } HeroNode temp = head.next; while(true) { //是否到链表最后 if(temp == null) { break; } //输出节点信息 System.out.println(temp); //将next后移 temp = temp.next; } } } //定义一个heroNode,每个heroNode对象就是一个节点 class HeroNode{ public int no; public String name; public String nickName; public HeroNode next;//指向下一个节点 //构造器 public HeroNode(int no,String name,String nickName) { this.no = no; this.name = name; this.nickName = nickName; } //重写toString @Override public String toString() { // TODO Auto-generated method stub return "HeroNode [no="+no+",name="+name+",nickName="+nickName+"]"; } } 运行截图