数据结构之单项链表的操作
以下是自己敲的小demo,方便日后复习时候用.主要实现了对有头结点的单向链表的
增加,删除,修改,更新以及反转链表,倒叙输出,查找有效节点数,查找倒数第K个节点的
一些操作,如有冗余,欢迎指正.
package com.ebiz.list; import java.util.Stack; /** * @author YHj * @create 2019-07-14 16:57 */ public class SingleListDemo { public static void main(String[] args) { //创建节点 HeroNode heroNode01 = new HeroNode(1, "宋江", "及时雨"); HeroNode heroNode02 = new HeroNode(2, "卢俊义", "玉麒麟"); HeroNode heroNode03 = new HeroNode(3, "无用", "智多星"); HeroNode heroNode04 = new HeroNode(4, "林冲", "豹子头"); //创建链表 SingleList singleList = new SingleList(); //添加节点并按照英雄编号排序 singleList.addById(heroNode01); singleList.addById(heroNode04); singleList.addById(heroNode02); singleList.addById(heroNode03); //遍历节点 singleList.list(singleList); System.out.println("修改节点----------------------------------------------------"); //修改节点 singleList.update(new HeroNode(2, "卢俊义111", "玉麒麟111")); //遍历节点 singleList.list(singleList); //System.out.println("------------------------------------------------------"); //删除节点 //singleList.delete(5); //遍历节点 //singleList.list(); System.out.println("倒数第k个节点---------------------------------------------------"); System.out.println(SingleList.getDaoHeroNode(singleList,4)); System.out.println("链表倒叙----------------------------------------------------------"); singleList.reverseList(singleList); System.out.println("从尾到头打印单链表 不是反转,会破坏数据结构 采用stack--------------"); singleList.reverseStack(singleList); } } //管理节点的类 即链表 class SingleList { //初始化头结点 private static HeroNode headhero = new HeroNode(0, "", ""); //新增一个节点 public void add(HeroNode heroNode) { //临时节点 HeroNode temp = headhero; //找到最后一个节点 while (true) { if (temp.next == null) { break; } temp = temp.next; } //while循环退出,找到最后一个节点 temp.next = heroNode; } //遍历节点 public void list(SingleList singleList) { //判断是否为空 if (null == singleList.headhero.next) { System.out.println("链表为空"); } //临时节点 HeroNode temp = headhero.next; while (true) { if (null == temp) { break; } System.out.println("temp = " + temp); temp = temp.next; } } //按照英雄编号来插入 从小到大 public void addById(HeroNode heroNode) { //临时节点 HeroNode temp = headhero; //boolean 判断链表中是否已经存在 boolean isExist = false; while (true) { if (null == temp.next) { break; } if (temp.next.no > heroNode.no) { break; } if (temp.next.no == heroNode.no) { isExist = true; break; } temp = temp.next; } if (isExist) { System.out.println("该英雄已存在!"); } else { heroNode.next = temp.next; temp.next = heroNode; } } //修改对应节点 public void update(HeroNode heroNode) { //临时节点 HeroNode temp = headhero; //boolean 判断链表中是否存在对应节点 boolean isExist = false; while (true) { if (null == temp) { break; } if (temp.no == heroNode.no) { isExist = true; break; } temp = temp.next; } if (isExist) { temp.name = heroNode.name; temp.nickname = heroNode.nickname; } else { System.out.println("没有对应英雄!!!"); } } //删除节点 public void delete(int no) { //临时节点 HeroNode temp = headhero; //boolean 判断链表中是否存在对应节点 boolean isExist = false; while (true) { if (null == temp) { break; } if (temp.next.no == no) { isExist = true; break; } temp = temp.next; } if (isExist) { temp.next = temp.next.next; } else { System.out.println("没有该节点!"); } } //获取节点个数,不包含头结点 public static int getCount(SingleList singleList){ if (null == singleList.headhero.next){ return 0; } //临时节点 HeroNode temp=singleList.headhero.next; int count=0; while (temp != null){ count++; temp=temp.next; } return count; } //获取倒数第k个节点 public static HeroNode getDaoHeroNode(SingleList singleList,int k){ //判断是否为空 if (null == singleList.headhero.next) { System.out.println("链表为空"); } //得到链表有效节点 int len=getCount(singleList); if (k<0 || k>len){ return null; } //倒数第k个节点的前一个节点 int s=len-k; if (s ==0 ){ return singleList.headhero.next; } //计数器,找到第s个节点 int count =0; HeroNode temp=singleList.headhero.next; while (true){ count++; if (count ==s){ break; } temp=temp.next; } return temp.next; } //链表反转并输出 头插法 public void reverseList(SingleList singleList){ if (0 == this.getCount(singleList) || 1 == this.getCount(singleList)){ System.out.println("该链表没有节点!"); return; } //临时节点 遍历原来的链表 HeroNode cur=singleList.headhero.next; //临时节点的下一个节点 HeroNode cur_next=null; //新链表的头结点 HeroNode newHead = new HeroNode(0, "", ""); while (cur != null){ cur_next=cur.next; //找到当前节点的下一个节点 cur.next=newHead.next; //将头节点的下一个节点给要插入的节点 newHead.next=cur; //要插入的节点给头结点的下一个节点 cur=cur_next; //将原来当前节点的下一个节点在赋值给临时节点,因为现在的临时节点在新的头结点上 } singleList.headhero.next=newHead.next; this.list(singleList); } //从尾到头打印单链表 不是反转,会破坏数据结构 采用stack public void reverseStack(SingleList singleList){ if (null == singleList.headhero.next){ System.out.println("链表为空"); return; } //定义临时节点 HeroNode temp=headhero.next; //定义栈 Stack<HeroNode> stack = new Stack<>(); while (null != temp){ stack.push(temp); temp=temp.next; } while (stack.size() > 0){ System.out.println(stack.pop()); } } } //节点类 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 + '\'' + '}'; } }