数据结构--线性表之链表及代码实现

链表分类有 单链表,双链表。

【数据结构】链表的原理及与其相关的常见面试题总结

数据结构学习之双向链表结构

链表在物理存储上是与数组相反的,因为链表的每一个元素都可以散落在其他地方,他们之间的关系靠的就是指针来维系。 数组呢因为是连续存储,元素与元素之间的存储位置都挨着,,正是这个要求,所以在最开始的时候,必须告知我这个数组里要有几个元素以便于开辟指定的存储空间。当然,如果我们给了个超大的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
















猜你喜欢

转载自blog.csdn.net/weixin_28774815/article/details/80615266