链表

 

1.单链表

  (1)单链表的增、删、改、查、查找倒数第K个节点、链表反转

  1 package LianBiao;
  2 
  3 import java.util.Stack;
  4 
  5 /*
  6  * 单链表:头节点不存数据,只存下一节点地址
  7  * 编号唯一
  8  */
  9 public class LinkedListDemo1 {
 10     public static void main(String[] args){
 11         MyLinkedList1 t=new MyLinkedList1();
 12         
 13         t.addNodeByNo(1, "宋江", "及时雨");
 14         t.addNodeByNo(3, "吴用", "智多星");
 15         t.addNodeByNo(2, "卢俊义", "玉麒麟");
 16         t.addNodeByNo(4, "林冲", "豹子头");
 17         t.addNodeByNo(5, "武松", "行者");
 18         t.addNodeByNo(6, "鲁智深", "花和尚");
 19         t.show();
 20         System.out.println("-------------");
 21         //System.out.println("链表长度:"+t.getListLength());
 22         //System.out.println("-------------");
 23         //t.getLastNode(8);
 24         
 25         //t.reverseList();
 26         t.reverseList1();
 27     
 28         //t.findNodeByNo1(4);
 29         
 30         //t.findNodeByName1("宋江");
 31         //System.out.println("-----------------");
 32         //t.deleteNode1(5);
 33         //t.show();
 34         
 35     }
 36 
 37 }
 38 
 39 class Node1{
 40     
 41      int no;
 42      String name;
 43      String nickName;
 44      Node1 next;
 45     public Node1(int no, String name, String nickName, Node1 next) {
 46         this.no = no;
 47         this.name = name;
 48         this.nickName = nickName;
 49         this.next = next;
 50     }
 51     @Override
 52     public String toString() {
 53         return "座次: " + no + ", 姓名: " + name + ", 绰号: " + nickName;
 54     }
 55     @Override
 56     public int hashCode() {
 57         final int prime = 31;
 58         int result = 1;
 59         result = prime * result + ((name == null) ? 0 : name.hashCode());
 60         result = prime * result + ((next == null) ? 0 : next.hashCode());
 61         result = prime * result + ((nickName == null) ? 0 : nickName.hashCode());
 62         result = prime * result + no;
 63         return result;
 64     }
 65     @Override
 66     public boolean equals(Object obj) {
 67         if (this == obj)
 68             return true;
 69         if (obj == null)
 70             return false;
 71         if (getClass() != obj.getClass())
 72             return false;
 73         Node1 other = (Node1) obj;
 74         if (name == null) {
 75             if (other.name != null)
 76                 return false;
 77         } else if (!name.equals(other.name))
 78             return false;
 79         if (next == null) {
 80             if (other.next != null)
 81                 return false;
 82         } else if (!next.equals(other.next))
 83             return false;
 84         if (nickName == null) {
 85             if (other.nickName != null)
 86                 return false;
 87         } else if (!nickName.equals(other.nickName))
 88             return false;
 89         if (no != other.no)
 90             return false;
 91         return true;
 92     }
 93     
 94     
 95     
 96 }
 97 
 98 class MyLinkedList1{
 99     
100     Node1 head=new Node1(0,"","",null);
101     
102     
103     
104     //添加节点
105     public void addNode(int no, String name, String nickName){
106         Node1 temp=head;
107         //遍历整个链表,寻找尾节点
108         while(true){
109             if(temp.next==null){
110                 break;
111                 }else{
112                     temp=temp.next;
113                 }
114             }
115             
116             temp.next=new Node1(no,name,nickName,null);
117         }
118     
119     
120     
121     
122     //添加节点,使得添加进去的数据按照编号由小到大排序,这样取出来时直接就是排好的数据,不需要在遍历功能的代码里再想办法实现排序,有点类似set。
123     //同时保证编号的唯一性
124     public void addNodeByNo(int no, String name, String nickName){
125         Node1 temp=head;
126         boolean flag=false;
127         while(true){
128             if(temp.next==null){
129                 break;
130             }else{
131                 if(temp.next.no==no){
132                     flag=true;
133                     break;
134                 }else{
135                     if(temp.next.no>no){
136                         break;
137                     }else{
138                         temp=temp.next;
139                     }
140                 }
141             }
142         }
143         if(flag==true){
144             System.out.println("编号重复!!!");
145         }else{
146             temp.next=new Node1(no,name,nickName,temp.next);
147         }
148     }
149     
150     
151     
152     
153     //遍历整个链表:因为头节点只存下一节点的地址而不存数据,所以从头节点的下一个节点开始遍历
154     public void show(){
155         if(head.next==null){
156             System.out.println("链表为空!!!");
157         }else{
158            Node1 temp=head.next;//这里的指针指的是head.next
159            while(true){
160                if(temp==null){
161                    break;
162                }else{
163                    System.out.println(temp);
164                    temp=temp.next;
165                }
166            }
167         }
168     }
169     
170     
171     
172     
173     
174     //删除节点(根据编号删除)---成功实现,代码有点复杂,需要优化代码
175     public void deleteNode(int no){
176         if(head.next==null){
177             System.out.println("链表为空!!!");
178         }else{
179             Node1 temp=head;//这里的指针指的是head
180             while(true){
181                 if(temp.next==null){
182                     if(temp.no!=no){
183                     System.out.println("无此人!!!");
184                     break;
185                     }else{
186                         temp=null;
187                         break;
188                     }
189                 }else{
190                     if(temp.next.no==no){
191                         temp.next=temp.next.next;
192                         break;
193                     }else{
194                         temp=temp.next;
195                     }
196                 }
197             }
198         }
199     }
200     
201     
202     
203     
204     //优化:删除节点功能(根据编号删除)
205     
206     public void deleteNode1(int no){
207         if(head.next==null){
208             System.out.println("链表为空!!!");
209         }else{
210             boolean flag=false;;
211             Node1 temp=head;//这里的指针指的是head
212             while(true){
213                 if(temp.next==null){
214                     break;
215                 }else{
216                     if(temp.next.no==no){
217                         //temp.next=temp.next.next;
218                         flag=true;
219                         break;
220                     }else{
221                         temp=temp.next;
222                     }
223                 }
224             }
225             if(flag){
226                 temp.next=temp.next.next;
227             }else{
228                 System.out.println("无此人!!!");
229             }
230         }
231     }
232     
233     
234     
235     
236     //修改节点数据(根据编号修改)---成功实现,代码有点复杂,需要优化代码
237     public void modifyNode(int no,String name,String nickName){
238         if(head.next==null){
239             System.out.println("链表为空!!!");
240         }else{
241             Node1 temp=head.next;//这里的指针指的是head.next
242             while(true){
243                 if(temp.next==null){
244                     if(temp.no!=no){
245                         System.out.println("无此人!!!");
246                         break;
247                     }else{
248                         temp.name=name;
249                         temp.nickName=nickName;
250                         break;
251                     }
252                 }else{
253                     if(temp.no==no){
254                         temp.name=name;
255                         temp.nickName=nickName;
256                         break;
257                     }else{
258                         temp=temp.next;
259                     }
260                 }
261             }
262         }
263     }
264     
265     
266     //优化:修改节点数据(根据编号修改)
267     public void modifyNode1(int no,String name,String nickName){
268         if(head.next==null){
269             System.out.println("链表为空!!!");
270         }else{
271             boolean flag;//设置标志,用来表示是否找到相应数据
272             Node1 temp=head.next;//这里的指针指的是head.next
273             while(true){
274                 if(temp==null){
275                     flag=false;
276                 }else{
277                     if(temp.no==no){
278                         flag=true;
279                         break;
280                     }else{
281                         temp=temp.next;
282                     }
283                 }
284             }
285             
286             if(flag==true){
287                 temp.name=name;
288                 temp.nickName=nickName;
289             }else{
290                 System.out.println("无此人!!!");
291             }
292         }
293     }
294         
295     
296     
297     
298         //查询节点(根据编号:编号拥有唯一性)---成功实现,代码有点复杂,需要优化代码
299         public void findNodeByNo(int no){
300             if(head.next==null){
301                 System.out.println("链表为空!!!");
302             }else{
303                 Node1 temp=head.next;
304                 while(true){
305                     if(temp.next==null){
306                         if(temp.no==no){
307                             System.out.println(temp);
308                             break;
309                             
310                         }else{
311                             System.out.println("查无此人");
312                             break;
313                         }
314                     }else{
315                         if(temp.no==no){
316                             System.out.println(temp);
317                         }else{
318                             temp=temp.next;
319                         }
320                     }
321                 }
322                 
323             }
324             
325         }
326         
327         
328         
329         
330         //优化:查询节点(根据编号:编号拥有唯一性)
331         public void findNodeByNo1(int no){
332             if(head.next==null){
333                 System.out.println("链表为空!!!");
334             }else{
335                 Node1 temp=head.next;
336                 while(true){
337                     if(temp==null){
338                         System.out.println("查无此人");
339                         break;
340                     }else{
341                         if(temp.no==no){
342                             System.out.println(temp);
343                             break;
344                         }else{
345                             temp=temp.next;
346                         }
347                     }
348                 }
349                 
350             }
351             
352         }
353         
354         
355         
356         
357         
358         //查询节点(根据姓名,注:姓名不唯一)---成功实现,代码有点复杂,需要优化代码
359         
360         public void findNodeByName(String name){
361             int count=0;
362             if(head.next==null){
363                 System.out.println("链表为空!!!");
364             }else{
365                 Node1 temp=head.next;
366                 while(true){
367                 if(temp.next==null){
368                     if(temp.name.equals(name)){
369                         System.out.println(temp);
370                         count++;
371                         break;
372                    }else{
373                        break;
374                    }
375                 }else{
376                     if(temp.name.equals(name)){
377                         System.out.println(temp);
378                         count++;
379                         temp=temp.next;
380                     }else{
381                         temp=temp.next;
382                         }
383                             }
384                         }
385                 if(count==0){
386                     System.out.println("没有关于"+name+"的信息!!!");
387                 }
388                         
389                     }
390                     
391                 }
392                 
393         
394         
395         
396         
397         //查询节点(根据姓名,注:姓名不唯一)
398         public void findNodeByName1(String name){
399             if(head.next==null){
400                 System.out.println("链表为空!!!");
401             }else{
402                 boolean flag=false;//用来标识是否找到相应的数据
403                 Node1 temp=head.next;
404                 while(true){
405                 if(temp==null){
406                     break;
407                 }else{
408                     if(temp.name.equals(name)){
409                         flag=true;
410                         System.out.println(temp);
411                         temp=temp.next;
412                     }else{
413                         temp=temp.next;
414                         }
415                             }
416                         }
417                 if(flag==false){
418                     System.out.println("无此人!!!");
419                 }
420                         
421                     }
422             }
423         
424         
425         
426         
427         
428                 
429         //查询节点(根据绰号,绰号没有唯一性)---成功实现,代码有点复杂,需要优化代码
430         public void findNodeBynickName(String nickName){
431             int count=0;
432             if(head.next==null){
433                 System.out.println("链表为空!!!");
434               }else{
435                     Node1 temp=head.next;
436                     while(true){
437                     if(temp.next==null){
438                         if(temp.nickName.equals(nickName)){
439                             System.out.println(temp);
440                             count++;
441                             break;
442                         }else{
443                             break;
444                         }
445                     }else{
446                         if(temp.nickName.equals(nickName)){
447                             System.out.println(temp);
448                             count++;
449                             temp=temp.next;
450                         }else{
451                             temp=temp.next;
452                               }
453                          }
454                     }
455                         
456                 }
457             if(count==0){
458                 System.out.println("没有关于"+nickName+"的信息!!!");
459             }
460                     
461         }
462         
463         
464         
465         //优化:查询节点(根据绰号,绰号拥有唯一性)
466         public void findNodeBynickName1(String nickName){
467             if(head.next==null){
468                 System.out.println("链表为空!!!");
469               }else{
470                       boolean flag=false;//用来标识是否找到相应的数据
471                     Node1 temp=head.next;
472                     while(true){
473                     if(temp==null){
474                         break;
475                     }else{
476                         if(temp.nickName.equals(nickName)){
477                             flag=true;
478                             System.out.println(temp);
479                             temp=temp.next;
480                         }else{
481                             temp=temp.next;
482                               }
483                          }
484                     }
485                     
486                     if(flag==false){
487                         System.out.println("无此人!!!");
488                     }
489                         
490                 }
491             
492                     
493         }
494         
495         //获取链表中的有效节点个数
496         
497         public int getListLength(){
498             int count=0;
499             if(head.next==null){
500                 System.out.println("链表为空!!!");
501                 return 0;
502             }else{
503                 Node1 temp=head.next;
504                 while(true){
505                     if(temp!=null){
506                         count++;
507                         temp=temp.next;
508                     }else{
509                         break;
510                     }
511                 }
512                 //System.out.println("有效节点个数为:"+count);
513                 return count;
514             }
515         }
516         
517         
518         
519         //获取链表中倒数第k个节点
520         public void getLastNode(int index){
521             int size=getListLength();
522             if(index<1||index>size){
523                 System.out.println("超出范围");
524             }else{
525                 Node1 temp=head.next;
526                 for(int i=0;i<size-index;i++){
527                     temp=temp.next;
528                 }
529                 System.out.println("获取倒数第"+index+"节点:");
530                 System.out.println(temp);
531             }
532             
533         }
534         
535         
536         //反转链表(改变原链表的顺序,使其也为反向)
537         public void reverseList(){
538             MyLinkedList1 reverseList=new MyLinkedList1();
539             if(head.next==null){
540                 System.out.println("链表为空!!!");
541             }else{
542                 Node1 temp=head.next;
543                 Node1 save;
544                 Node1 header=new Node1(0,"","",null);
545                 while(true){
546                     if(temp==null){
547                         break;
548                     }else{
549                         save=temp.next;
550                         /*
551                         temp.next=temp;
552                         temp=save;    
553                         */
554                         temp.next=header.next;
555                         header.next=temp;
556                         temp=save;
557                     }
558                 }
559                 reverseList.head.next=header.next;
560                 reverseList.show();
561                 
562             }
563             
564 
565         }
566 
567         
568         //反转链表(不改变原链表的结构)---使用栈
569         public void reverseList1(){
570             if(head.next==null){
571                 System.out.println("链表为空!!!");
572             }else{
573                 //创建一个栈
574                 Stack stack=new Stack();
575                 int count=0;
576                 Node1 temp=head.next;//这里的指针指的是head.next
577                    while(true){
578                        if(temp==null){
579                            break;
580                        }else{
581                           stack.add(temp);
582                           count++;
583                            temp=temp.next;
584                        }
585                    }
586                    for(int i=0;i<count;i++){
587                       System.out.println( stack.pop());
588                    }
589             }
590         }
591         
592     
593     
594 }

  (2)链表排序

  1 package XianXingBiao;
  2 /*
  3  * 使用链表:
  4  * 未做完,比较大小部分有问题
  5  */
  6 import java.util.LinkedList;
  7 import java.util.List;
  8 
  9 public class PaiXuTest2 {
 10     public static void main(String[] args){
 11         int[] a={1,3,5,7,9};
 12         int[] b={2,6,8,10,12};
 13         NewLinkedList l1=new NewLinkedList();
 14         NewLinkedList l2=new NewLinkedList();
 15         
 16         for(int i=0;i<a.length;i++){
 17             l1.addNode(a[i]);;
 18         }
 19         
 20         for(int j=0;j<a.length;j++){
 21             l2.addNode(b[j]);
 22         }
 23         l1.showLink();
 24         l2.showLink();
 25         
 26         /*
 27         PaiXuTest2 t=new PaiXuTest2();
 28         t.paiXu1(l1, l2);
 29         */
 30         
 31         
 32         
 33         
 34         
 35         
 36         
 37     
 38     }
 39     
 40     //排序:未成功,结果里面有错误(一定要注意:若要操作某个节点,应当将指针指在它的前一个节点,和删除节点的道理一样)
 41         public void paiXu(NewLinkedList a,NewLinkedList b){
 42             System.out.println("排序如下:");
 43             Node ta=a.head.next;
 44             Node tb=b.head.next;
 45             Node temp;
 46             NewLinkedList c=new NewLinkedList();
 47             temp=c.head;
 48             
 49             while(ta.next!=null&&tb.next!=null){
 50                 if(ta.data<tb.data){
 51                     temp.next=ta;
 52                     ta=ta.next;
 53                     temp=temp.next;
 54                 }else{
 55                     temp.next=tb;
 56                     tb=tb.next;
 57                     temp=temp.next;
 58                 }
 59             }
 60             
 61             if(ta.next!=null){
 62                 temp.next=ta;
 63               }
 64             if(tb.next!=null){
 65                 temp.next=tb;
 66             }
 67             c.showLink();
 68             
 69             
 70         }
 71         
 72         //排序:成功(一定要注意:若要操作某个节点,应当将指针指在它的前一个节点,和删除节点的道理一样)
 73                 public void paiXu1(NewLinkedList a,NewLinkedList b){
 74                     System.out.println("排序如下:");
 75                     Node ta=a.head.next;
 76                     Node tb=b.head.next;
 77                     Node temp;
 78                     NewLinkedList c=new NewLinkedList();
 79                     temp=c.head;
 80                     
 81                     while(ta!=null&&tb!=null){
 82                         if(ta.data<tb.data){
 83                             temp.next=ta;
 84                             ta=ta.next;
 85                             temp=temp.next;
 86                         }else{
 87                             temp.next=tb;
 88                             tb=tb.next;
 89                             temp=temp.next;
 90                         }
 91                     }
 92                     
 93                     if(ta!=null){
 94                         temp.next=ta;
 95                       }
 96                     if(tb!=null){
 97                         temp.next=tb;
 98                     }
 99                     c.showLink();
100                     
101                     
102                 }
103 
104         
105         //运行结果为空,未查找问题,回头查找问题
106         public void paiXu2(NewLinkedList a,NewLinkedList b){
107             System.out.println("排序如下:");
108             Node ta=a.head.next;
109             Node tb=b.head.next;
110             Node temp;
111             NewLinkedList c=new NewLinkedList();
112             temp=c.head.next;
113             //c.head.next=temp;
114             while(ta!=null&&tb!=null){
115                 if(ta.data<tb.data){
116                     System.out.println("--------------------");
117                     temp=ta;
118                     System.out.println(c.head.next);
119                     System.out.println("temp=ta="+temp);
120                     System.out.println("temp.next=ta.next"+temp.next);
121                     ta=ta.next;
122                     //System.out.println("ta-->"+ta);
123                     temp=temp.next;
124                     System.out.println("temp:"+temp);
125                     System.out.println("--------------------");
126                 }else{
127                     System.out.println("**********");
128                     temp=tb;
129                     System.out.println("temp=tb="+temp);
130                     System.out.println("temp.next=tb.next"+temp.next);
131                     //System.out.println("tb"+tb);
132                     tb=tb.next;
133                     //System.out.println("tb.next"+tb.next);
134                     temp=temp.next;
135                     System.out.println("temp:"+temp);
136                     System.out.println("**********");
137                     
138                 }
139             }
140             
141             if(ta!=null){
142                 temp=ta;
143                 System.out.println("--------"+temp);
144               }
145             if(tb!=null){
146                 temp=tb;
147                 System.out.println("*******"+temp);
148             }
149             System.out.println(c.head.next);
150             c.showLink();
151             
152             
153         }
154         
155         
156         
157         
158 }
159 
160 class Node{
161     int data;
162     Node next;
163 
164     public Node(){
165         
166     }
167     
168     public Node(int data,Node next){
169         this.data=data;
170         this.next=next;
171     }
172 
173     @Override
174     public String toString() {
175         return " " + data ;
176     }
177 
178     
179     
180     
181 }
182 
183 class NewLinkedList{
184     
185     Node head=new Node(-1,null);
186     
187     //增加节点
188     public void addNode(int data){
189         
190             Node temp=head;
191             while(true){
192                 if(temp.next==null){
193                     temp.next=new Node(data,null);
194                     break;
195                 }else{
196                     temp=temp.next;
197                 }
198             }
199         }
200     
201     
202     //遍历链表:因为头节点只存下一节点的地址而不存数据,所以从头节点的下一个节点开始遍历
203     public void showLink(){
204         if(head.next==null){
205             System.out.println("链表为空!!!");
206         }else{
207             Node temp=head.next;
208             while(true){
209                 if(temp.next==null){ //最后一个节点,打印后直接跳出循环
210                     System.out.print(temp);
211                     break;
212                 }else{
213                     System.out.print(temp+",");
214                     temp=temp.next;
215                 }
216             }
217         }
218         System.out.println();
219     }
220     
221     
222     
223     /*
224     //排序:
225     public  static void paiXu(NewLinkedList a,NewLinkedList b){
226         System.out.println("排序如下:");
227         Node ta=new Node(-1,null);
228         Node tb=new Node(-1,null);
229         Node temp=new Node(-1,null);
230         NewLinkedList c=null;
231         c.head=temp;
232         ta=a.head.next;
233         tb=b.head.next;
234         
235         {
236             if(ta.data<tb.data){
237                 temp.next=ta;
238                 temp=temp.next;
239                 ta=ta.next;
240             }else{
241                 temp.next=tb;
242                 temp=temp.next;
243                 tb=tb.next;
244                 
245             }
246         }while(ta.next==null&&tb.next ==null)
247         
248         
249             
250         if(ta.next!=null){
251             temp.next=ta;
252           }
253         if(tb.next!=null){
254             temp.next=tb;
255         }
256         c.showLink();
257         
258         
259     }
260     
261     */
262     
263     
264     
265 }

 2.双向链表

