链表分类有 单链表,双链表。
链表在物理存储上是与数组相反的,因为链表的每一个元素都可以散落在其他地方,他们之间的关系靠的就是指针来维系。 数组呢因为是连续存储,元素与元素之间的存储位置都挨着,,正是这个要求,所以在最开始的时候,必须告知我这个数组里要有几个元素以便于开辟指定的存储空间。当然,如果我们给了个超大的index值来找数组的某个元素的话,,给的内存就那点儿,存的数量都是一定的,指针越界啥的分分秒的事情!!但是链表呢,人家巧妙的避开了连续存储这个坑,,爱存哪儿存哪儿,你也不用给我指定特定元素数量了,,因为我的存储是分布的,每个元素都具备见缝插针的存储能力,那怎么找呢?我只需要记录下一个元素的地址在哪里,如果需要找特定元素的时候,,我就从第一个元素存储的指针开始顺藤摸瓜,反正踏过千山万水总会找到的。。当然,这点也反映了,链表实则在查找上面稍有吃力。。因为在这点上毕竟不能像数组一样,只要 i[n]这样就能分分秒知道他的内存地址。但是呢,链表在插入方面,删除方面那就完胜数组了,因为数组,还得涉及一些一波元素集体后移这类问题。而链表只需要找到节点,拆了指针重新指就行。比如删除一个节点,只需要把被删除节点得前一个节点的next指针指向被删除节点的下一个节点就行。。那么被删除的节点由于没有指向它的指针,就只能等着被垃圾回收机制回收。
现在我是发现了,只要掌握了思想,看懂代码,编码,是很简单的事情。所以有时候看源码十分迷糊的话,就去找找人家的基本思想。以下就是看了链表的思想之后码出来的。以前感到头疼的地方,焕然大悟,以前疑惑为什么会这样写?现在明白思想了才知道,哎,,这种思想,无论谁都得这样写,理所当然的。
单向链表的实现。
package 数据结构;
/**
* 链表相关类
* @author forev
*
*/
public class MyLink {
Note head = null;
int size = 0;
/**
*
* @param o
*/
public void add(Object o){
Note newNote = new Note(o);
if (head == null) {//说明头部还没有元素,这个链表还没有内容
head = newNote;
size = 1;
return;
}else {
//已经有元素了,那么遍历,找到最后一个元素
Note point = head;
while (point.nextPoint != null) {
point = point.nextPoint;
}
point.nextPoint = newNote;
size ++;
}
}
/**
*
* @param o
* @return
*/
public boolean insert(Object o, int index){
//空链表
//头部
//尾部
//中间
boolean isInserted = false;
Note note;
if (head == null) {
System.out.println("空链表!");
} else if (index < 0){
System.out.println("index 越界!");
} else if (index == 0) {
note = new Note(o);
note.nextPoint = head;
head = note;
size ++;
isInserted = true;
} else if (index >= size) { // 如果指定了一个超大的位置,那就默认最后一个添加
add(o);
size ++;
isInserted = true;
} else {
int i = 1;
Note point = head;
while (i < index){
point = point.nextPoint;
i ++;
}
note = new Note(o);
Note nextPoint = point.nextPoint;
point.nextPoint = note;
note.nextPoint = nextPoint;
size ++;
isInserted = true;
}
return isInserted;
}
/**
*
* @param o
* @return
*/
public boolean delete(int index){
if (index > size -1 || index < 0) {
System.out.println("越界了");
return false;
}
if (index == 0) {
head = head.nextPoint; //原来的head 因为没有指向它的指针,在特定的时机下就会被回收。
size -= 1;
return true;
}
int i = 1;
Note prenote= head;
while(i < index) {
prenote = prenote.nextPoint;
i ++;
}
prenote.nextPoint = prenote.nextPoint.nextPoint;
size -= 1;
return true;
}
/**
*
* @param oldObj
* @param newObj
* @return
*/
public boolean change(Object oldObj, Object newObj){
boolean isChanged = false;
if (head == null) {
System.out.println("空链表。");
}else{
Note point = head;
while(point != null) {
if (point.data == oldObj){
point.data = newObj;
isChanged = true;
}
point = point.nextPoint;
}
}
return isChanged;
}
public int size(){
return size;
}
@Override
public String toString() {
// TODO Auto-generated method stub
StringBuilder sb = new StringBuilder();
if (head == null){
sb.append("空链表!");
}else {
Note point = head;
while (point != null) {
sb.append(point.data.toString() + ", ");
point = point.nextPoint;
}
}
return sb.toString();
}
}
class Note{
Object data;
Note nextPoint;
public Note(Object o) {
this.data = o;
}
}
相关代码 LinkedList