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

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=神龟]

 

以上是关于算法与数据结构单链表的增删改查逆序打印与输出合并有序链表的主要内容,如果未能解决你的问题,请参考以下文章

算法_链表篇

python实现单链表的增删改查

python实现单链表的增删改查

单链表的增删改查(进阶版)

java数据结构与算法:java代码模拟带头节点单向链表的业务

数据结构 线性结构(数组[列表] ,链表 单链表的增删改查**, 线性结构的应用 队列 栈[函数的调用**]),非线性结构 树