单向链表的简单实现

Posted 9527yzx

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了单向链表的简单实现相关的知识,希望对你有一定的参考价值。

一、概念

  单向链表是一种简单数据结构,由多个节点构成,每个节点里面保存了节点中的数据和指向下一个节点的引用,链表的第一个节点被称为根节点(root)或头节点(head)

  技术分享图片

 二、使用Java实现基本结构

  需要一个Node类和一个Link类,Node类中存放Node中保存的数据和下一个Node的指向,Link类中保存root节点。

 1 class Node {
 2     private String data;
 3     private Node next;
 4     public Node(String data) {
 5         this.data = data;
 6     }
 7     public String getData(){
 8         return data;
 9     }
10     public void setNext(Node node) {
11         this.next = node;
12     }
13     public Node getNext() {
14         return next;
15     }
16     public void addNode(Node newNode){    //增加节点
17         if(this.next == null){
18             this.next = newNode;
19         }else{
20             //当前节点不为空,则用当前节点的下一个去继续保存
21             this.next.addNode(newNode);
22         }
23     }
24     public void printNode(){
25         System.out.println(this.data);
26         if(this.next != null)
27             this.next.printNode();
28     }
29 }
30 class List {    
31     private Node root;
32     public void add(String data){    //增加数据
33         Node newNode = new Node(data);
34         if( this.root == null){
35             this.root = newNode;
36         }else{
37             this.root.addNode(newNode);
38         }
39     }
40 }

  以上代码实现了链表的基本结构,和Link中的add()(以String对象为例子)方法,但是上面代码中Node类可以直接被外部访问,我们希望外部对链表的操作都通过Link类进行,Node类对外部隐藏,可以使用内部类来实现。

  1 class Link{
  2     private class Node{
  3         private String data;        //节点中要保存的数据
  4         private Node next;            //设置指向下一个节点
  5         public Node(String data){    //构造方法保存数据
  6             this.data = data;
  7         }
  8         public void addNode(Node newNode){        //将新节点添加到已有节点后
  9             if(this.next == null){                //判断当前节点是否为最后一个节点
 10                 this.next = newNode;            //如果是最后一个节点,则用当前节点指向新节点
 11             }else{
 12                 this.next.addNode(newNode);        //否则向后继续保存
 13             }
 14         }
 15         public boolean containsNode(String data){    //查询节点
 16             if(data.equals(this.data)){                //找到内容,返回true
 17                 return true;
 18             }else {
 19                 if (this.next != null){                //存在后续节点,继续 查找
 20                     this.next.containsNode(data);
 21                 }else{
 22                     return false;                    //不存在后续节点,没找到
 23                 }
 24             }
 25                 return false;                        
 26         }
 27         public String getNode(int index){        //根据索引查询节点
 28             //将节点编号与索引进行比较,相等则返回当前节点中的数据,不相等则找下一个编号
 29             if(Link.this.foot++ == index){        
 30                 return this.data;
 31             }else{
 32                 return this.next.getNode(index);
 33             }
 34         }
 35         public void setNode(int index , String data){        //根据索引修改Node的内容
 36             if(Link.this.foot ++ == index){                    //找到对象Node
 37                 this.data = data;            //修改data的值
 38             }else{
 39                 this.next.setNode(index, data);            //继续判断下一个节点
 40             }
 41         }
 42         public void removeNode(Node previous, String data){
 43             if(data.equals(this.data)){
 44                 previous.next = this.next;
 45             }else{
 46                 this.next.removeNode(this,data);
 47             }
 48         }
 49         public void toArrayNode(){        //将节点中数据转换成数组中的值
 50             Link.this.refArray[Link.this.foot++] = this.data;
 51             if(this.next != null){        //存在后续节点继续存放
 52                 this.next.toArrayNode();
 53             }
 54         }
 55         
 56     }
 57     //==========================上面为Node节点=================
 58     private Node root;    //定义链表中的根节点
 59     private int count = 0;    //统计节点个数
 60     private int foot = 0;    //表示Node元素编号
 61     private String[] refArray;        //对象数组,用来存放各个节点的值
 62     public void add(String data){        //链表中添加数据
 63         if(data == null){                //为了简便,暂且设置不保存null值
 64             return ;
 65         }
 66         Node newNode = new Node(data);    //实例化一个Node节点来保存数据
 67         if(this.root == null){            //判断是否存在root节点
 68             this.root = newNode;        //不存在则将当前节点设置为root节点
 69         }else{
 70             this.root.addNode(newNode);    //存在root节点则将新节点添加到链表后面
 71         }
 72         this.count ++ ;                    //保存成功count++
 73 
 74     }
 75     public int size(){        //取得节点个数
 76         return this.count;
 77     }
 78     public boolean isEmpty(){    //判断空链表
 79         //return this.count == 0;
 80         return this.root == null;
 81     }
 82     public boolean contains(String data){        //查找数据
 83         if(data == null || this.root == null){    //没有要查数据或根节点没保存数据
 84             return false ;
 85         }
 86         return this.root.containsNode(data);
 87     }
 88     public String get(int index){
 89         if(index > this.count){            //表示索引超出查询范围,没有数据
 90             return null;
 91         }
 92         this.foot = 0;                    //每次查询都是从前往后查找
 93         return this.root.getNode(index);
 94     }
 95     public void set(int index,String data){            //修改指定编号节点的内容
 96         if(index > this.count){
 97             return ;            //超出范围无法修改
 98         }
 99         this.foot = 0;                    //设置foot属性的内容
100         this.root.setNode(index,data);
101     }
102     public void remove(String data){        //移除指定数据
103         if(this.contains(data)){            //判断链表中是否存在指定数据
104             if(data.equals(this.root.data)){        //判断要删除的数据是否是root中数据
105                 this.root = this.root.next;            //移除root元素
106             }else{
107                 //继续判断下一个元素
108                 this.root.next.removeNode(this.root, data);
109             }
110         }
111         this.count--;            //删除一个节点,链表长度减一
112     }
113     public String[] toArray(){
114         if(this.root == null){
115             return null;
116         }
117         this.foot = 0;        //初始化root
118         this.refArray = new String[this.count];
119         this.root.toArrayNode();        //调用Node类中方法将每个节点数据添加到数组
120         return refArray;
121     }
122 }

  以上代码将Node类作为Link类的内部类来实现单向链表,

  public void add(String data){}:向链表中添加数据,需要为Link增加一个Node,这里将Node添加到Link的最后,每成功增加一个数据,count自增记录Link中Node的个数;

  public int size(){}:统计Link中Node元素的个数;

  public boolean isEmpty(){}:判断空链表,有两种判断方式,一种是判断root节点是否为空,另一种是判断节点个数是否为0;

  public boolean contains(String data){}:查找Link中是否存在指定数据,从root节点开始一次判断每个Node中的数据是否符合;

  public String get(int index){}:根据索引查找Link中对应的数据,索引从0开始;

  public void set(int index,String data){}:根据索引修改Link中对应的数据内容;

  public void remove(String data){}:根据指定内容移除Link中对应的Node,成功移除节点个数减1;

  public String[] toArray(){}:将Link转换成对象数组,数组长度为Link中Node的个数;

以上是关于单向链表的简单实现的主要内容,如果未能解决你的问题,请参考以下文章

简单的单向链表的java实现

单向链表的创建及其简单功能的实现

C语言反转单向链表的代码

单向链表的简单实现

单向链表的Java实现

数据结构和算法--链表一之单向链表的简单实现