16 单向链表

所谓链表就好像火车车厢那样,从火车头开始,每一节车厢之后都连着后一节车厢

想要实现链表,则肯定要设计一个链表的节点类,在此类中必须有一个属性可以保存下一个节点的引用地址:

 1 class Node{        // 定义节点类
 2     private String data ;    // 保存节点内容
 3     private Node next ;        // 表示保存下一个节点
 4     public Node(String data){        // 通过构造设置节点内容
 5         this.data = data ;    // 设置内容
 6     }
 7     public void setNext(Node next){
 8         this.next = next ;        // 设置下一个节点
 9     }
10     public Node getNext(){    // 取得下一个节点
11         return this.next ;
12     }
13     public String getData(){
14         return this.data ;    // 取得节点的内容
15     }
16 };
17 public class LinkDemo01{
18     public static void main(String args[]){
19         Node root = new Node("火车头") ;  // 定义根节点
20         Node n1 = new Node("车厢-A") ;    // 定义第一个车厢(第一个节点)
21         Node n2 = new Node("车厢-B") ;    // 定义第二个车厢(第二个节点)
22         Node n3 = new Node("车厢-C") ;    // 定义第三个车厢(第三个节点)
23         root.setNext(n1) ;            // 设置火车头的下一个节点是第一个车厢A
24         n1.setNext(n2) ;            // 设置第一个车厢的下一个节点是第二个车厢
25         n2.setNext(n3) ;            // 设置第二个车厢的下一个节点是第三个车厢
26         printNode(root) ;            // 从头开始输出
27     }
28     public static void printNode(Node node){    // 输出节点
29         System.out.print(node.getData() + "\t") ;    // 输出节点的内容
30         if(node.getNext()!=null){        // 判断此节点是否存在下一个节点
31             printNode(node.getNext()) ;    // 向下继续输出
32         }
33     }
34 };
View Code

(注:本程序中,所有的关系都是通过用户手工进行设置的,如果要想让其真正变得有意义,则需要为其加入一个操作的封装。)

 

假设现在的节点操作有以下几种:增加数据,查找数据,删除数据。特别强调的是,如果要删除节点的话,则直接修改上一个节点的引用即可

 1 class Link{        // 链表的完成类
 2     class Node{    // 保存每一个节点,此处为了方便直接定义成内部类
 3         private String data ;    // 保存节点的内容
 4         private Node next ;        // 保存下一个节点
 5         public Node(String data){
 6             this.data = data ;        // 通过构造方法设置节点内容
 7         }
 8         public void add(Node newNode){        // 将节点加入到合适的位置
 9             if(this.next==null){            // 如果下一个节点为空,则把新节点设置在next的位置上
10                 this.next = newNode ;
11             }else{        // 如果不为空,则需要向下继续找next
12                 this.next.add(newNode) ;
13             }
14         }
15         public void print(){
16             System.out.print(this.data + "\t") ;    // 输出节点内容
17             if(this.next!=null){        // 还有下一个元素,需要继续输出
18                 this.next.print() ;    // 下一个节点继续调用print
19             }
20         }
21         public boolean search(String data){    // 内部搜索的方法
22             if(data.equals(this.data)){        // 判断输入的数据是否和当前节点的数据一致
23                 return true ;
24             }else{    // 向下继续判断
25                 if(this.next!=null){    // 下一个节点如果存在,则继续查找
26                     return this.next.search(data) ;    // 返回下一个的查询结果
27                 }else{
28                     return false ;        // 如果所有的节点都查询完之后,没有内容相等,则返回false
29                 }
30             }
31         }
32         public void delete(Node previous,String data){
33             if(data.equals(this.data)){    // 找到了匹配的节点
34                 previous.next = this.next ;    // 空出当前的节点
35             }else{
36                 if(this.next!=null){    // 还是存在下一个节点
37                     this.next.delete(this,data) ;    // 继续查找
38                 }
39             }
40         }
41     };
42     private Node root ;        // 链表中必然存在一个根节点
43     public void addNode(String data){    // 增加节点
44         Node newNode = new Node(data) ;    // 定义新的节点
45         if(this.root==null){            // 没有根节点
46             this.root = newNode ;    // 将第一个节点设置成根节点
47         }else{        // 不是根节点,放到最后一个节点之后
48             this.root.add(newNode) ;    // 通过Node自动安排此节点放的位置
49         }
50     }
51     public void printNode(){        // 输出全部的链表内容
52         if(this.root!=null){        // 如果根元素不为空
53             this.root.print() ;    // 调用Node类中的输出操作
54         }
55     }
56     public boolean contains(String name){    // 判断元素是否存在
57         return this.root.search(name) ;    // 调用Node类中的查找方法
58     }
59     public void deleteNode(String data){        // 删除节点
60         if(this.contains(data)){    // 判断节点是否存在
61             // 一定要判断此元素现在是不是根元素相等的
62             if(this.root.data.equals(data)){    // 内容是根节点
63                 this.root = this.root.next ;    // 修改根节点,将第一个节点设置成根节点
64             }else{
65                 this.root.next.delete(root,data) ;    // 把下一个节点的前节点和数据一起传入进去
66             }
67         }
68     }
69 };
70 public class LinkDemo02{
71     public static void main(String args[]){
72         Link l = new Link() ;
73         l.addNode("A") ;        // 增加节点
74         l.addNode("B") ;        // 增加节点
75         l.addNode("C") ;        // 增加节点
76         l.addNode("D") ;        // 增加节点
77         l.addNode("E") ;        // 增加节点
78         System.out.println("======= 删除之前 ========") ;
79         l.printNode() ;
80         // System.out.println(l.contains("X")) ;
81         l.deleteNode("C") ;        // 删除节点
82         l.deleteNode("D") ;        // 删除节点
83         l.deleteNode("A") ;        // 删除节点
84         System.out.println("\n====== 删除之后 =========") ;
85         l.printNode() ;
86         System.out.println("\n查询节点:" + l.contains("B")) ;
87     }
88 };
View Code

 

posted @ 2015-02-26 16:31  闲来垂钓  阅读(151)  评论(0)    收藏  举报