算法与数据结构单链表的增删改查逆序打印与输出合并有序链表
Posted djames23
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了算法与数据结构单链表的增删改查逆序打印与输出合并有序链表相关的知识,希望对你有一定的参考价值。
最近博主在B站学习算法与数据结构,视频链接:
https://www.bilibili.com/video/BV1E4411H73v?p=23
这是一道课后练习,题目是:合并两个有序的单链表,使合并后的链表依然有序。
代码如下,合并部分的代码是mergeTwoSingleLinkedList:
1 import java.util.Stack; 2 3 public class SingleLinkedListDemo{ 4 5 public static void main(String[] args){ 6 boolean flag = false; // true=直接添加 7 HeroNode player1 = new HeroNode(23,"詹姆斯","King"); 8 HeroNode player2 = new HeroNode(24,"科比","黑曼巴"); 9 HeroNode player3 = new HeroNode(2,"韦德","闪电侠"); 10 HeroNode player4 = new HeroNode(3,"戴维斯","浓眉"); 11 12 HeroNode newPlayer1 = new HeroNode(14,"丹尼格林","皇阿玛"); 13 HeroNode newPlayer2 = new HeroNode(32,"麦基","囧哥"); 14 HeroNode newPlayer3 = new HeroNode(34,"阿德托昆博","字母哥"); 15 HeroNode newPlayer4 = new HeroNode(0,"维斯布鲁克","神龟"); 16 SingleLinkedList singleLinkedList = new SingleLinkedList(); 17 SingleLinkedList newsingleLinkedList = new SingleLinkedList(); 18 if (flag) { 19 singleLinkedList.add(player1); 20 singleLinkedList.add(player2); 21 singleLinkedList.add(player3); 22 singleLinkedList.add(player4); 23 System.out.println("直接添加后的链表情况:"); 24 singleLinkedList.list(); 25 System.out.println(" "); 26 }else { 27 singleLinkedList.addByOrder(player1); 28 singleLinkedList.addByOrder(player2); 29 singleLinkedList.addByOrder(player3); 30 singleLinkedList.addByOrder(player4); 31 System.out.println("链表1排序后的链表情况:"); 32 singleLinkedList.list(); 33 newsingleLinkedList.addByOrder(newPlayer1); 34 newsingleLinkedList.addByOrder(newPlayer2); 35 newsingleLinkedList.addByOrder(newPlayer3); 36 newsingleLinkedList.addByOrder(newPlayer4); 37 System.out.println("链表2排序后的链表情况:"); 38 newsingleLinkedList.list(); 39 } 40 //merge two singleLinkedList 41 System.out.println("合并两个有序链表并返回一个有序链接:"); 42 mergeTwoSingleLinkedList(singleLinkedList.getHead(),newsingleLinkedList.getHead()); 43 singleLinkedList.list(); 44 System.out.println("***************----------------***************"); 45 //update 46 HeroNode newPlayer = new HeroNode(2,"欧文","小王爷"); 47 singleLinkedList.update(newPlayer); 48 System.out.println("修改后的链表情况:"); 49 singleLinkedList.list(); 50 //delete 51 singleLinkedList.del(24); 52 System.out.println("删除后的链表情况:"); 53 singleLinkedList.list(); 54 //查找倒数第k个节点 55 HeroNode res = findLastIndexNode(singleLinkedList.getHead(),2); 56 System.out.println("倒数第k个节点res="+ res); 57 //求单链表有效节点的个数 58 System.out.println("有效的节点个数="+getLength(singleLinkedList.getHead())); 59 //逆序打印单链表,不改变链表结构 60 System.out.println("逆序打印单链表,不改变单链表的结构"); 61 reversePrint(singleLinkedList.getHead()); 62 System.out.println("原链表如下:"); 63 singleLinkedList.list(); 64 //反转单链表 65 System.out.println("反转单链表"); 66 reverseList(singleLinkedList.getHead()); 67 singleLinkedList.list(); 68 } 69 70 public static void mergeTwoSingleLinkedList(HeroNode head1, HeroNode head2){ 71 if (head1.next == null || head2.next == null){ 72 return;//若其中1个链表为空,不进行合并 73 } 74 HeroNode temp = head1; // 指向head1链表的头节点 75 HeroNode cur2 = head2.next; // 指向head2链表头节点的下一个节点 76 HeroNode next1 = null; //保存temp的下一个节点 77 HeroNode next2 = null; //保存cu2的下一个节点 78 while(cur2 != null){ 79 next2 = cur2.next; 80 while (temp.next != null){ 81 next1 = temp.next; 82 if (cur2.no <= temp.next.no){ //当cur2的no小于等于temp下一个节点的no时 83 cur2.next = temp.next; // 将cur2插入到head1中 84 temp.next = cur2; 85 break; 86 }else { 87 temp = next1; //将链表head1向后移,遍历head1 88 if(temp.next == null){// head1到最后时,将cur2添加到head1的末尾 89 temp.next = cur2; 90 cur2.next = null; 91 break; 92 } 93 } 94 } 95 cur2 = next2; //将head2向后移,重新遍历head1的整个链表 96 } 97 } 98 public static void reversePrint(HeroNode head){ 99 if (head.next == null){ 100 return; 101 } 102 Stack<HeroNode> stack = new Stack<HeroNode>(); 103 HeroNode cur = head.next; 104 while (cur != null){ 105 stack.push(cur); 106 cur = cur.next; 107 } 108 while (stack.size()>0){ 109 System.out.println(stack.pop()); 110 } 111 } 112 public static void reverseList(HeroNode head){ 113 if (head.next == null || head.next.next == null){ 114 return; 115 } 116 HeroNode cur = head.next; 117 HeroNode next = null; 118 HeroNode reverseHead = new HeroNode(0,"",""); 119 while (cur != null){ 120 next = cur.next; 121 cur.next = reverseHead.next; 122 reverseHead.next = cur; 123 cur = next; 124 } 125 head.next = reverseHead.next; 126 } 127 128 public static HeroNode findLastIndexNode(HeroNode head, int index){ 129 if(head.next == null){ 130 return null; 131 } 132 int size = getLength(head); 133 if(index <=0 || index > size){ 134 return null; 135 } 136 HeroNode cur = head.next; 137 for (int i=0;i<size-index;i++){ 138 cur = cur.next; 139 } 140 return cur; 141 142 } 143 public static int getLength(HeroNode head){ 144 if(head.next == null){ 145 return 0; 146 } 147 int length = 0; 148 HeroNode cur = head.next; 149 while (cur != null){ 150 length++; 151 cur = cur.next; 152 } 153 return length; 154 } 155 } 156 157 class SingleLinkedList{ 158 private HeroNode head = new HeroNode(0, "", ""); 159 public HeroNode getHead(){return head;} 160 161 public void add(HeroNode heroNode){ 162 HeroNode temp = head; 163 while(true){ 164 if(temp.next == null){ 165 break; 166 } 167 temp = temp.next; 168 } 169 temp.next = heroNode; 170 } 171 172 public void addByOrder(HeroNode heroNode){ 173 HeroNode temp = head; 174 boolean flag = false; 175 while(true){ 176 if(temp.next == null){ 177 break; 178 } 179 if(temp.next.no > heroNode.no){ 180 break; 181 }else if (temp.next.no == heroNode.no){ 182 flag = true; 183 break; 184 } 185 temp = temp.next; 186 } 187 if(flag){ 188 System.out.printf("准备插入的英雄编号%d已存在,不能加入",heroNode.no); 189 } else { 190 heroNode.next = temp.next; 191 temp.next = heroNode; 192 } 193 } 194 195 public void update(HeroNode newHeroNode){ 196 if(head.next == null){ 197 System.out.println("链表为空"); 198 return; 199 } 200 HeroNode temp = head.next; 201 boolean flag = false; 202 while (true){ 203 if (temp == null){ 204 break; 205 } 206 if(temp.no == newHeroNode.no){ 207 flag = true; 208 break; 209 } 210 temp = temp.next; 211 } 212 if (flag){ 213 temp.name = newHeroNode.name; 214 temp.nickname = newHeroNode.nickname; 215 }else { 216 System.out.printf("没有找到编号%d的节点,不能修改 ", newHeroNode.no); 217 } 218 } 219 220 public void del(int no){ 221 HeroNode temp = head; 222 boolean flag = false; 223 while (true){ 224 if (temp.next == null){ 225 System.out.println("已遍历完整个链表 "); 226 break; 227 } 228 if (no == temp.next.no){ 229 flag = true; 230 break; 231 } 232 temp = temp.next; 233 } 234 if(flag){ 235 temp.next = temp.next.next; 236 }else { 237 System.out.printf("要删除的节点%d不存在 ", no); 238 } 239 } 240 241 public void list(){ 242 if (head.next == null){ 243 System.out.println("链表为空"); 244 return; 245 } 246 HeroNode temp = head.next; 247 while (true){ 248 if (temp == null){ 249 break; 250 } 251 System.out.println(temp); 252 temp = temp.next; 253 } 254 } 255 } 256 257 class HeroNode{ 258 public int no; 259 public String name; 260 public String nickname; 261 public HeroNode next; 262 263 public HeroNode(int no, String name, String nickname){ 264 this.no = no; 265 this.name = name; 266 this.nickname = nickname; 267 } 268 @Override 269 public String toString(){ 270 return "HeroNode [no" + no +", name=" + name + ", nickname="+ nickname + "]"; 271 } 272 }
打印结果如下:
1 链表1排序后的链表情况: 2 HeroNode [no2, name=韦德, nickname=闪电侠] 3 HeroNode [no3, name=戴维斯, nickname=浓眉] 4 HeroNode [no23, name=詹姆斯, nickname=King] 5 HeroNode [no24, name=科比, nickname=黑曼巴] 6 链表2排序后的链表情况: 7 HeroNode [no0, name=维斯布鲁克, nickname=神龟] 8 HeroNode [no14, name=丹尼格林, nickname=皇阿玛] 9 HeroNode [no32, name=麦基, nickname=囧哥] 10 HeroNode [no34, name=阿德托昆博, nickname=字母哥] 11 合并两个有序链表并返回一个有序链接: 12 HeroNode [no0, name=维斯布鲁克, nickname=神龟] 13 HeroNode [no2, name=韦德, nickname=闪电侠] 14 HeroNode [no3, name=戴维斯, nickname=浓眉] 15 HeroNode [no14, name=丹尼格林, nickname=皇阿玛] 16 HeroNode [no23, name=詹姆斯, nickname=King] 17 HeroNode [no24, name=科比, nickname=黑曼巴] 18 HeroNode [no32, name=麦基, nickname=囧哥] 19 HeroNode [no34, name=阿德托昆博, nickname=字母哥] 20 ***************----------------*************** 21 修改后的链表情况: 22 HeroNode [no0, name=维斯布鲁克, nickname=神龟] 23 HeroNode [no2, name=欧文, nickname=小王爷] 24 HeroNode [no3, name=戴维斯, nickname=浓眉] 25 HeroNode [no14, name=丹尼格林, nickname=皇阿玛] 26 HeroNode [no23, name=詹姆斯, nickname=King] 27 HeroNode [no24, name=科比, nickname=黑曼巴] 28 HeroNode [no32, name=麦基, nickname=囧哥] 29 HeroNode [no34, name=阿德托昆博, nickname=字母哥] 30 删除后的链表情况: 31 HeroNode [no0, name=维斯布鲁克, nickname=神龟] 32 HeroNode [no2, name=欧文, nickname=小王爷] 33 HeroNode [no3, name=戴维斯, nickname=浓眉] 34 HeroNode [no14, name=丹尼格林, nickname=皇阿玛] 35 HeroNode [no23, name=詹姆斯, nickname=King] 36 HeroNode [no32, name=麦基, nickname=囧哥] 37 HeroNode [no34, name=阿德托昆博, nickname=字母哥] 38 倒数第k个节点res=HeroNode [no32, name=麦基, nickname=囧哥] 39 有效的节点个数=7 40 逆序打印单链表,不改变单链表的结构 41 HeroNode [no34, name=阿德托昆博, nickname=字母哥] 42 HeroNode [no32, name=麦基, nickname=囧哥] 43 HeroNode [no23, name=詹姆斯, nickname=King] 44 HeroNode [no14, name=丹尼格林, nickname=皇阿玛] 45 HeroNode [no3, name=戴维斯, nickname=浓眉] 46 HeroNode [no2, name=欧文, nickname=小王爷] 47 HeroNode [no0, name=维斯布鲁克, nickname=神龟] 48 原链表如下: 49 HeroNode [no0, name=维斯布鲁克, nickname=神龟] 50 HeroNode [no2, name=欧文, nickname=小王爷] 51 HeroNode [no3, name=戴维斯, nickname=浓眉] 52 HeroNode [no14, name=丹尼格林, nickname=皇阿玛] 53 HeroNode [no23, name=詹姆斯, nickname=King] 54 HeroNode [no32, name=麦基, nickname=囧哥] 55 HeroNode [no34, name=阿德托昆博, nickname=字母哥] 56 反转单链表 57 HeroNode [no34, name=阿德托昆博, nickname=字母哥] 58 HeroNode [no32, name=麦基, nickname=囧哥] 59 HeroNode [no23, name=詹姆斯, nickname=King] 60 HeroNode [no14, name=丹尼格林, nickname=皇阿玛] 61 HeroNode [no3, name=戴维斯, nickname=浓眉] 62 HeroNode [no2, name=欧文, nickname=小王爷] 63 HeroNode [no0, name=维斯布鲁克, nickname=神龟]
以上是关于算法与数据结构单链表的增删改查逆序打印与输出合并有序链表的主要内容,如果未能解决你的问题,请参考以下文章
java数据结构与算法:java代码模拟带头节点单向链表的业务
数据结构 线性结构(数组[列表] ,链表 单链表的增删改查**, 线性结构的应用 队列 栈[函数的调用**]),非线性结构 树