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 }