首页 > 代码库 > Java 模拟双端链表

Java 模拟双端链表

双端链表:

双端链表与传统链表非常相似.只是新增了一个属性-即对最后一个链结点的引用rear

这样在链尾插入会变得非常容易,只需改变rear的next为新增的结点即可,而不需要循环搜索到最后一个节点

所以有insertFirst、insertLast

删除链头时,只需要改变引用指向即可;删除链尾时,需要将倒数第二个结点的next置空,

而没有一个引用是指向它的,所以还是需要循环来读取操作

/**
 * 双端链表
 * @author stone
 */
public class TwoEndpointList<T> {
	private Link<T> head;		//首结点
	private Link<T> rear;		//尾部指针
	
	public TwoEndpointList() {
		
	}
	
	public T peekHead() {
		if (head != null) {
			return head.data;
		}
		return null;
	}
	
	public boolean isEmpty() {
		return head == null;
	}
	
	public void insertFirst(T data) {// 插入 到 链头
		Link<T> newLink = new Link<T>(data);
		newLink.next = head; //新结点的next指向上一结点
		head = newLink;
	}
	
	public void insertLast(T data) {//在链尾 插入
		Link<T> newLink = new Link<T>(data);
		if (rear != null) {
			rear.next = newLink;
		} else {
			head = newLink;
			head.next = rear;
		}
		rear = newLink; //下次插入时,从rear处插入
		
	}
	
	public T  deleteHead() {//删除 链头
		if (isEmpty()) return null;
		Link<T> temp = head;
		head = head.next; //变更首结点,为下一结点
		if (head != null && head.next == null) {
			rear = head;
		}
		return temp.data;
	}
	
	public T find(T t) {
		if (isEmpty()) {
			return null;
		}
		Link<T> find = head;
		while (find != null) {
			if (!find.data.equals(t)) {
				find = find.next;
			} else {
				break;
			}
		}
		if (find == null) {
			return null;
		}
		return find.data;
 	}
	
	public T delete(T t) {
		if (isEmpty()) {
			return null;
		} else {
			if (head.data.equals(t)) {
				Link<T> temp = head;
				head = head.next; //变更首结点,为下一结点
				return temp.data;
			}
		}
		Link<T> p = head;
		Link<T> q = head;
		while (!p.data.equals(t)) {
			if (p.next == null) {//表示到链尾还没找到
				return null;
			} else {
				q = p;
				p = p.next;
			}
		}
		q.next = p.next;
		return p.data;
	}
	
	public void displayList() {//遍历
		System.out.println("List (head-->last):");
		Link<T> current = head;
		while (current != null) {
			current.displayLink();
			current = current.next;
		}
	}
	
	public void displayListReverse() {//反序遍历
		if (isEmpty()) {
			return;
		}
		Link<T> p = head, q = head.next, t;
		while (q != null) {//指针反向,遍历的数据顺序向后
			t = q.next; //no3
			if (p == head) {// 当为原来的头时,头的.next应该置空
				p.next = null;
			}
			q.next = p;// no3 -> no1  pointer reverse
			p = q; //start is reverse
			q = t; //no3 start
		}
		//上面循环中的if里,把head.next 置空了, 而当q为null不执行循环时,p就为原来的最且一个数据项,反转后把p赋给head
		head = p; 
		displayList();
	}
	
	class Link<T> {//链结点
		T data;		//数据域
		Link<T> next; //后继指针,结点		链域
		Link(T data) {
			this.data = http://www.mamicode.com/data;>打印

List (head-->last):
the data is 4
the data is 2
the data is 1
the data is 3
the data is 5
List (head-->last):
the data is 2
the data is 1
the data is 3
the data is 5
find:null
find:3
delete find:null
delete find:5
List (head-->last):
the data is 2
the data is 1
the data is 3
----reverse----
List (head-->last):
the data is 3
the data is 1
the data is 2

/**
 * 使用链表实现栈
 * @author stone
 *
 */
public class LinkStack<T> {
	private TwoEndpointList<T> datas;
	
	public LinkStack() {
		datas = new TwoEndpointList<T>();
	}
	
	// 入栈
	public void push(T data) {
		datas.insertFirst(data);
	}
	
	// 出栈
	public T pop() {
		return datas.deleteHead();
	}
	
	// 查看栈顶
	public T peek() {
		return datas.peekHead();
	}
	
	//栈是否为空
	public boolean isEmpty() {
		return datas.isEmpty();
	}
	
	public static void main(String[] args) {
		LinkStack<Integer> stack = new LinkStack<Integer>();
		for (int i = 0; i < 5; i++) {
			stack.push(i);
		}
		for (int i = 0; i < 5; i++) {
			Integer peek = stack.peek();
			System.out.println("peek:" + peek);
		}
		for (int i = 0; i < 6; i++) {
			Integer pop = stack.pop();
			System.out.println("pop:" + pop);
		}
		
		System.out.println("----");
		for (int i = 5; i > 0; i--) {
			stack.push(i);
		}
		for (int i = 5; i > 0; i--) {
			Integer peek = stack.peek();
			System.out.println("peek:" + peek);
		}
		for (int i = 5; i > 0; i--) {
			Integer pop = stack.pop();
			System.out.println("pop:" + pop);
		}
	}
}
打印

peek:4
peek:4
peek:4
peek:4
peek:4
pop:4
pop:3
pop:2
pop:1
pop:0
pop:null
----
peek:1
peek:1
peek:1
peek:1
peek:1
pop:1
pop:2
pop:3
pop:4
pop:5



Java 模拟双端链表