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 }
完整版代码(链表下标从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 }
撰写时间:2017-07-27 21:03:19
修改时间:
感觉有些地方处理的不好,很粗糙,将来慢慢改进吧。
若代码有什么不足,不吝赐教。
越学习越发现自己的无知