1 package linkedlist; 2 3 import java.util.Stack; 4 5 public class SingleLinkedListDemo { 6 7 public static void main(String[] args) { 8 HeroNode hero1 = new HeroNode(1, "唐僧", "师傅"); 9 HeroNode hero2 = new HeroNode(2, "孙悟空", "大师兄"); 10 HeroNode hero3 = new HeroNode(3, "猪八戒", "二师兄"); 11 HeroNode hero4 = new HeroNode(4, "沙和尚", "三师弟"); 12 SingleLinedList singleLinedList = new SingleLinedList(); 13 14 // singleLinedList.add(hero1); 15 // singleLinedList.add(hero2); 16 // singleLinedList.add(hero3); 17 // singleLinedList.add(hero4); 18 19 singleLinedList.addByOrder(hero1); 20 singleLinedList.addByOrder(hero4); 21 singleLinedList.addByOrder(hero2); 22 singleLinedList.addByOrder(hero3); 23 singleLinedList.addByOrder(hero3); 24 //测试修改节点的代码 25 HeroNode newHeroNode = new HeroNode(2, "六耳猕猴", "假悟空"); 26 singleLinedList.update(newHeroNode); 27 // 删除一个节点 28 singleLinedList.del(2); 29 singleLinedList.del(3); 30 31 System.out.println("有效节点的个数"+getLength(singleLinedList.getHead())); 32 singleLinedList.list(); 33 HeroNode res=findLastIndexNode(singleLinedList.getHead(), 2); 34 System.out.println("res="+res); 35 36 //测试单链表反转 37 System.out.println("链表反转"); 38 reversesetList(singleLinedList.getHead()); 39 singleLinedList.list(); 40 System.out.println("逆序打印单链表"); 41 reversePrint(singleLinedList.getHead()); 42 43 } 44 45 public static int getLength(HeroNode head) { 46 if(head.next==null) { 47 //空链表 48 return 0; 49 } 50 int length =0; 51 //定义辅助变量,没有统计头节点 52 HeroNode cur=head.next; 53 while(cur!=null) { 54 length++; 55 cur=cur.next; 56 } 57 return length; 58 } 59 60 61 62 //查找单链表中的倒数第K个节点 63 public static HeroNode findLastIndexNode(HeroNode head,int index) { 64 if(head.next==null) { 65 return null; 66 } 67 int size=getLength(head); 68 if(index<=0||index>size) { 69 return null; 70 } 71 HeroNode cur=head.next; 72 for(int i=0;i<size-index;i++) { 73 cur=cur.next; 74 }return cur; 75 } 76 77 //将单链表反转 78 public static void reversesetList(HeroNode head) { 79 if(head.next==null||head.next.next==null) { 80 return ; 81 } 82 HeroNode cur=head.next; 83 HeroNode next=null;//指向当前节点的下一个节点 84 HeroNode reHeroNode=new HeroNode(0, "", ""); 85 while(cur!=null) { 86 next=cur.next; 87 cur.next=reHeroNode.next; 88 reHeroNode.next=cur; 89 cur=next; 90 } 91 head.next=reHeroNode.next; 92 93 94 } 95 public static void reversePrint(HeroNode head) { 96 if(head.next==null) { 97 return ; 98 } 99 Stack<HeroNode> stack=new Stack<HeroNode>(); 100 HeroNode cur=head.next; 101 while(cur!=null) { 102 stack.push(cur); 103 cur=cur.next; 104 } 105 while(stack.size()>0) { 106 System.out.println(stack.pop()); 107 } 108 } 109 } 110 111 112 113 //定义一个singleLinkedList 114 class SingleLinedList { 115 // 先初始化一个头节点,头节点不要动,不存放具体的数据 116 private HeroNode head = new HeroNode(0, "", ""); 117 //返回头节点 118 public HeroNode getHead() { 119 return head; 120 } 121 122 // 添加节点到单向链表 123 // 1.找到当前链表的最后 124 // 2.将最后这个节点的next指向新的节点 125 126 public void add(HeroNode heronode) { 127 // 因为head节点不能动,因此我们需要一个辅助遍历temp 128 HeroNode temp = head; 129 while (true) { 130 if (temp.next == null) { 131 break; 132 } 133 temp = temp.next; 134 } 135 temp.next = heronode; 136 } 137 138 139 140 141 142 // 第二种方式在添加英雄时,根据排名将英雄插入到指定位置 143 // (如果有这个排名,则添加失败,并给出提示) 144 public void addByOrder(HeroNode heroNode) { 145 HeroNode temp = head; 146 boolean flag = false;// 标志添加的编号是否存在,默认为false 147 while (true) { 148 if (temp.next == null) { 149 break; 150 } 151 if (temp.next.no > heroNode.no) {// 位置找到在temp的后面加入 152 break; 153 154 } else if (temp.next.no == heroNode.no) { 155 flag = true; 156 break; 157 } 158 temp = temp.next; 159 } 160 if (flag == true) { 161 System.out.println("准备插入的英雄编号" + heroNode.no + "已经存在"); 162 163 } else { 164 heroNode.next = temp.next; 165 temp.next = heroNode; 166 } 167 } 168 169 //根据编号修改节点的信息 170 public void update(HeroNode newHeroNode) { 171 172 if (head.next == null) { 173 System.out.println("链表为空~"); 174 return; 175 } 176 HeroNode temp = head.next; 177 boolean flag = false; 178 while (true) { 179 if (temp == null) { 180 break;// 已经遍历完列表 181 } 182 if (temp.no == newHeroNode.no) { 183 flag = true; 184 break; 185 } 186 temp = temp.next; 187 } 188 // 根据flag,判断是否找到要修改的节点 189 if (flag) { 190 temp.name = newHeroNode.name; 191 temp.nickname = newHeroNode.nickname; 192 } else { 193 System.out.println("没有找到编号为" + newHeroNode.no + "的节点,不能修改"); 194 } 195 196 } 197 198 public void del(int no) { 199 HeroNode temp = head; 200 boolean flag = false; 201 while (true) { 202 if (temp.next == null) { 203 break; 204 } 205 if (temp.next.no == no) { 206 flag = true; 207 break; 208 } 209 temp = temp.next; 210 } 211 if (flag) { 212 temp.next = temp.next.next; 213 } else { 214 System.out.println("要删除的节点" + no + "不存在"); 215 } 216 } 217 218 219 220 221 222 223 // 显示链表【遍历】 224 public void list() { 225 if (head.next == null) { 226 System.out.println("链表为空"); 227 return; 228 } 229 HeroNode temp = head.next; 230 while (true) { 231 if (temp == null) { 232 break; 233 } 234 System.out.println(temp); 235 temp = temp.next; 236 } 237 } 238 239 } 240 241 //定义HeroNode,每个HeroNode对象就是一个节点 242 class HeroNode { 243 public int no; 244 public String name; 245 public String nickname; 246 public HeroNode next;// 指向下一个节点 247 248 // 构造器 249 public HeroNode(int no, String name, String nickname) { 250 super(); 251 this.no = no; 252 this.name = name; 253 this.nickname = nickname; 254 } 255 256 // 重写toString 257 @Override 258 public String toString() { 259 return "HeroNode [no=" + no + ", name=" + name + ", nickname=" + nickname + "]"; 260 } 261 262 }