Java数据结构之单链表
2020-06-29 04:53
836 查看
Java单链表
1. 单链表的定义
- 链表是以节点的方式进行的链式存储;
- 每一个节点包含两个域分别为data域以及next域;
- data域用于存放数据,next域用于指向下一个节点;
- 链表中的每一个节点在逻辑上是连续的,而在实际中不一定连续,主要是依靠next域进行下一节点的查找;
- 链表分带有头结点的和没有头结点的,根据实际的需求来确定。
2.代码实现单链表的增加与遍历
这是单链表的节点的定义,为了方便访问数据,所以把属性都弄成了public。
no,name,nickname这三个属性都是节点的数据,next就是指向的下一个节点。重写toString方法是为了方便查看节点内的属性的值。
//定义一个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; } @Override public String toString() { return "HeroNode [no=" + no + ", name=" + name + ", nickname=" + nickname + "]"; } }
定义链表,其中有链表的增加方法,更新方法,删除方法,具体描述如代码内。
第一种添加:直接将节点插入链表尾部,不考虑顺序。
//添加节点到单向链表 //思路,当不考虑编号顺序时 //1.找到当前链表的最后一个节点 //2.将最后这个节点的next指向新的节点 public void add(HeroNode heroNode) { //因为head节点不能动,因此我们需要一个辅助变量temp HeroNode temp = head; //遍历链表,找到最后 while(true) { //找到链表的最后,即next为null的时候 if(temp.next == null) { break; } //如果没有找到最后,则temp指向下一个节点 temp = temp.next; } //当退出循环时,temp指向的是最后一个节点 //此时将最后一个节点的next指向新的节点 temp.next = heroNode; }
第二种添加:根据节点中no的大小将节点插入到指定位置。
思路:
1. 首先找到新添加的节点的位置,以引用传递的方式遍历链表;
2. 新的节点.next = temp.next;
3. 再将temp.next = 新的节点;
//顺序添加 public void sequenceAdd(HeroNode heroNode) { HeroNode temp = head; //用于标记是否找到 boolean flag = false; while(true) { //如果为空,表示要么是空链表要么是到达了链表的最后一个节点,此时跳出循环准备执行添加操作。 if(temp.next == null) { break; } //找到所要插入的节点的后一个位置 if(temp.next.no > heroNode.no) { break; } //判断如果节点的no相同,返回指定信息 if(temp.next.no == heroNode.no) { flag = true; break; } //当以上都没找到时,跳到下一个节点继续查询 temp = temp.next; } if(flag) { System.out.println("编号"+heroNode.no+"已经存在"); }else { //首先先将待插入的节点的next指向前一个节点的next heroNode.next = temp.next; //前一个结点的next指向该插入节点的本身,顺序不能更改。 temp.next = heroNode; } }
更新节点,思路:先遍历找到该节点,在进行更新。
//更新节点 public void updata(HeroNode newHreoHeroNode) { //该temp节点指向的不再是头节点了,而是头结点的下一个,也就是第一个数据节点 HeroNode temp = head.next; //标记位,判断是否找到节点 boolean flag = false; while(true) { if(temp == null) { break; } if(temp.no == newHreoHeroNode.no) { flag = true; break; } temp = temp.next; } if(flag) { temp.name = newHreoHeroNode.name; temp.nickname = newHreoHeroNode.nickname; }else { System.out.println("节点"+newHreoHeroNode.no+"没找到"); } }
删除节点,思路:
1. 找到要删除的节点temp
2. 令temp.next = temp.next.next;
3. 被删除的节点将不再有其他的引用指向
//删除节点,只是将节点的引用给改变了,有GC进行空节点的回收 public void delete(int no) { HeroNode temp = head; boolean flag = false; while(true) { if(temp.next == null) { break; } if(temp.next.no == no) { flag = true; break; } temp = temp.next; } if(flag) { temp.next = temp.next.next; }else { System.out.println("编号"+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; } } }
完整代码展示
package com.atguigu.linkedlist; public class SingleLinkedListDemo { public static void main(String[] args) { //测试,先创建头结点 ctrl + alt + 向下箭头,自动补齐ctrl+2 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 singleLinkedList1 = new SingleLinkedList(); //添加 // singleLinkedList.add(heroNode1); // singleLinkedList.add(heroNode2); // singleLinkedList.add(heroNode3); // singleLinkedList.add(heroNode4); //顺序添加 singleLinkedList1.sequenceAdd(heroNode1); singleLinkedList1.sequenceAdd(heroNode3); singleLinkedList1.sequenceAdd(heroNode2); singleLinkedList1.sequenceAdd(heroNode2); singleLinkedList1.sequenceAdd(heroNode4); //显示 System.out.println("更新前:"); singleLinkedList.list(); //更新 HeroNode heroNode = new HeroNode(3, "用哥", "智多星***"); singleLinkedList.updata(heroNode); System.out.println("更新后:"); singleLinkedList.list(); System.out.println("----------------------"); System.out.println("删除节点前:"); singleLinkedList1.list(); singleLinkedList1.delete(4); System.out.println("删除节点后:"); singleLinkedList1.list(); } } //定义SingleLinkedList来管理英雄 class SingleLinkedList{ //先初始化一个头结点,头节点不要动,不存放具体的数据 private HeroNode head = new HeroNode(0,"",""); //添加节点到单向链表 //思路,当不考虑编号顺序时 //1.找到当前链表的最后一个节点 //2.将最后这个节点的next指向新的节点 public void add(HeroNode heroNode) { //因为head节点不能动,因此我们需要一个辅助变量temp HeroNode temp = head; //遍历链表,找到最后 while(true) { //找到链表的最后,即next为null的时候 if(temp.next == null) { break; } //如果没有找到最后,则temp指向下一个节点 temp = temp.next; } //当退出循环时,temp指向的是最后一个节点 //此时将最后一个节点的next指向新的节点 temp.next = heroNode; } //顺序添加 public void sequenceAdd(HeroNode heroNode) { HeroNode temp = head; boolean flag = false; while(true) { if(temp.next == null) { break; } if(temp.next.no > heroNode.no) { break; } if(temp.next.no == heroNode.no) { flag = true; break; } temp = temp.next; } if(flag) { System.out.println("编号"+heroNode.no+"已经存在"); }else { heroNode.next = temp.next; temp.next = heroNode; } } //更新节点 public void updata(HeroNode newHreoHeroNode) { HeroNode temp = head.next; boolean flag = false; while(true) { if(temp == null) { break; } if(temp.no == newHreoHeroNode.no) { flag = true; break; } temp = temp.next; } if(flag) { temp.name = newHreoHeroNode.name; temp.nickname = newHreoHeroNode.nickname; }else { System.out.println("节点"+newHreoHeroNode.no+"没找到"); } } //删除节点 public void delete(int no) { HeroNode temp = head; boolean flag = false; while(true) { if(temp.next == null) { break; } if(temp.next.no == no) { flag = true; break; } temp = temp.next; } if(flag) { temp.next = temp.next.next; }else { System.out.println("编号"+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; } @Override public String toString() { return "HeroNode [no=" + no + ", name=" + name + ", nickname=" + nickname + "]"; } }
学习自尚硅谷Java数据结构与java算法,韩顺平数据结构与算法
相关文章推荐
- 数据结构之稀疏数组的实现
- Java集合中的数据结构栈
- Java集合中的数据结构单向队列
- Java集合中的数据结构双向队列
- java 数据结构JCF简介
- java 数据结构详解---list之ArrayList LinkedList Vector
- java 数据结构set 之HashSet TreeSet LinkedHashSet
- java 数据结构 map 之 HashMap LinkedHashMap TreeMap
- java 数据结构 Properties文件详解
- 动态规划 C++数据结构 01 背包问题
- 数据结构+算法
- Leetcode 211. 添加与搜索单词 - 数据结构设计 C++
- mooc大学浙大数据结构——最大子列和问题
- 数据结构——二叉树
- jdk1.8中HashMap的数据结构优化
- 数据结构上机题一:Life游戏 C++实现
- 数据结构上机题二:实现一个通用的循环队列C++
- 数据结构上机题三:实现一个循环链表类并解决约瑟夫问题
- 数据结构上机题四:滑雪问题
- 数据结构上机题五:有序链表