linkedlist - java 简单实现

本文详细介绍了链表数据结构的特点、内部结构及基本操作方法,包括插入、删除、搜索等,并提供了一个Java实现的示例及其单元测试案例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

 

linked list

 

链表,

 

------

特点:

 

linkedlist 相对于基于数组的 list:

* 在中间 插入 & 删除 时,效率较高,只影响 前结点的next指针 和 后结点的pre指针,

* 根据 index get() 时 效率较低,需要一个个查找

 

------

结构:

 

每个元素包含:

* value 值,

* pre 前一个元素,

* next 后1个元素,

 

------

操作:

 

* search

O(n)

* insert

O(1)

* delete

O(1)

* Sentinels

用 一个 特殊值 表示不存在的值,以方便各种操作对空元素的判断,


------

例子 (java 实现):

 

* java 类

 

package eric.algrathem.struct.linkedlist;

import java.util.ArrayList;
import java.util.List;

/**
 * structure for linkedlist
 * 
 * @author eric
 * @date 2011-2-11 上午03:27:26
 */
public class LinkedListStruct<E> {
	/** the header entry */
	private Entry<E> header;
	/** total entry count */
	private int size;

	public LinkedListStruct() {
		this.header = new Entry<E>(null, null, null);
		this.size = 0;
	}

	/**
	 * add at end
	 * 
	 * @param ele
	 */
	public boolean add(E ele) {
		if (size == 0) {
			header.element = ele;
			size++;
		} else {
			addAtEnd(ele);
		}
		return true;
	}

	/**
	 * add at specify position
	 * 
	 * @param ele
	 * @param index target index,index <= current size
	 * @return
	 */
	public boolean add(E ele, int index) {
		if (index < 0 || index > size) { // index invalid
			throw new IndexOutOfBoundsException("Index: " + index + ", Size: " + size);
		} else if (index == size) { // append at end
			return add(ele);
		} else { // add at position of one current element
			addBefore(ele, getEntry(index));
		}
		return true;
	}

	public E get(int index) {
		return getEntry(index).element;
	}

	public void remove(int index) {
		remove(getEntry(index));
	}

	/** return size */
	public int size() {
		return size;
	}

	/**
	 * search,return first match element's index,if not found return -1
	 * 
	 * @param ele
	 * @return
	 */
	public int search(E ele) {
		return search(ele, 0);
	}

	/**
	 * search,search from specified index,return first match element's index,if not found return -1
	 * 
	 * @param ele
	 * @param start
	 * @return
	 */
	public int search(E ele, int start) {
		Entry<E> entry = getEntry(start);
		int index = start;
		while (index < size) {
			if (entry.element != null && entry.element.equals(ele)) {
				return index;
			}
			entry = entry.next;
			index++;
		}
		return -1;
	}

	/**
	 * search all,return all match element's index in a list
	 * 
	 * @param ele
	 * @return
	 */
	public List<Integer> searchAll(E ele) {
		return searchAll(ele, 0);
	}

	/**
	 * search all,search from specified index,return all match element's index in a list
	 * 
	 * @param ele
	 * @param start
	 * @return
	 */
	public List<Integer> searchAll(E ele, int start) {
		List<Integer> result = new ArrayList<Integer>();
		Entry<E> entry = getEntry(start);
		int index = start;
		while (index < size) {
			if (entry.element != null && entry.element.equals(ele)) {
				result.add(index);
			}
			entry = entry.next;
			index++;
		}
		return result;
	}

	/** single data entity,including data & two reference(previous,next) */
	private static class Entry<E> {
		E element;
		Entry<E> next;
		Entry<E> previous;

		Entry(E element, Entry<E> next, Entry<E> previous) {
			this.element = element;
			this.next = next;
			this.previous = previous;
		}
	}

	/**
	 * insert before
	 * 
	 * @param ele
	 * @param entry
	 * @return
	 */
	private synchronized Entry<E> addBefore(E ele, Entry<E> entry) {
		Entry<E> newEntry = new Entry<E>(ele, entry, entry.previous);
		if (entry.previous != null) {
			entry.previous.next = newEntry;
		}
		entry.previous = newEntry;
		if (newEntry.previous == null) { // reset header
			header = newEntry;
		}
		size++;
		return newEntry;
	}

