JAVA实现单链表

1,使用Node内部类来表示单链表的节点,这样就不需要为Node类的字段添加get方法和set方法就能访问这些字段,要知道内部类的这个用法。

2,public boolean deleteByElement(T element) 该方法删除链表中第一个元素值为element的元素。在该类结构下,这个方法实在是不好实现。

3,判断链表是否为空时,使用了断言,这样更能找到程序中的逻辑错误。如,链表为空,但 size 不为 0 的情况。

  1 public class LinkList<T> {
  2     private class Node{
  3         private T data;
  4         private Node next;
  5         private Node(){
  6             
  7         }
  8         private Node(T data, Node next){
  9             this.data = data;
 10             this.next = next;
 11         }
 12     }
 13     
 14     private Node header;//保存链表的头结点
 15     private Node tail;//保存链表的尾结点,采用尾插法添加结点时,不需要遍历整个链表
 16     private int size;//保存链表中已包含的节点数
 17     
 18     public LinkList(){
 19         header = tail = null;
 20     }
 21     public LinkList(T element){
 22         header = new Node(element, null);
 23         tail = header;
 24         size++;
 25     }
 26     
 27     public int length(){
 28         return size;
 29     }
 30     
 31     //获得索引为index处的元素值,注意:索引从0开始
 32     public T get(int index){
 33         return getNodeByIndex(index).data;
 34     }
 35     private Node getNodeByIndex(int index){
 36         if(index < 0 || index > size - 1)
 37             throw new IndexOutOfBoundsException("单链表越界");
 38         Node current = header;
 39         for(int i = 0; (i < size) && (current != null); i++, current = current.next)
 40             if(i == index)
 41                 return current;
 42         return null;
 43     }
 44     
 45     //返回链表中指定元素的索引,若指定元素不存在,返回-1
 46     public int locate(T element){
 47         Node current = header;
 48         for(int i = 0; i < size && current != null; i++, current = current.next)
 49             if(current.data.equals(element))
 50                 return i;
 51         return -1;
 52     }
 53 
 54     public void insert(T element, int index){
 55         if(index < 0 || index > size)
 56             throw new IndexOutOfBoundsException("单链表索引越界");
 57         if(header == null)//链表是空链表时
 58             add(element);
 59         else{
 60             if(index == 0)//在表头插入
 61                 addAtHeader(element);
 62             else{
 63                 Node prev = getNodeByIndex(index - 1);//获取插入结点的前驱
 64                 prev.next = new Node(element, prev.next);
 65                 size++;
 66             }
 67         }
 68     }
 69     
 70     //采用尾插法为链表增加新节点
 71     public void add(T element){
 72         if(header == null){
 73             header = new Node(element, null);
 74             tail = header;
 75         }
 76         else{
 77             Node newNode = new Node(element, null);
 78             tail.next = newNode;
 79             tail = newNode;
 80         }
 81         size++;
 82     }
 83     
 84     //采用头插法为链表增加新节点
 85     public void addAtHeader(T element){
 86         header = new Node(element, header);//新建的结点的next 需要指向 header结点
 87         if(tail == header)//如果插入之前是空链表
 88             tail = header;
 89         size++;
 90     }
 91     
 92     public T delete(int index){
 93         if(index < 0 || index > size - 1)
 94             throw new IndexOutOfBoundsException("链表索引越界");
 95         Node del;
 96         //待删除的是header节点
 97         if(index == 0){
 98             del = header;
 99             header = header.next;
100         }
101         else{
102             Node prev = getNodeByIndex(index - 1);//获取待删节点的前驱
103             del = prev.next;//del 指向待删除的节点
104             prev.next = del.next;
105         }
106         del.next = null;//将待删节点从链表中脱离出去
107         size--;
108         return del.data;
109     }
110     
111     //根据指定的元素来删除节点
112     public boolean deleteByElement(T element){
113         //链表为空
114         if(empty()){
115             return false;
116         }
117         //待删元素为第一个元素
118         else if(header.data.equals(element)){
119             Node del = header;
120             header = header.next;
121             if(tail == header)//说明整个链表中只有一个元素,tail也应当置null
122                 tail = null;
123             del.next = null;
124             size --;
125             return true;
126         }
127         //待删元素为链表中其他元素
128         else{
129             Node del = header.next;
130             Node prev = header;
131             while(del != null){
132                 if(del.data.equals(element)){
133                     if(tail == del)//如果待删元素是最后一个元素,需要将tail指针指向其前驱
134                         tail = prev;
135                     prev.next = del.next;
136                     del.next = null;
137                     size--;
138                     return true;
139                 }
140                 //若没有找到element,则继续下一轮的循环
141                 prev = del;
142                 del = del.next;
143             }
144             return false;
145         }
146     }
147     
148     //删除链表中的最后一个元素
149     public T remove(){
150         return delete(size - 1);
151     }
152     
153     //判断链表是否为空
154     public boolean empty(){
155         boolean result;
156         if(size == 0){
157             assert header == null;//当出现链表为空,但size不为0时,使用断言能够帮助找到逻辑错误
158             result = true;
159         }
160         else{
161             assert header != null;
162             result = false;
163         }
164         return result;
165         //return size == 0;
166     }
167     
168     //清空链表
169     public void clear(){
170         header = tail = null;
171         size = 0;
172     }
173     
174     public String toString(){
175         if(empty())
176             return "[]";
177         else{
178             StringBuilder sb = new StringBuilder("[");
179             for(Node current = header; current != null; current = current.next)
180                 sb.append(current.data.toString() + ", ");
181             int len = sb.length();
182             //注意删除最后添加的两个多余的字符
183             return sb.delete(len - 2, len).append("]").toString();
184         }
185     }
186 }

 

    原文作者:hapjin
    原文地址: https://www.cnblogs.com/hapjin/p/4448185.html
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