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 };
(注:本程序中,所有的关系都是通过用户手工进行设置的,如果要想让其真正变得有意义,则需要为其加入一个操作的封装。)
假设现在的节点操作有以下几种:增加数据,查找数据,删除数据。特别强调的是,如果要删除节点的话,则直接修改上一个节点的引用即可
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 };

浙公网安备 33010602011771号