【算法与数据结构】单链表的增删改查、逆序打印与输出、合并有序链表

最近博主在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=神龟]
原文地址:https://www.cnblogs.com/DJames23/p/12819392.html