2.1单向链表的缺点

  (1)查找方向只能是一个方向;

  (2)单向链表不能自我删除,所以单向链表删除节点时(记为B),只能先找到待删除节点的上一个节点(记为A),然后再让A.next指向B的下一个节点(记为C),即:A.next=A.next.next,完成删除B的任务,最后B会被垃圾回收机制回收;

 

  而双向链表可以弥补单链表的缺点:

  双向链表可以双向查找节点;双向链表可以进行自我删除

2.2 双向链表的增、删、改、查

 

  1 package LianBiao;
  2 /*
  3  * 双向链表的增删改查
  4  * 基本就是在单向链表的基础上做修改
  5  * 
  6  */
  7 public class DoubleLinkedListDemo {
  8     public static void main(String[] args){
  9         
 10         DoubleLinkedList dt=new DoubleLinkedList();
 11     
 12         dt.addNode(1, "宋江", "及时雨");
 13         dt.addNode(2, "卢俊义", "玉麒麟");
 14         dt.addNode(3, "吴用", "智多星");
 15         dt.addNode(4, "公孙胜", "入云龙");
 16         dt.addNode(5, "林冲", "豹子头");
 17         dt.addNode(6, "鲁智深", "花和尚");
 18         dt.addNode(7, "武松", "行者");
 19         dt.addNode(8, "李逵", "黑旋风");
 20         dt.addNode(9, "杨志", "青面兽");
 21         
 22         /*
 23         System.out.println("---------------------------");
 24         dt.show();
 25         System.out.println("---------------------------");
 26         dt.backShow();
 27         System.out.println("---------------------------");
 28         dt.showHeadTail();
 29         System.out.println("---------------------------");
 30         */
 31         
 32         //dt.findNodeDouble(5);
 33         //dt.deleteNodeDouble(8);
 34          dt.show();
 35          System.out.println("--------------------");
 36          dt.modifyNodeDouble(9, "刘备", "玄德");
 37         dt.show();
 38          System.out.println("dt.tail---->"+dt.tail);
 39     }
 40 
 41 }
 42 
 43 class HeroNode{
 44     int no;
 45     String name;
 46     String nickName;
 47     HeroNode next;
 48     HeroNode pre;
 49     
 50     
 51 
 52     public HeroNode(int no, String name, String nickName, HeroNode next, HeroNode pre) {
 53         super();
 54         this.no = no;
 55         this.name = name;
 56         this.nickName = nickName;
 57         this.next = next;
 58         this.pre = pre;
 59     }
 60 
 61 
 62 
 63     @Override
 64     public String toString() {
 65         return "座次: " + no + " 姓名: " + name + " 绰号: " + nickName;
 66     }
 67     
 68 }
 69 
 70 class DoubleLinkedList{
 71     
 72     HeroNode head=new HeroNode(-1,"","",null,null);
 73     HeroNode tail=new HeroNode(-1,"","",null,null);
 74     
 75     /*
 76      * 增加节点(默认加到尾部).和单向链表的方法基本一样,只是在末尾节点的指向上,使的添加节点的pre指向上一节点即可
 77      */
 78     public void addNode(int no,String name,String nickName){
 79         HeroNode temp=head;
 80         //遍历整个链表,寻找尾节点
 81         while(true){
 82             if(temp.next==null){
 83                 break;
 84                 }else{
 85                     temp=temp.next;
 86                 }
 87             }
 88             
 89             temp.next=new HeroNode(no,name,nickName,null,temp);
 90             tail=new HeroNode(no,name,nickName,null,temp);
 91         }
 92     
 93         
 94     
 95     
 96     
 97     //正向遍历
 98     
 99     public void show(){
100         System.out.println("****************"+tail);
101         if(head.next==null){
102             System.out.println("链表为空!!!");
103         }else{
104             HeroNode temp=head.next;
105             while(true){
106                 if(temp==null){
107                     break;
108                 }else{
109                     System.out.println(temp);
110                     temp=temp.next;
111                 }
112             }
113             
114         }
115     }
116     
117     
118     //反向遍历
119     public void backShow(){
120         long startTime=System.nanoTime();
121         if(tail==null){
122             System.out.println("链表为空");
123         }else{
124             HeroNode index=tail;
125             while(true){
126                 if(index==head){  
127                     break; //当尾节点=头节点时,遍历完毕,退出
128                 }else{
129                     System.out.println(index);
130                     index=index.pre;
131                 }
132             }
133             
134             long endTime=System.nanoTime();
135             System.out.println("运行耗时:"+(endTime-startTime));
136             
137         }
138     }
139     
140     
141     //双向遍历
142     public void showHeadTail(){
143         long startTime=System.nanoTime();
144         if(head.next==null){
145             System.out.println("链表为空!!!");
146         }else{
147             HeroNode temp=head.next;
148             HeroNode index=tail;
149             boolean flag=true;//true:单数;false:双数
150         while(true){
151             if(temp==index){
152                 flag=true;//单数
153                 break;
154             }
155             if(temp.next==index){
156                 flag=false;//双数
157                 break;
158             }
159             System.out.println(temp);
160             System.out.println(index);
161             temp=temp.next;
162             index=index.pre;
163             
164         }
165         
166         if(flag==true){
167             System.out.println(temp);
168         }else{
169             System.out.println(temp);
170             System.out.println(index);
171         }
172         
173         long endTime=System.nanoTime();
174         System.out.println("运行耗时:"+(endTime-startTime));
175     }
176 }
177     
178     //查找节点(单向正向查找)
179     public void findNode(int no){
180         if(head.next==null){
181             System.out.println("链表为空!!!");
182         }else{
183             HeroNode temp=head.next;
184             while(true){
185                 if(temp==null){
186                     System.out.println("查无此人");
187                     break;
188                 }else{
189                     if(temp.no==no){
190                         System.out.println(temp);
191                         break;
192                     }else{
193                         temp=temp.next;
194                     }
195                 }
196             }
197             
198         }
199     }
200     
201     //查找节点(双向查找)
202     public void findNodeDouble(int no){
203         if(head.next==null){
204             System.out.println("链表为空!!!");
205         }else{
206             
207             HeroNode temp=head.next;
208             HeroNode index=tail;
209             while(true){
210                 
211               if(temp==index){
212                   if(temp.no==no){
213                       System.out.println(temp);
214                       break;
215                   }else{
216 
217                   System.out.println("查无此人!!!");
218                   break;
219                   }
220               }
221               if(index.next==temp){
222                   System.out.println("查无此人!!!");
223                   break;
224               }
225                  
226 
227                   if(temp.no==no){
228                       System.out.println(temp);
229                       break;
230                   }
231                   if(index.no==no){
232                       System.out.println(index);
233                       break;
234                   }
235                   temp=temp.next;
236                   index=index.pre;
237                   
238               }
239            }
240         }
241     
242     
243     //删除节点(单向查找并删除)
244     public void deleteNode(int no){
245         if(head.next==null){
246             System.out.println("链表为空!!!");
247         }else{
248             HeroNode temp=head.next;//这里的指针指的是head
249             boolean flag=false;
250             while(true){
251                 if(temp==null){
252                     break;
253                 }else{
254                     if(temp.no==no){
255                         flag=true;
256                         break;
257                     }else{
258                         temp=temp.next;
259                     }
260                 }
261             }
262             if(flag){
263                 if(temp.next==null){
264                     temp.pre.next=temp.next;
265                 }else{
266                     temp.pre.next=temp.next;
267                     temp.next.pre=temp.pre;
268                 }
269             }else{
270                 System.out.println("无此人!!!");
271             }
272             
273         }
274     }
275     
276     
277     //删除节点(单向查找并删除)
278         public void deleteNode2(int no){
279             if(head.next==null){
280                 System.out.println("链表为空!!!");
281             }else{
282                 HeroNode temp=head.next;//这里的指针指的是head
283                 while(true){
284                     if(temp.next==null){
285                         if(temp.no==no){
286                             //tail=null;//删除不了最后一个节点
287                             temp.pre.next=null;
288                         
289                         }else{
290                             System.out.println("无此人!!!");
291                         }
292                         break;
293                     }else{
294                         if(temp.no==no){
295                             temp.pre.next=temp.next;
296                             temp.next.pre=temp.pre;
297                             break;
298                         }else{
299                             temp=temp.next;
300                         }
301                     }
302                 }
303                 
304                 
305             }
306         }
307         
308     
309     //删除节点(双向遍历)
310         public void deleteNodeDouble(int no){
311             if(head.next==null){
312                 System.out.println("链表为空!!!");
313             }else{
314                 HeroNode temp=head.next;
315                 HeroNode index=tail;
316                 /*
317                  * 1.判断是否删除的是最后一个节点
318                  * 2.while循环
319                  */
320                 if(tail.no==no){ 
321                     index.pre.next=null;//如果删除的是最后一个节点,则将其删除
322                 }else{
323                     //若不是,则执行循环
324                     while(true){
325                     if(temp==index){  //链表长度为单数,当前后指针相遇
326                           if(temp.no==no){//如果相遇的节点是需要删除的节点,则将其删掉
327                                temp.pre.next=temp.next;
328                                temp.next.pre=temp.pre;
329                            }else{
330                                //如果不是,则说明这条链表中没有找到符合删除条件的节点
331                                System.out.println("无此人!!!");
332                            }
333                                break;
334                       }
335                    if(index.next==temp){  //链表长度为双数时,若链表中没有符合删除条件的节点,则会出现这种情况,所以当出现这种情况,证明这条链表中没有找到符合删除条件的节点
336                          System.out.println("无此人!!!");
337                          break;
338                      }
339                    if(temp.no==no){
340                          temp.pre.next=temp.next;
341                          temp.next.pre=temp.pre;
342                              break;
343                       }else{
344                          temp=temp.next;
345                       }
346                    if(index.no==no){
347                        index.pre.next=index.next;
348                        index.next.pre=index.pre;
349                        break;
350                    }else{
351                        index=index.pre;
352                    }
353                     
354                 }
355                 
356              }
357             }
358         }
359         
360         
361         //修改某个节点(单向遍历)
362         public void modifyNode(int no,String name,String nickName){
363             
364         }
365         
366         //修改某个节点(双向遍历)
367         /*
368          * 存在一个问题:修改尾节点后,再进行单向正向遍历,发现尾节点是之前没有修改的,但是对尾节点进行打印发现是已经修改过的;而对其他节点的修改操作是成功的
369          * 而进行反向单向遍历以及双向遍历时,发现一切正常,修改功能可以正常实现
370          */
371         
372        public void modifyNodeDouble(int no,String name,String nickName){
373            if(head.next==null){
374                 System.out.println("链表为空!!!");
375             }else{
376                 HeroNode temp=head.next;
377                 HeroNode index=tail;
378                 while(true){
379                     if(temp==index){  //链表长度为单数,当前后指针相遇
380                           if(temp.no==no){//如果相遇的节点是需要修改的节点,则修改
381                                temp.name=name;
382                                temp.nickName=nickName;
383                            }else{
384                                //如果不是,则说明这条链表中没有找到符合条件的节点
385                                System.out.println("无此人!!!");
386                            }
387                                break;
388                       }
389                    if(index.next==temp){  //链表长度为双数时,若链表中没有符合条件的节点,则会出现这种情况,所以当出现这种情况,证明这条链表中没有找到符合条件的节点
390                          System.out.println("无此人!!!");
391                          break;
392                      }
393                    if(temp.no==no){
394                        temp.name=name;
395                        temp.nickName=nickName;
396                        break;
397                       }else{
398                          temp=temp.next;
399                       }
400                    if(index.no==no){
401                        index.name=name;
402                        index.nickName=nickName;
403                        break;
404                    }else{
405                       index=index.pre;
406                    }
407                     
408                 }
409                 System.out.println("打印尾节点----》"+tail);
410             }
411         }
412 
413 }

  问题:在modifyNodeDouble()方法中,如果修改的是尾节点,在使用show()正向单向遍历打印时,发现尾节点还是之前的那个,并未成功修改,而测试其他节点的修改时,发现可以修改成功;当使用backShow()反向单向遍历以及showHeadTail()双向遍历时,发现,所有位置的节点的修改功能都能成功实现。

  在main()方法,以及show()方法,还有modifyNodeDouble()方法中,对tail进行打印:

 

  main()方法中打印

 

             show()方法中打印

 

          modifyNodeDouble()方法中打印

  发现tail的值都是修改后的值,那么问题可能就出在正向单向遍历那里:可能是当show()方法中的temp指针移到倒数第二个节点时,temp.next指针指的不是tail,而是原来之前未修改时的节点。这样导致即使修改了尾节点,但是采用这种遍历方法,遍历后还是原来之前未修改的值。

  可是该如何解决这个问题???

