数据结构--单链表
1) 链表是以节点的方式来存储,是链式存储
2) 每个节点包含 data 域, next 域:指向下一个节点.
3) 如图:发现链表的各个节点不一定是连续存储.
4) 链表分带头节点的链表和没有头节点的链表,根据实际的需求来确定
5) 各个节点是分散的存在,他们的联系是指向,节点A指向了节点B,构建时关键是搭建出联系指向,遍历时只要找到
6) 由后给前赋值,如删除:tempNode.nextNode = tempNode.nextNode.nextNode;
使用带 head 头的单向链表实现 –水浒英雄排行榜管理完成对英雄人物的增删改查操作
3.1、第一种方法在添加英雄时,直接添加到链表的尾部
3.2、第二种方式在添加英雄时,根据排名将英雄插入到指定位置
1)思路的分析示意图
3.3、修改节点功能
思路
(1) 先找到该节点,通过遍历,
(2)temp.name = newHeroNode.name ; temp.nickname= newHeroNode.nickname
3.4、删除节点
1)思路的分析示意图
四、上代码
Node节点类
1 public class HeroNode { 2 public Integer no; 3 public String name; 4 public String nickName; 5 public HeroNode nextNode; 6 7 public HeroNode() { 8 } 9 10 public HeroNode(Integer no, String name, String nickName) { 11 this.no = no; 12 this.name = name; 13 this.nickName = nickName; 14 } 15 16 @Override 17 public String toString() { 18 return "HeroNode{" + 19 "no=" + no + 20 ", name='" + name + '\'' + 21 ", nickName='" + nickName + '\'' + 22 '}'; 23 } 24 }
public class SingleLinkListServe { //初始化一个头节点,头节点不要动,不存放任何数据 HeroNode headNode = new HeroNode(); //1、向链表尾部添加节点 /** * 思路:当不考虑编号的顺序时 * 1、找到当前链表的最后节点 * 2、将最后节点的nextNode指向新的节点 */ public void addNode(HeroNode newNode){ //创建一个临时节点 HeroNode tempNode = headNode; //循环,直到找到最后一个节点就退出 while (true){ if(tempNode.nextNode == null){ break; } tempNode = tempNode.nextNode; } //循环退出后即找到最后一个节点了,在最后一个节点的nextNode进行添加新节点 tempNode.nextNode = newNode; } //2、根据序号添加节点 /** * 思路:(如果有这个排名,则添加失败,并给出提示) * 1、找到添加的位置 * 2、新的节点.nextNode = temp.nextNode * 3、temp.next = 新的节点 */ public void addByOrder(HeroNode newHeroNode){ //创建临时节点 HeroNode tempNode = headNode; //创建一个标记 boolean flag = false; while(true){ if(tempNode.nextNode == null){ break; } if(tempNode.nextNode.no > newHeroNode.no){ break; } if(tempNode.nextNode.no == newHeroNode.no){ flag = true; break; } tempNode = tempNode.nextNode; } if(flag){//编号存在,不能添加 System.out.printf("编号%d的节点已经存在,不能添加",tempNode.no); }else { newHeroNode.nextNode = tempNode.nextNode; tempNode.nextNode = newHeroNode; } } //3、根据编号修改节点信息 public void update(HeroNode newNode){ HeroNode tempNode = headNode; //是否找到的标识 boolean flag = false; if(headNode.nextNode == null){ System.out.println("链表为空"); return; } while (true){ tempNode = tempNode.nextNode; //最后一个节点 if(tempNode == null){ break; } //找到了,标识为true if(tempNode.no == newNode.no){ flag = true; break; } } //根据flag判断是否找到节点 if(flag){ tempNode.name = newNode.name; tempNode.nickName = newNode.nickName; }else { System.out.println("未找到节点"); } } //4、删除节点 public void delNode(int no){ HeroNode tempNode = headNode; boolean flag = false; if(tempNode == null){ System.out.println("链表为空"); } while(true){ if(tempNode.nextNode == null){ break; } if(tempNode.nextNode.no == no){ flag = true; break; } tempNode = tempNode.nextNode; } if(flag){//表示找到节点了 tempNode.nextNode = tempNode.nextNode.nextNode; }else { System.out.println("节点没找到"); } } //5、遍历链表 public void printList(){ //创建一个临时节点 HeroNode tempNode = headNode; //判断链表是否为空 if(tempNode.nextNode== null){ System.out.println("链表为空"); return; } while(true){ //判断是否为最后节点 if(tempNode.nextNode== null){ break; } //非最后节点就输出打印,并将临时节点往下移动 System.out.println(tempNode.nextNode); tempNode = tempNode.nextNode; } } }
1 public class SingleLinkListDemo { 2 public static void main(String[] args) { 3 HeroNode heroNode1 = new HeroNode(1,"宋江","及时雨"); 4 HeroNode heroNode2 = new HeroNode(2,"卢俊义","玉麒麟"); 5 HeroNode heroNode3 = new HeroNode(3,"吴用","智多星"); 6 HeroNode heroNode4 = new HeroNode(4,"林冲","豹子头"); 7 8 SingleLinkListServe singleLinkListServe = new SingleLinkListServe(); 9 //直接添加 10 /*singleLinkListServe.addNode(heroNode1); 11 singleLinkListServe.addNode(heroNode2); 12 singleLinkListServe.addNode(heroNode3); 13 singleLinkListServe.addNode(heroNode4);*/ 14 //有序添加 15 singleLinkListServe.addByOrder(heroNode1); 16 singleLinkListServe.addByOrder(heroNode2); 17 singleLinkListServe.addByOrder(heroNode4); 18 singleLinkListServe.addByOrder(heroNode3); 19 singleLinkListServe.printList(); 20 System.out.println("————————————————————————————————————————————————————————————————"); 21 //更新 22 HeroNode updateNode = new HeroNode(4,"林冲冲","豹子头大哥"); 23 singleLinkListServe.update(updateNode); 24 singleLinkListServe.printList(); 25 System.out.println("————————————————————————————————————————————————————————————————"); 26 //删除 27 singleLinkListServe.delNode(4); 28 singleLinkListServe.printList(); 29 } 30 }
1 //单链表反转 2 public HeroNode turnNode(){ 3 HeroNode head = headNode; 4 if(head.nextNode == null || head.nextNode.nextNode == null){ 5 return head; 6 } 7 HeroNode curr = head; 8 HeroNode prev = null; 9 10 while(curr != null){ 11 HeroNode next = curr.nextNode; 12 curr.nextNode = prev; 13 prev = curr; 14 curr = next; 15 } 16 17 return prev; 18 19 } 20 //遍历反转链表 21 public void printList(HeroNode headNode){ 22 //创建一个临时节点 23 HeroNode tempNode = headNode; 24 while(tempNode !=null){ 25 if(tempNode.nextNode != null){ 26 System.out.println(tempNode); 27 } 28 tempNode = tempNode.nextNode; 29 } 30 }
1 //从尾到头打印单链表(不改变链表结构) 2 public void printListUseStack(){ 3 4 HeroNode tempNode = headNode; 5 6 Stack<HeroNode> stack = new Stack<>(); 7 8 if(tempNode.nextNode == null){ 9 System.out.println("链表为空"); 10 return; 11 } 12 13 while(tempNode.nextNode != null){ 14 //将获取的数据放入栈中 15 stack.push(tempNode.nextNode); 16 tempNode = tempNode.nextNode; 17 } 18 while(stack.size()>0){ 19 //从栈中输出 20 System.out.println(stack.pop()); 21 } 22 23 }