Java实现单链表

  刚开始学习java不久的时候以为java没有指针。。。不知道怎么弄链表,最近才顿悟完成这个简单的链表。。。实现这个链表类让我感觉面向对象思想更进一步,建议自己看了思路自己做。(我就是o(^▽^)o)

  java中有基本数据类型和引用数据类型(其实就是指针)。如果对引用不够了解请访问   http://zwmf.iteye.com/blog/1738574 (我觉得写得特别好,就没必要重复了)。

实现链表的思路:

  1)链表类,结点类(链表类的内部类),在main()方法创建一条链表类对象,通过方法逐步创建结点类,通过引用链接起来成为链表。

  2)结点类包含数据和对下个结点的引用,以及可以对数据赋值的构造函数。

  3)链表类的构造方法,只构造出不含数据的头结点。(外部类可以直接对内部类的私有成员进行访问,这样就可以直接修改引用)

主体代码:

1 public  class MyLink<E>{
2     private class Node{
3             privare Object data;         //保存数据
4             private Node next;           //对下个结点的引用
5         }  
6 }
MyLink

完整版代码(链表下标从0开始):

  1 package myLink;
  2 
  3 public class MyLink<E> {          //使用泛型是为了使用时候可以规范链表的数据类型
  4     // 结点内部类
  5     private class Node {
  6         private Object data;                  //数据
  7         private Node next = null;          //指向下个结点的引用
  8 
  9         public Node() {                         //无参数构造函数为了创建头结点服务
 10             data = null;
 11         }
 12 
 13         public Node(E data) {                //带数据的构造函数
 14             this.data = data;
 15         }
 16 
 17     }
 18 
 19     private Node head;               // 头引用(指针)
 20     private Node rear;                // 尾引用(指针)
 21     private Node point;              //临时引用(指针)
 22     private int length;                 // 链表长度
 23 
 24     public MyLink() {                  //链表构造函数,创建无数据的头结点
 25         head = new Node();     
 26         rear = head;
 27         length = 0;
 28     }
 29 
 30     /**
 31      * 从尾部插入链表
 32      * 
 33      */
 34     public void add(E elem) {
 35         point = new Node(elem);
 36         rear.next = point;
 37         rear = point;
 38         length++;
 39 
 40     }
 41 
 42     /**
 43      * 遍历输出链表
 44      */
 45     public void traverse() {
 46         point = head;            //移动临时引用到头结点
 47         if (head != null)
 48             System.out.print("[" + head.data + "]");
 49         while (point.next != null) {
 50             System.out.print("-➜[" + point.next.data + "]");
 51             point = point.next;
 52         }
 53         System.out.println();
 54     }
 55 
 56     /**
 57      * 获得链表长度
 58      * 
 59      */
 60     public int length() {
 61         return length;
 62     }
 63 
 64     /**
 65      * 清除链表内容
 66          * (java垃圾回收,当对象没有引用指向,则视为垃圾,清理时机由系统决定)
 67      */
 68     public void clear() {               
 69         while (head.next != null) {
 70             head.next = head.next.next;
 71         }
 72         rear = head;      // 回到初始状态
 73         point = null;
 74         length = 0;
 75         System.gc();      //请求系统清理垃圾,未必有用
 76     }
 77 
 78     /**
 79      * 在指定个位置插入元素成为第p个元素
 80      */
 81     public void insert(int position, E elem) {
 82                 if(position>=0 && position<=length){
 83             point = movePoint(position);
 84             Node tmp = new Node(elem);
 85             tmp.next = point.next;
 86             point.next = tmp;
 87             length++;
 88                }else{
 89                     System.out.println("没有指定位置,插入失败")
 90                }
 91 
 92     }
 93 
 94     /**
 95      * 删除指定位置的元素
 96      */
 97     public void remove(int position) {
 98         if (position >= 0 && position < length) {
 99             point = movePoint(position);
100             Node tmp = point.next;
101             point.next = tmp.next;
102             length--;
103         } else {
104             System.out.println("删除失败,没有指定位置元素");
105         }
106     }
107 
108     /**
109      * 更改指定位置的元素
110      */
111     public void set(int position, E elem) {
112         if (position >= 0 && position < length) {
113             point = movePoint(position);
114             point.next.data = elem;
115         } else {
116             System.out.println("修改失败,没有指定位置元素");
117         }
118     }
119 
120     /**
121      * 移动指针到指定位置
122          * 私有方法,供其它方法使用
123      */
124     private Node movePoint(int position) {
125         if (position < 0)                    //如果参数小于零,则移动到头部,本来是为了规避参数错误问题,但在使用此方法的其他方法皆有做其他处理,可删除
126             return head;
127         if (position > length)            //如果参数大于长度,则移动到尾部,同上,可删除
128             return rear;
129 
130         if (position >= 0 && position <= length) {
131             point = head;
132             while (point != null) {
133                 if (position == 0)
134                     break;
135                 position--;
136                 point = point.next;
137             }
138         }
139 
140         return point;
141 
142     }
143 
144     /**
145      * 连接两条链表
146          * 已知问题,两链表的数据类型不一定相同,凭我目前实力无法理解解决(如何获取泛型实际类型)
147      */
148     public void connect(MyLink b) {
149         this.rear.next = b.head.next;
150         this.length += b.length;
151         b.head = null;
152     }
153 
154     /**
155      * 按下标查找
156      */
157     public E find(int position) {
158         if (position >= 0 && position < length) {
159             Node tmp = movePoint(position);
160             return (E) tmp.next.data;
161         }
162         return null;
163     }
164 
165     /**
166      * 查找元素的值,返回下标
167      */
168     public int search(E elem) {
169         point = head.next;
170         int idex = -1;
171         while (point != null) {
172             idex++;
173             if (point.data == elem)
174                 break;
175             point = point.next;
176         }
177         return idex;
178 
179     }
180 }
View Code

撰写时间:2017-07-27 21:03:19

修改时间:

感觉有些地方处理的不好,很粗糙,将来慢慢改进吧。

若代码有什么不足,不吝赐教。

原文地址:https://www.cnblogs.com/xy-hong/p/7247374.html