最近博主在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=神龟]