关于单链表的增删改查方法的递归实现(JAVA语言实现)

因为在学习数据结构,准备把java的集合框架底层源码,好好的过一遍,所以先按照自己的想法把单链表的类给写出来了;

写该类的目的:

1.练习递归

2.为深入理解java集合框架底层源码打好基础

学习的视频看的慕课网liuyubobo老师的课程:Java玩转数据结构 从入门到进阶

废话不多说,一下为源代码:

  1 public class LinkedList<E extends Comparable<E>> {
  2     //链表节点内部类
  3     private class Node{
  4         E e;
  5         Node next;
  6         public Node(E _e,Node _next){
  7             this.e = _e;
  8             this.next = _next;
  9         }
 10         public Node(E _e){
 11             this(_e, null);
 12         }
 13         public Node(){
 14             this(null, null);
 15         }
 16     }
 17     //头节点
 18     private Node head;
 19     //链表实际存储大小
 20     private int size;
 21     //无参构造函数
 22     public LinekedList(){
 23         this.head = null;
 24         this.size = 0;
 25     }
 26     //判断链表是否为空
 27     public boolean isEmpty(){
 28         return this.size == 0;
 29     }
 30     public int size(){
 31         return this.size;
 32     }
 33     //在链表头添加节点
 34     public void addFirst(E e){
 35         add(0, e);
 36     }
 37     //在链表尾添加节点
 38     public void addLast(E e){
 39         add(size, e);
 40     }
 41     //在链表指定位置添加节点
 42     public void add(int index,E e){
 43         if (index < 0 || index > size) {
 44             throw new IllegalArgumentException("Index is error.");
 45         }
 46         head = add(index, e, head);
 47     }
 48     //通过递归实现链表的添加
 49     private Node add(int index,E e,Node node){
 50         if (index == 0 && node == null) {
 51             this.size++;
 52             return new Node(e);
 53         }
 54         if (index == 0) {
 55             this.size++;
 56             Node newNode = new Node(e);
 57             //newNode.next = node.next;
 58             newNode.next = node;
 59             //node.next = newNode;
 60             return newNode;
 61         }
 62         node.next = add(index - 1, e, node.next);
 63         return node;
 64     }
 65     /**
 66      * 用于根据索引查找对应的节点,
 67      * @param index
 68      * @param node
 69      * @return 相应的节点对象
 70      */
 71     private Node getElementByIndex(int index,Node node){
 72         if (index == 0 && node != null) {
 73             return node;
 74         }
 75         Node ret = getElementByIndex(index - 1, node.next);
 76         return ret;
 77     }
 78     //删除链表头节点
 79     public E removeFirst(){
 80         return remove(0);
 81     }
 82     //删除链表尾结点
 83     public E removeLast(){
 84         return remove(size - 1);
 85     }
 86     //删除指定位置节点,并返回删除节点值
 87     public E remove(int index){
 88         if (isEmpty()) {
 89             throw new IllegalArgumentException("List is empty.");
 90         }
 91         if (index < 0 || index >= size) {
 92             throw new IllegalArgumentException("Index is error.");
 93         }
 94         Node ret = getElementByIndex(index, head);
 95         head = remove(index, head);
 96         return ret.e;
 97     }
 98     //递归删除节点值
 99     private Node remove(int index,Node node){
100         if (node == null) {
101             return node;
102         }
103         if (index == 0) {
104             Node delNode = node;
105             node = delNode.next;
106             delNode.next = null;
107             this.size--;
108             return node;
109         }
110         node.next = remove(index - 1, node.next);
111         return node;
112     }
113     //修改指定位置节点的值,通过递归实现
114     public void set(int index,E e){
115         if (isEmpty()) {
116             throw new IllegalArgumentException("List is empty.");
117         }
118         if (index < 0 || index >= size) {
119             throw new IllegalArgumentException("Index is error.");
120         }
121         set(index, e, head);
122     }
123     private void set(int index,E e,Node node){
124         if (node == null) {
125             return;
126         }
127         if (index == 0) {
128             node.e = e;
129         }
130         set(index - 1, e, node.next);
131         return;
132     }
133     //获取链表头节点的值
134     public E getFirst(){
135         return get(0);
136     }
137     //获取链表尾结点的值
138     public E getLast(){
139         return get(size - 1);
140     }
141     //获取链表制定位置的值,通过递归实现
142     public E get(int index){
143         if (isEmpty()) {
144             throw new IllegalArgumentException("List is empty.");
145         }
146         if (index < 0 || index >= size) {
147             throw new IllegalArgumentException("Index is error.");
148         }
149         return get(index, head).e;
150     }
151     private Node get(int index,Node node){
152         if (node == null) {
153             return node;
154         }
155         if (index == 0) {
156             return node;
157         }
158         Node ret = get(index - 1, node.next);
159         return ret;
160     }
161     //查询链表中的节点是否包含值e
162     public boolean contains(E e){
163         return contains(e, head);
164     }
165     private boolean contains(E e,Node node){
166         if (node == null) {
167             return false;
168         }
169         if (node.e == e) {
170             return true;
171         }
172         return contains(e, node.next);
173     }
174     //重写Object类的toString方法:也是通过链表天然的递归性,来访问
175     //链表的每一个节点
176     @Override
177     public String toString() {
178         StringBuilder res = new StringBuilder();
179         res.append("Font -> ");
180         linkToString(head, res);
181         return res.toString();
182     }
183     private void linkToString(Node node,StringBuilder res){
184         if (node == null) {
185             res.append("NULL");
186             return;
187         }
188         res.append(node.e + " -> ");
189         linkToString(node.next, res);
190         return;
191     }
192     
193     /*public static void main(String[] args) {
194         LinekedList<Integer> ll = new LinekedList<>();
195         for (int i = 0; i < 13; i++) {
196             ll.addLast(i);
197             System.out.println(ll.toString());
198         }
199         System.out.println("------------------");
200         for (int i = 0; i < 11; i++) {
201             Integer ii = ll.removeFirst();
202             System.out.println(ii);
203             System.out.println(ll.toString());
204         }
205         
206     }*/
207 }
View Code

有一些方法测了,但是有些方法没测,有需要可以自行参考(不保证准确啊...)

该类主要包含链表的增删改查,里面加了索引主要是为了好理解(注:链表是没有索引的).

因为,才刚开始熟悉递归以及数据结构,所以需要各位大佬的多多指正

有建议的可以在评论中指出.

猜你喜欢

转载自www.cnblogs.com/zy-2113/p/10781280.html