	/**
	 * add at end
	 * 
	 * @param ele
	 * @return
	 */
	private synchronized Entry<E> addAtEnd(E ele) {
		Entry<E> end = getEntry(size - 1);
		Entry<E> newEntry = new Entry<E>(ele, null, end);
		end.next = newEntry;
		size++;
		return newEntry;
	}

	/**
	 * get by index,index is the order of entry (start by 0)
	 * 
	 * @param index
	 * @return
	 */
	private synchronized Entry<E> getEntry(int index) {
		if (index < 0 || index >= size) {
			throw new IndexOutOfBoundsException("Index: " + index + ", Size: " + size);
		}
		Entry<E> entry = header;
		while (index-- > 0) {
			entry = entry.next;
		}
		return entry;
	}

	/**
	 * insert before
	 * 
	 * @param ele
	 * @param entry
	 * @return
	 */
	private synchronized void remove(Entry<E> entry) {
		if (entry.previous != null) {
			entry.previous.next = entry.next;
		} else { // header is the target to remove,reset header
			header = (entry.next == null ? new Entry<E>(null, null, null) : entry.next);
		}
		if (entry.next != null) {
			entry.next.previous = entry.previous;
		}
		entry.previous = entry.next = null;
		entry = null;
		size--;
	}
}
 

 

junit 测试类

 

package eric.algrathem.struct.linkedlist;

import java.util.List;

import junit.framework.Assert;
import junit.framework.TestCase;

import org.junit.Test;

/**
 * test case for LinkedListStruct
 * 
 * @author eric
 * @date 2011-2-11 下午08:50:35
 */
public class LinkedListStructTest extends TestCase {
	@Test
	public void testAdd() {
		LinkedListStruct<Integer> list = new LinkedListStruct<Integer>();
		int size = 10;
		for (int i = 0; i < size; i++) {
			list.add(i);
		}

		for (int i = 0; i < size; i++) {
			Assert.assertTrue(i == list.get(i));
		}

		list.add(100, 5);
		Assert.assertTrue(100 == list.get(5));
		Assert.assertTrue(4 == list.get(4));
		Assert.assertTrue(5 == list.get(6));
		Assert.assertTrue(6 == list.get(7));
	}

	@Test
	public void testRemove() {
		LinkedListStruct<Integer> list = new LinkedListStruct<Integer>();
		int size = 20;
		int[] removeIndexArr = { 3, 8, 15 };
		for (int i = 0; i < size; i++) {
			list.add(i);
		}
		for (int i = 0; i < removeIndexArr.length; i++) {
			list.remove(removeIndexArr[i] - i);
		}

		Assert.assertTrue(list.size() == size - removeIndexArr.length);
		int curRemove = 0;
		int fix = 0;
		for (int i = 0; i < list.size(); i++) {
			if (curRemove < removeIndexArr.length && i == (removeIndexArr[curRemove] - curRemove)) {
				fix++;
				curRemove++;
			}
			Assert.assertTrue(list.get(i) == i + fix);
		}
	}

	@Test
	public void testSearch() {
		LinkedListStruct<Integer> list = new LinkedListStruct<Integer>();
		int size = 10;
		int repeat = 3;
		for (int i = 0; i < repeat; i++) {
			for (int j = 0; j < size; j++) {
				list.add(j);
			}
		}
		for (int x = 0; x < size; x++) {
			Assert.assertEquals(x, list.search(x));
			for (int y = 0; y < repeat; y++) {
				Assert.assertEquals(x + size * y, list.search(x, size * y));
			}
		}
	}

	@Test
	public void testSearchAll() {
		LinkedListStruct<Integer> list = new LinkedListStruct<Integer>();
		int size = 10;
		int repeat = 3;
		for (int i = 0; i < repeat; i++) {
			for (int j = 0; j < size; j++) {
				list.add(j);
			}
		}
		for (int x = 0; x < size; x++) {
			// searchAll(ele)
			List<Integer> result = list.searchAll(x);
			Assert.assertEquals(result.size(), repeat);
			for (int y = 0; y < repeat; y++) {
				Assert.assertTrue(result.get(y) == x + y * size);
			}

			// searchAll(ele,start)
			for (int z = 0; z < repeat; z++) {
				List<Integer> resultPart = list.searchAll(x, z * size);
				Assert.assertEquals(resultPart.size(), repeat - z);
				for (int z1 = 0; z1 < resultPart.size(); z1++) {
					Assert.assertTrue(resultPart.get(z1) == ((z + z1) * size) + x);
				}
			}
		}
	}
}

 
------

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值