1 public class simpleLinkListDemo {
2 public static void main(String[] args) {
3
4 MySimpleLinkList simpleLinkList=new MySimpleLinkList();
5
6 simpleLinkList.addAndOrder(new HeroNode(1,"张三"));
7 simpleLinkList.addAndOrder(new HeroNode(3,"王五"));
8 simpleLinkList.addAndOrder(new HeroNode(4,"赵六"));
9 simpleLinkList.addAndOrder(new HeroNode(2,"李四"));
10 simpleLinkList.update(new HeroNode(4,"李芳亮"));
11 simpleLinkList.delete(new HeroNode(2,"李四"));
12 simpleLinkList.showAllNode();
13
14 }
15 }
16
17 class MySimpleLinkList{
18 //头节点 是链表的开始 不存放数据 只存放下一个节点
19 private HeroNode head=new HeroNode();
20
21 public HeroNode getHead() {
22 return head;
23 }
24
25 //添加节点方法
26 public void add(HeroNode node){
27 //临时节点 先从头节点开始遍历
28 HeroNode tempNode=head;
29 while (true){
30 //如果下一个节点为空 代表已是最后一个节点 将要添加的节点 插入最后即可
31 if(tempNode.nextNode==null){
32 tempNode.nextNode=node;
33 break;
34 }else {
35 //临时节点后移
36 tempNode=tempNode.nextNode;
37 }
38 }
39 }
40
41 //添加节点 并且根据节点内的编号进行排序
42 public void addAndOrder(HeroNode heroNode){
43 //临时节点从头节点开始
44 HeroNode tempNode=head;
45 while (true){
46 //如果当前节点的下一个节点为空 代表已到链表尾部 直接添加
47 if(tempNode.nextNode==null) {
48 tempNode.nextNode = heroNode;
49 break;
50 //如果当前节点id等于要添加的节点id 代表已存在给出提示
51 }else if(tempNode.id==heroNode.id) {
52 System.out.println("当前要添加的id为"+heroNode.id+"已经存在");
53 break;
54 //如果当前节点的下一个节点的id大于要添加的节点
55 //说明要添加的节点id大小处于当前节点和下一个节点之间 直接插入中间即可
56 }else if(tempNode.nextNode.id>heroNode.id){
57 //要添加的节点的下一个节点等于当前节点的下一个节点
58 heroNode.nextNode=tempNode.nextNode;
59 //当前节点的下一个节点 等于当前节点 这就实现了将当前节点插入至两个节点之间
60 tempNode.nextNode=heroNode;
61 break;
62 }
63 //以上条件不满足 临时节点继续后移
64 tempNode=tempNode.nextNode;
65 }
66
67 }
68
69 //修改节点 根据id修改 所以id不能修改
70 public void update(HeroNode heroNode){
71 //从头节点的下一个节点开始遍历
72 HeroNode tempNode=head.nextNode;
73 while (true){
74 //临时节点为空 代表链表已到最后 或者为空 结束循环
75 if(tempNode==null){
76 break;
77 //临时节点的id==要修改的节点id 进行修改
78 }else if(tempNode.id==heroNode.id) {
79 tempNode.name=heroNode.name;
80 break;
81 //以上条件不成立 临时节点后移 继续遍历
82 }else{
83 tempNode=tempNode.nextNode;
84 }
85 }
86 }
87
88 //删除节点
89 public void delete(HeroNode heroNode){
90 //临时节点等于头节点
91 HeroNode tempNode=head;
92 while (true){
93 //下一个节点为空 结束循环
94 if(tempNode.nextNode==null){
95 break;
96 }else if(tempNode.nextNode.id==heroNode.id){
97 tempNode.nextNode=tempNode.nextNode.nextNode;
98 break;
99 }else{
100 tempNode=tempNode.nextNode;
101 }
102 }
103
104 }
105
106 //打印所有节点
107 public void showAllNode(){
108 //临时节点 获得头节点的下一个节点 因为头节点不存储数据
109 HeroNode tempNode=head.nextNode;
110 //节点为空就结束循环 否则打印当前节点 然后临时节点等于下一个节点
111 while (true){
112 if(tempNode==null){
113 break;
114 }
115 System.out.println(tempNode);
116 tempNode=tempNode.nextNode;
117 }
118 }
119
120 /**
121 * @Description: 获得链表长度
122 * @Author: Tan
123 * @Date: 2019/10/11
124 * @param head: 当前链表的头节点
125 * @return: int
126 **/
127 public int getLength(HeroNode head){
128 HeroNode tempNode=head.nextNode;
129 int length=0;
130 while (tempNode!=null){
131 length++;
132 tempNode=tempNode.nextNode;
133 }
134 return length;
135 }
136
137 /**
138 * @Description: 查找倒数的第N个节点 (新浪面试题)
139 * @Author: Tan
140 * @Date: 2019/10/11
141 * @param index: 倒数节点的位置
142 * @return: com.tqq.HeroNode
143 **/
144 public HeroNode getLastIndexNode(int index){
145 //获得链表长度
146 int size=getLength(head);
147 //长度为0 链表为空 直接返回
148 if(size==0){
149 return null;
150 }
151 //倒数位置不能小于0 大于总长度
152 if(index<0||index>size){
153 return null;
154 }
155 //记录循环次数
156 int count=0;
157 //头节点的下一个节点 就是链表的第一个节点
158 HeroNode tempNode=head.nextNode;
159 //链表长度-倒数位置 等于从头节点向后遍历的位置 比如链表长度4 要倒数第一个 4-1=3 就是倒数第一个
160 while (count!=size-index){
161 count++;
162 tempNode=tempNode.nextNode;
163 }
164 return tempNode;
165 }
166
167 /**
168 * @Description: 反转当前链表 (腾讯面试题)
169 * @Author: Tan
170 * @Date: 2019/10/13
171 * @return: void
172 * 这个反转链表就是 在弄一个头节点 用来记录反转以后的节点
173 * 遍历之前的链表 将每一个节点 插入到反转节点
174 * 最后将头节点的下一个节点指向已经反转排序好以后的节点
175 **/
176 public void reverse(){
177 //头节点下一个节点为空 代表链表为空 下下个节点为空 代表链表就一个元素 不需要反转
178 if(head.nextNode==null||head.nextNode.nextNode==null){
179 return ;
180 }
181 //遍历指针
182 HeroNode cur=head.nextNode;
183 //存储当前节点的下一个节点
184 HeroNode tempNode;
185 //反转头节点
186 HeroNode reverseHead=new HeroNode();
187 while (cur!=null){
188 //存储当前节点的下一个节点
189 tempNode=cur.nextNode;
190 //当前节点的下一个节点=反转头节点的下一个节点 相当于把当前节点加入到反转节点的第一个
191 cur.nextNode=reverseHead.nextNode;
192 //反转头节点的下一个节点=当前节点
193 reverseHead.nextNode=cur;
194 //指针后移
195 cur=tempNode;
196 }
197 //头节点的下一个节点 指向已经反转过的节点
198 head.nextNode=reverseHead.nextNode;
199 }
200
201
202
203 }
204
205
206 class HeroNode{
207 public int id;
208 public String name;
209 //存放着下一个节点
210 public HeroNode nextNode;
211 public HeroNode(int id,String name){
212 this.id=id;
213 this.name=name;
214 }
215
216 public HeroNode(){
217 }
218
219 @Override
220 public String toString() {
221 return "HeroNode{" +
222 "id=" + id +
223 ", name='" + name + '\'' +
224 '}';
225 }
226 }