java的数据结构与算法(4)单项链表
2019-07-28 23:49
465 查看
什么是链表:
是以节点的方式存数据,有data域(存放数据),next域(存放下一个数据的指针)
最大的特征可以是不连续的
使用的场景:后端接受的数据是无序的,需要给前端返回一个有序的数据。
package cn.itjy.linkedlist; public class SingleLinkedListDemo { public static void main(String[] args) { // test // 先创建节点 HeroNode node1 = new HeroNode(1, "宋江", "及时雨"); HeroNode node2 = new HeroNode(2, "吴用", "智多星"); HeroNode node3 = new HeroNode(3, "李逵", "黑旋风"); HeroNode node4 = new HeroNode(4, "林冲", "豹子头"); SingleLinkedList linkedList = new SingleLinkedList(); /* * linkedList.add(node1); linkedList.add(node4); linkedList.add(node2); * linkedList.add(node3); */ linkedList.add2(node1); linkedList.add2(node4); linkedList.add2(node2); linkedList.add2(node3); linkedList.list(); HeroNode newHeroNode = new HeroNode(4, "小林", "豹头~~"); linkedList.update(newHeroNode); // 显示 System.out.println("修改后的列表情况。。 "); linkedList.list(); System.out.println("删除后的列表情况。。 "); linkedList.delete(3); linkedList.list(); // 测试 System.out.println("有效的节点个数=" + getLength(linkedList.getHead())); } // 查找单链表的倒数第K个节点【新浪面试题】 /* * 思路:1.编写一个方法,接受head节点,同时接受index 2.index:表示倒数第index个节点 3.先把链表从头到尾遍历,得到链表的length * 4.得到size后,我们从链表第一个开始遍历(size-index),就可以得到 5.如果找到,返回该节点,否则返回空 */ public static HeroNode findLastIndexNode(HeroNode herd, int index) { // 判断如果链表为空 if (herd.next == null) { return null; } // 第一次遍历得到链表的长度(节点个数) int size = getLength(herd); // 第二次遍历 size-index 位置,就是倒数第k个节点 // 先做一个数据的校验 if (index <= 0|| index > size) { return null; } // 定义一个辅助变量 return null; } // 方法:获取到单链表的节点的个数(如果带头节点的链表,需求不统计节点) /** * @param node * 链表的头节点 * @return 有效节点的个数 */ public static int getLength(HeroNode node) { if (node.next == null) { // return 0; } int length = 0; // 定义一个辅助变量 HeroNode cur = node.next; while (cur != null) { length++; cur = cur.next; } return length; } } // 定义一个singleLinkedList管理我们的英雄 class SingleLinkedList { // 先初始化一个头节点,头节点不要动,不存放具体的数据 private HeroNode head = new HeroNode(0, "", ""); // 返回头节点 public HeroNode getHead() { return head; } // 添加节点到单向链表 /* * 思路:当不考虑编号的顺序时 1.找到当前链表的最后节点 2.将最后这个节点的next 指向新的节点 */ public void add(HeroNode heroNode) { // 因为head节点不能动,因此我们需要一个辅助变量 HeroNode temp = head; // 遍历链表 while (true) { // 找到链表的最后 if (temp.next == null) { // break; } // 如果没有找到最后,将temp后移 temp = temp.next; } // 当推出while循环时,temp就指向了链表的最后 // 最后的节点指向新的节点 temp.next = heroNode; } // 第二种方式在添加英雄时,根据排名将英雄插入到指定的位置 // (如果有这个排名,则添加失败,并给出提示) public void add2(HeroNode heroNode) { // 因为头节点不能动,因此通过辅助变量来帮助添加的位置 // 因为单链表,因此我们找的temp是位于添加位置的前一个节点,否则加入不了 HeroNode temp = head; boolean flag = false; // 标识添加的编号是否存在,默认为false while (true) { if (temp.next == null) {// 说明temp已经在链表的最后 break; } if (temp.next.no > heroNode.no) { // 位置找到,就在temp后面插入 break; } else if (temp.next.no == heroNode.no) { // 编号存在,希望添加的hero的编号已然存在 flag = true; break; } temp = temp.next; // 后移 遍历列表 } // 判断flag的值 if (flag) { System.out.printf("插入英雄的编号%d已存在\n", heroNode.no); } else { // 插入到链表中,temp的后面 heroNode.next = temp.next; temp.next = heroNode; } } // 修改节点的信息,根据no编号来修改,即no编号不能改。 public void update(HeroNode newHeroNode) { // 判断是否为空 if (head.next == null) { System.out.println("链表为空"); return; } // 找到需要修改的节点,根据no编号 // 定义一个辅助变量 HeroNode temp = head.next; boolean flag = false; // 表示是否找到该节点 while (true) { if (temp == null) { break; // 到链表的最后 } if (temp.no == newHeroNode.no) { // 找到 flag = true; break; } temp = temp.next; } // 根据flag 判断是否找到要修改的节点 if (flag) { temp.name = newHeroNode.name; temp.nickName = newHeroNode.nickName; } else { System.out.printf("没有找到编号%d节点,不能修改\n", newHeroNode.no); } } // 删除节点 // 思路 /* * 1.head 不能动,因此我们需要辅助节点确定位置 2.说明我们在比较时 , 是temp.next.no 和徐娅萍删除的no比较 */ public void delete(int no) { HeroNode temp = head; // 找到是否找到待输出节点的前一个节点 boolean flag = false; while (true) { if (temp.next == null) { break; } if (temp.next.no == no) { // 找到待删除节点的前一个节点temp flag = true; break; } temp = temp.next; } if (flag) { temp.next = temp.next.next; } else { System.out.printf("没有找到编号%d节点,不能删除\n", no); } } // 显示链表 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 = 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 public String toString() { return "HeroNode [no=" + no + ", name=" + name + ", nickName=" + nickName + "]"; } }
相关文章推荐
- java的数据结构与算法(7)单项链表之百度面试题
- 数据结构与算法(Java描述)-4、单链表以及单链表的应用
- 数据结构与算法(java)——链表
- java数据结构与算法-有序链表
- Java数据结构与算法中级篇之栈、队列、链表
- 数据结构与算法Java(一) 数组与链表
- java单项环形链表,优化约瑟夫环
- 数据结构与算法 ---- 线性表 及Java实现 顺序表、链表、栈、队列
- java的数据结构与算法(8)双向链表
- Java 版本的单项链表插入
- java单项链表反转
- java实现单项链表以及如何检测回环
- java数据结构与算法-用链表实现栈
- 数据结构与算法(3)---Java语言实现:栈的单链表定义
- Java实现两个有序的单项链表的合并
- 删除一个单项链表的最中间的元素,要求时间尽可能短(不能使用两次循环)java
- 数据结构与算法(1)---Java语言实现:线性表的单链表定义
- 数据结构与算法之链表2---单向链表(Java版)
- java数据结构与算法-双端链表实现队列
- 数据结构与算法 ---- 线性表 及Java实现 顺序表、链表、栈、队列