数据结构学习java(一点五)链式顺序表(链表)

java中没有将指针暴露给用户(以前做过看过一篇文章写有java中是有指针的,只是被藏起来了),所以得使用引用的方式。

何为引用请看下面这篇文章(写的很不错,当然肯定比我写的好):

https://www.cnblogs.com/huajiezh/p/5835618.html

链表中内部类和嵌套类的区别:

https://blog.csdn.net/WelcomeSpring/article/details/79430546

以下代码采用内部类。

 1  /**
 2      * 内部类
 3      * @param <E> 泛型
 4      */
 5     private class Node<E>{
 6         E data;
 7         Node<E> next;
 8         Node<E> pre;
 9         public Node(E data){
10             this.data=data;
11         }
12 
13      public Node(E data, Node next, Node pre) {
14          this.data = data;
15          this.next = next;
16          this.pre = pre;
17      }
18      public Node(){
19         next=null;
20         pre=null;
21         data=null;
22      }
23      public E getData() {
24          return data;
25      }
26 
27      public void setData(E data) {
28          this.data = data;
29      }
30 
31      public Node getNext() {
32          return next;
33      }
34 
35      public void setNext(Node next) {
36          this.next = next;
37      }
38 
39      public Node getPre() {
40          return pre;
41      }
42 
43      public void setPre(Node pre) {
44          this.pre = pre;
45      }
46  }

E data:存储对象的区域   Node<E> next:引用链表的下一个对象  Node<E> pre;引用链表的上一个对象 所构成了一个双链表

源代码:

  1 /**
  2  * @author 李正阳
  3  * @param <E> 泛型
  4  */
  5 public class MyLinkedList<E> implements List<E> {
  6 
  7     private Node<E> head=new Node<>();
  8     private int size=0;
  9 
 10     /**
 11      * 在链表的最后插入元素
 12      * @param data 插入的元素
 13      * @return true 插入成功
 14      */
 15     @Override
 16     public boolean add(E data) {
 17         Node<E> pNode= head;
 18         while (pNode.getNext()!=null){
 19             pNode=pNode.next;
 20         }
 21         Node<E> temp=new Node(data);
 22         temp.setPre(pNode);
 23         pNode.setNext(temp);
 24         size++;
 25         return true;
 26     }
 27 
 28     /**
 29      *在number位置添加一个元素
 30      * @param number 在链表中的位置(不是从0开始)
 31      * @return true 添加成功
 32      */
 33     @Override
 34     public boolean add(int number,E data){
 35         Node<E> pNode=head;
 36         Node<E> temp=new Node<>(data);
 37         for (int i=0;i<number;i++){
 38            pNode= pNode.getNext();
 39         }
 40         pNode.getPre().setNext(temp);
 41         temp.setPre(pNode.getPre());
 42         temp.setNext(pNode.getNext());
 43         pNode.getNext().setPre(temp);
 44         return true;
 45     }
 46     /**
 47      * 判空函数
 48      * @return true 链表为空 false 链表不为空
 49      */
 50     @Override
 51     public boolean isEmpty() {
 52         if(head.getNext()==null){
 53             return true;
 54         }else {
 55             return false;
 56         }
 57     }
 58 
 59     /**
 60      * 删除链表中number位置的元素
 61      * @param number 元素在链表中的位置
 62      * @return 删除的那个元素
 63      */
 64     @Override
 65     public E remove(int number) {
 66         E temp;
 67         Node<E> pNode,preNode;
 68         pNode=head;
 69         for(int i=0;i<number;i++){
 70             pNode=pNode.next;
 71         }
 72         temp=(E) pNode.getData();
 73         preNode=pNode.getPre();
 74         preNode.setNext(pNode.getNext());
 75         pNode.getNext().setPre(preNode);
 76         pNode.setNext(null);
 77         pNode.setPre(null);
 78         pNode=null;
 79         return temp;
 80     }
 81 
 82     /**
 83      * 尾删法
 84      * @return 删除的那个元素
 85      */
 86     @Override
 87     public E remove() {
 88         E temp;
 89         Node<E> pNode,preNode;
 90         pNode=head;
 91         while (pNode.getNext()!=null){
 92             pNode=pNode.next;
 93         }
 94         temp=(E) pNode.getData();
 95         preNode=pNode.getPre();
 96         preNode.setNext(null);
 97         pNode.setNext(null);
 98         pNode.setPre(null);
 99         pNode=null;
100         return temp;
101     }
102 
103     /**
104      * 将第i位置的元素替换
105      * @param i 元素在链表中的位置
106      * @param data 替换的元素
107      */
108     @Override
109     public void set(int i, E data) {
110         Node<E> pNode=head;
111         for (int j=0;j<i;j++){
112             pNode=pNode.getNext();
113         }
114         pNode.setData(data);
115     }
116 
117     /**
118      * 获得链表在i位置的元素
119      * @param i 元素在i位置的元素
120      * @return i位置的元素
121      */
122     @Override
123     public E get(int i) {
124         E temp;
125         Node<E> pNode=head;
126         for (int j=0;j<i;j++){
127             pNode=pNode.getNext();
128         }
129         temp=(E) pNode.getData();
130         return temp;
131     }
132 
133     /**
134      * 检查这条链表现有的是否为回文
135      * @return true 为回文 false 不为回文
136      */
137     @Override
138     public boolean isPalindrome() {
139         Node<E> pNode,nNode;
140         pNode=head.getNext();
141         nNode=head;
142         while (nNode.getNext()!=null){
143             nNode=nNode.getNext();
144         }
145        StringBuilder posSequence=new StringBuilder();
146         StringBuilder revOrder=new StringBuilder();
147         while(pNode.getNext()!=null) {
148             posSequence.append(pNode.getData());
149             pNode=pNode.getNext();
150         }
151         posSequence.append(pNode.getData());
152         while (nNode.getPre()!=null){
153             revOrder.append(nNode.getData());
154             nNode=nNode.getPre();
155         }
156        String posequence=posSequence.toString();
157         String revoredr=revOrder.toString();
158         if(posequence.equals(revoredr)) {
159             return true;
160         }else {
161             return false;
162         }
163     }
164 
165     /**
166      * 倒置链表
167      */
168     @Override
169     public void reverseList(){
170         Node<E> node,nNode;
171         node=head.getNext();
172         node.setPre(node.getNext());
173         node=node.getNext();
174         nNode=node.getNext();
175         head.getNext().setNext(null);
176         while (nNode!=null) {
177             node.setNext(node.getPre());
178             node.setPre(nNode);
179             node=node.getPre();
180             nNode=node.getNext();
181         }
182         node.setNext(node.getPre());
183         node.setPre(head);
184         head.setNext(node);
185     }
186     /**
187      * 头插法
188      * @param data 插入的元素
189      * @return true 添加成功 false 添加失败
190      */
191     @Override
192     public boolean addFirst(E data){
193         Node<E> node=new Node(data);
194         Node<E> preNode=head.getNext();
195         head.setNext(node);
196         preNode.setPre(node);
197         node.setNext(preNode);
198         node.setPre(head);
199         return true;
200     }
201 
202     /**
203      * 遍历并输出链表中的元素
204      */
205     @Override
206     public void traver() {
207         if(isEmpty()){
208             System.out.println("链表为空");
209         }else {
210             Node<E> pNode = head.getNext();
211             while (pNode != null) {
212                 System.out.print(pNode.getData() + " ");
213                 pNode = pNode.getNext();
214             }
215         }
216     }
217 
218     /**
219      * 内部类
220      * @param <E> 泛型
221      */
222     private class Node<E>{
223         E data;
224         Node<E> next;
225         Node<E> pre;
226         public Node(E data){
227             this.data=data;
228         }
229 
230      public Node(E data, Node next, Node pre) {
231          this.data = data;
232          this.next = next;
233          this.pre = pre;
234      }
235      public Node(){
236         next=null;
237         pre=null;
238         data=null;
239      }
240      public E getData() {
241          return data;
242      }
243 
244      public void setData(E data) {
245          this.data = data;
246      }
247 
248      public Node getNext() {
249          return next;
250      }
251 
252      public void setNext(Node next) {
253          this.next = next;
254      }
255 
256      public Node getPre() {
257          return pre;
258      }
259 
260      public void setPre(Node pre) {
261          this.pre = pre;
262      }
263  }
264 
265 }