3.单向环型链表及约瑟夫问题

  约瑟夫问题:

 

  1 package LianBiao;
  2 /*
  3  * 循环链表
  4  */
  5 public class CircleLinkedListDemo {
  6     public static void main(String[] args){
  7         
  8         ChildNode c1=new ChildNode(1,"佟湘玉");
  9         ChildNode c2=new ChildNode(2,"白展堂");
 10         ChildNode c3=new ChildNode(3,"郭芙蓉");
 11         ChildNode c4=new ChildNode(4,"吕秀才");
 12         ChildNode c5=new ChildNode(5,"李大嘴");
 13         ChildNode c6=new ChildNode(6,"莫小贝");
 14         ChildNode c7=new ChildNode(7,"老邢");
 15         ChildNode c8=new ChildNode(8,"燕小六");
 16         
 17         
 18         CircleLinkedList cl=new CircleLinkedList();
 19         cl.addNode(c1);
 20         cl.addNode(c2);
 21         cl.addNode(c3);
 22         cl.addNode(c4);
 23         cl.addNode(c5);
 24         cl.addNode(c6);
 25         cl.addNode(c7);
 26         cl.addNode(c8);
 27         cl.showNode();
 28         System.out.println("------------");
 29         cl.showByNum(1, 10);
 30         System.out.println("------------");
 31         cl.showNode();
 32     
 33         
 34     }
 35 
 36 }
 37 
 38 class ChildNode{
 39     int no;
 40     String name;
 41     ChildNode next;
 42     
 43     @Override
 44     public String toString() {
 45         return "no: " + no + ", name: " + name ;
 46     }
 47 
 48     public ChildNode(int no, String name) {
 49         super();
 50         this.no = no;
 51         this.name = name;
 52 
 53     }
 54     
 55     
 56     
 57 }
 58 
 59 class CircleLinkedList{
 60     ChildNode first=new ChildNode(-1,null);
 61     int num=0;//记录圈中成员个数
 62     
 63     
 64     //添加节点--成功实现
 65     public void addNode(ChildNode child){
 66      if(first.next==null){
 67          first=child;
 68          first.next=first;
 69          num++;
 70      }else{
 71          ChildNode temp=first;
 72          while(true){
 73             if(temp.next==first){
 74                 break;
 75             }else{
 76                 temp=temp.next;
 77             }
 78          }
 79          temp.next=child;
 80          child.next=first;
 81          num++;
 82         
 83      }
 84      
 85     }
 86     
 87     //遍历节点--成功实现
 88     public void showNode(){
 89         if(first.next==null){
 90             System.out.println("链表为空!!!");
 91         }else{
 92         ChildNode temp=first;
 93         while(true){
 94             if(temp.next==first){
 95                 System.out.println(temp);
 96                 break;
 97             }else{
 98                 System.out.println(temp);
 99                 temp=temp.next;
100             }
101           }
102         }
103     }
104     
105     //测试是否是环形链表--成功
106     public void showNodeTest(){
107         ChildNode temp=first;
108         while(true){
109             System.out.println(temp);
110             temp=temp.next;
111         }
112     }
113     
114     //约瑟夫问题--成功实现(存在的问题:运行完此功能后,原有链表结构被破坏)
115     /*
116      * @param startNo:表示从第几个人出数
117      * @param countNum:表示数几下
118      * @param total:表示圈中成员总数
119      */
120     public void showByNum(int startNo,int countNum){
121         System.out.println("出圈顺序为:");
122         int total=num;
123         ChildNode last;//last指针,用来指向first的上一个节点
124         if(first==null){
125             System.out.println("链表为空,请添加数据!!!");
126         }else{
127             if(startNo<1||startNo>total){
128                 System.out.println("非法输入!!!");
129             }else{
130                 
131                 //找到开始数的成员,将first指针移到此处,同时将last指针移到其后面
132                 ChildNode temp=first;
133                 while(true){
134                     if(temp.next.no==startNo){
135                         last=temp;
136                         first=temp.next;
137                         break;
138                     }else{
139                         temp=temp.next;
140                     }
141                 }
142                 
143                 //开始循环
144                 while(true){
145                     if(first.next==first){
146                         System.out.println(first);
147                         break;
148                     }else{
149                         for(int i=1;i<countNum;i++){
150                             first=first.next;
151                             last=last.next;
152                         }
153                         System.out.println(first);
154                         first=first.next;
155                         last.next=first;
156                     }
157                 }
158                 
159                 
160             }
161         }
162         
163     }
164 }

posted @ 2021-02-07 17:29  L1998  阅读(65)  评论(0)    收藏  举报