单链表

 最近在恶补数据结构和算法,我看的书是《java数据结构与算法 第二版》,我也会在博客上记录我的学习过程。

《java数据结构与算法 第二版》书中把冗长的代码中重要的代码独立出来讲解,我觉得这种方式很好,阅读简单,思路清晰,能看清各个模块之间的关系。今天我会用这种庖丁解牛的方式一步步实现单链表数据结构。

Link类

 1 public class Link {
 2    public int data1;//数据1
 3    public String data2;//数据2
 4    public Link next;//指向下一个链结点
 5    //构造函数  初始化
 6    public Link(int d1,String d2){
 7        this.data1=d1;
 8        this.data2=d2;
 9        //next 会被自动赋值为null,意味着这个字段不指向任何结点
10    }
11    public void displayLink(){
12        System.out.println("数据1:"+data1+","+"数据2:"+data2);
13    }
14 }

LinkList类

定义了对链表中对第一个节点的引用,叫做first。从first出发,沿着链表中每个链结点的next字段,就可以找到其他链结点

 1 class LinkList{
 2     
 3     private Link first;
 4     //构造函数
 5     public LinkList(){
 6         first=null;//虽然first成员变量会被自动赋值为null,但是为了让我们的代码更加易读,在这里强调下first是怎么开始运作的
 7     }
 8     //用来判断first是否为空
 9     public boolean isEmpty(){
10         return (first==null);
11     }
12     
13 }

insertFirst()

作用是在表头插入一个新的结点。只需要使新创建的结点的next指向原来first的值,然后改变first的值,让它指向新的结点。如图所示

 

1 public void insertFirst(int d1,String d2){
2         //创建一个新结点
3         Link newLink=new Link(d1,d2);
4         newLink.next=first;
5         first=newLink;
6     }

 find(key)

查找结点,一个叫current的变量开始时指向first,然后不断赋值为current.next,沿着链表移动,直到它找到与传进来的key相等的值,返回该结点的引用。如果没有找到对应的值,则返回null

 1     public Link find(int key){
 2         Link current=first;//指向第一个结点
 3         while (current.data1!=key){
 4             if(current.next==null){
 5                 return null;//到达链表尾部返回null
 6             }else{
 7                 current=current.next;//没找到移到下一个结点
 8             }
 9         }
10         return current;
11     }

deleteFirst()

删除表头,如图

1     public Link deleteFirst(){
2         Link temp =first;
3         first=first.next;
4         return temp;   
5     }

delete(key)

删除方法和find()方法类似。先找到要删除的结点,同时获得指向前一个结点的引用和指向后一个结点的引用(即要删除结点的next),然后修改前一个结点的引用,使它指向后一个结点。

 1     public Link delete(int key){
 2         Link current=first;
 3         Link previous=first;
 4         while(current.data1!=key){
 5             if(current.next==null){
 6                 return null;//到达链表尾部没有找到数据
 7             }else{
 8                 previous=current;//前一个继续向下移动
 9                 current=current.next;//当前向下移动
10             }
11         }
12         //如果找到了跳出循环
13         if(current==first){
14             first=first.next;//如果找到的是第一个,则删掉表头,指向下一个结点
15         }else{
16             previous.next=current.next;
17         }
18         return current;//返回被删除的结点 Ps:被删除的结点其实还在内存中的某个地方,但是已经没有任何引用指向它了,在java中,GC会在某个时刻销毁它,不用我们操心
19     }

 displayList()

为了显示链表,从first开始,沿着引用链从一个结点到下一个结点

1     public void displayList(){
2         System.out.println("开始打印链表");
3         Link current=first;
4         while(current!=null){
5             current.displayLink();
6             current=current.next;
7         }
8         System.out.println("结束");
9     }

下面给出完整的代码

 1 public class Link {
 2    public int data1;//数据1
 3    public String data2;//数据2
 4    public Link next;//指向下一个链结点
 5    //构造函数  初始化
 6    public Link(int d1,String d2){
 7        this.data1=d1;
 8        this.data2=d2;
 9        //next 会被自动赋值为null
10    }
11    public void displayLink(){
12        System.out.println("数据1:"+data1+","+"数据2:"+data2);
13    }
14 }
15 class LinkList{
16     
17     private Link first;
18     //构造函数
19     public LinkList(){
20         first=null;//虽然first成员变量会被自动赋值为null,但是为了让我们的代码更加易读,在这里强调下first是怎么开始运作的
21     }
22     //用来判断first是否为空
23     public boolean isEmpty(){
24         return (first==null);
25     }
26     public void insertFirst(int d1,String d2){
27         //创建一个新结点
28         Link newLink=new Link(d1,d2);
29         newLink.next=first;
30         first=newLink;
31     }
32     public Link find(int key){
33         Link current=first;//指向第一个结点
34         while (current.data1!=key){
35             if(current.next==null){
36                 return null;//到达链表尾部返回null
37             }else{
38                 current=current.next;//没找到移到下一个结点
39             }
40         }
41         return current;
42     }
43     public Link delete(int key){
44         Link current=first;
45         Link previous=first;
46         while(current.data1!=key){
47             if(current.next==null){
48                 return null;//到达链表尾部没有找到数据
49             }else{
50                 previous=current;//前一个继续向下移动
51                 current=current.next;//当前向下移动
52             }
53         }
54         //如果找到了跳出循环
55         if(current==first){
56             first=first.next;//如果找到的是第一个,则删掉表头,指向下一个结点
57         }else{
58             previous.next=current.next;
59         }
60         return current;//返回被删除的结点
61     }
62     public Link deleteFirst(){
63         Link temp =first;
64         first=first.next;
65         return temp;    
66     }
67     public void displayList(){
68         System.out.println("开始打印链表");
69         Link current=first;
70         while(current!=null){
71             current.displayLink();
72             current=current.next;
73         }
74         System.out.println("结束");
75     }
76     
77 }

Test类

 1 public class Test {
 2     public static void main(String[] args) {
 3         LinkList linkList=new LinkList();
 4             linkList.insertFirst(1, "老王");
 5             linkList.insertFirst(2, "小明");
 6             linkList.insertFirst(3, "萌妹");//插入3个数据
 7             linkList.displayList();
 8             linkList.deleteFirst();//删除表头
 9             linkList.displayList();
10             linkList.find(1).displayLink();//查找key为1的数据
11             linkList.displayList();
12             linkList.delete(1).displayLink();//删除key为1的数据
13             linkList.displayList();
14     }
15 }
开始打印链表
数据1:3,数据2:萌妹
数据1:2,数据2:小明
数据1:1,数据2:老王
结束
开始打印链表
数据1:2,数据2:小明
数据1:1,数据2:老王
结束
数据1:1,数据2:老王
开始打印链表
数据1:2,数据2:小明
数据1:1,数据2:老王
结束
数据1:1,数据2:老王
开始打印链表
数据1:2,数据2:小明
结束

 

posted @ 2017-03-17 23:30  一只会编程的猫  阅读(206)  评论(0编辑  收藏  举报