检查链表所存储是否为回文:

 1     /**
 2      * 检查这条链表现有的是否为回文
 3      * @return true 为回文 false 不为回文
 4      */
 5     @Override
 6     public boolean isPalindrome() {
 7         Node<E> pNode,nNode;
 8         pNode=head.getNext();
 9         nNode=head;
10         while (nNode.getNext()!=null){
11             nNode=nNode.getNext();
12         }
13        StringBuilder posSequence=new StringBuilder();
14         StringBuilder revOrder=new StringBuilder();
15         while(pNode.getNext()!=null) {
16             posSequence.append(pNode.getData());
17             pNode=pNode.getNext();
18         }
19         posSequence.append(pNode.getData());
20         while (nNode.getPre()!=null){
21             revOrder.append(nNode.getData());
22             nNode=nNode.getPre();
23         }
24        String posequence=posSequence.toString();
25         String revoredr=revOrder.toString();
26         if(posequence.equals(revoredr)) {
27             return true;
28         }else {
29             return false;
30         }
31     }
* 算法设计:比较粗暴,直接从链表头到尾将值组成一个String
* 从链表尾到头将值组成一个String
* 然后比较这两个字符串是否相等
链表倒置:
 1   /**
 2      * 倒置链表
 3      * 算法设计
 4      */
 5     @Override
 6     public void reverseList(){
 7         Node<E> node,nNode;
 8         node=head.getNext();
 9         node.setPre(node.getNext());
10         node=node.getNext();
11         nNode=node.getNext();
12         head.getNext().setNext(null);
13         while (nNode!=null) {
14             node.setNext(node.getPre());
15             node.setPre(nNode);
16             node=node.getPre();
17             nNode=node.getNext();
18         }
19         node.setNext(node.getPre());
20         node.setPre(head);
21         head.setNext(node);
22     }
* 算法设计:倒置链表需要修改三处地方,
* 头结点变成尾节点:将pre赋值尾next的引用,next赋值为null
* 尾节点变成头结点:将next赋值为pre,pre赋值为null
* 中间节点将next设置为pre,next设置为pre


 

posted @ 2019-02-14 19:32  dark_Souls  阅读(425)  评论(0编辑  收藏  举报