java 实现双链表

最近可能要出去面试,简单的复习了一下数据结构双链表。原文请参见http://www.it165.net/pro/html/201403/10922.html


package fly.zxy.CollectionJava;


/**
 * java语言实现双向链表(双向循环链表)
 * @author VM_ZXY_WIN
 *
 * @param <T>
 */
public class DoubleLink<T> {
	
	private DNode<T> mHead;
	private int mCount;
	
	public DoubleLink(){
		mHead = new DNode<T>(null, null, null);
		mHead.next = mHead.prev = mHead;
		mCount = 0;
	}
	
	/**
	 * 返回节点数
	 * @return
	 */
	public int size(){
		return mCount;
	}
	
	/**
	 * 返回链表是否为空
	 * @return
	 */
	public boolean isEmpty(){
		return mCount == 0;
	}
	
	/* 	#####关于双向链表的查询操作 */
	/**
	 * 根据index获取节点
	 * @param index
	 * @return
	 */
	public DNode<T> getNode(int index){
		if(index<0 || index>=mCount)
			throw new IndexOutOfBoundsException();
		
		DNode<T> rDNode = null;

		//正向查找(向下查找)
		if(index<mCount/2){
			rDNode = mHead.next;
			for(int i=0;i<index;i++)
				rDNode = rDNode.next;
			return rDNode;
				
		}
		
		//反向查找(向上查找) index > mCount/2
		rDNode = mHead.prev;
		int rIndex = mCount-index-1;
		for(int j=0;j<rIndex;j++)
			rDNode = rDNode.prev;
		return rDNode;
	}
	
	/**
	 * 根据index获取节点的值
	 * @param index
	 * @return
	 */
	public T get(int index){
		return getNode(index).value;
	}
	
	/**
	 * 获取第一个节点的值
	 * @return
	 */
	public T getFirst(){
		return getNode(0).value;
	}
	
	/**
	 * 获取最后一个节点的值
	 * @return
	 */
	public T getLast(){
		return getNode(mCount-1).value;
	}
	
	/* 	#####关于双向链表的添加操作 */
	/**
	 * 在指定index处插入一个节点
	 * @param index
	 */
	public void insert(int index,T t){
		//if(index<0 || index>=mCount)
		//	throw new IndexOutOfBoundsException();
		
		if(index ==0){
			appendFirst(t);
			return ;
		}
		
		DNode<T> node = getNode(index);
		DNode<T> newDNode = new DNode<T>(t, node.prev, node);
		node.prev.next = newDNode;
		node.prev = newDNode;
		mCount++;
	}
	
	/**
	 * 向链表尾部添加一个节点
	 * @param t 节点的value
	 */
	public void appendLast(T t){
		DNode<T> node = new DNode<T>(t, mHead.prev, mHead);
		mHead.prev.next = node; //node.prev.next = node;
		mHead.prev = node;		//node.next.prev = node;
		mCount++;
	}
	
	/**
	 * 向链表头部添加一个节点
	 * @param t
	 */
	public void appendFirst(T t){
		DNode<T> node = new DNode<T>(t, mHead, mHead.next);
		mHead.next.prev = node;
		mHead.next = node;
		mCount++;
	}
	
	/* 	#####关于双向链表的删除操作 */
	/**
	 * 根据index删除指定的节点
	 * @param index
	 * @return
	 */
	public T del(int index){
		DNode<T> node = getNode(index);
		node.prev.next = node.next;
		node.next.prev = node.prev;
		mCount--;
		return node.value;
	}
	
	/**
	 * 删除第一个节点
	 * @param index
	 * @return
	 */
	public T delFirst(){
		return del(0);
	}
	
	/**
	 * 删除最后一个节点
	 * @return
	 */
	public T delLast(){
		return del(mCount-1);
	}
	
	
	//toString
	public String toString(){
		String r = "";
		DNode<T> node = mHead.next;
		for(int i=0;i<mCount;i++){
			r += "index:"+i+" value:"+node.value+"\n";
			node = node.next;			
		}
		return r;
	}
	
	/**
	 * 打印头部,双链表的头部没有存储值,是一个特殊的节点
	 */
	public void printMHead(){ 
		System.out.println("mHead value:"+mHead.value+
				" \nmHead.prev.value:"+mHead.prev.value+ //链表中最后一个节点
				" \nmHead.next.value:"+mHead.next.value);//链表中第一个节点(有value)
	}
	
	/**
	 * 将双链表转换成数组形式(仿照java Collection框架LinkedList中的toArray()方法)
	 * @return
	 */
	public Object[] toArray(){
		Object[] result =  new Object[mCount];
		int i=0;
		//如果下一个节点为头部节点,说明双链表已经便利的一边(和toString()原理相同)
		for(DNode<T> n = mHead.next;n != mHead;n = n.next)
			result[i++] = n.value;
		return result;
	}
	
	/* 	#####对DoubleLink测试 	*/
	public static void main(String [] args){
		DoubleLink<String> dLink = new DoubleLink<String>();
		dLink.appendLast("A");
		dLink.appendLast("B");
		dLink.appendLast("C");
		dLink.appendLast("D");
		dLink.appendLast("E");
		dLink.appendLast("F");
		
		System.out.printf("打印dLink的初始值:\n%s",dLink.toString());
		
		//向头部添加一个值
		dLink.appendFirst("First");
		System.out.printf("\n输出头部的值:%s", dLink.getFirst());
		
		//在指定的index处添加一个值
		dLink.insert(4, "INDEX-4");
		System.out.printf("\n输出index为4的值:%s", dLink.get(4));
		
		//删除头部节点和尾部节点
		dLink.delFirst();
		dLink.delLast();
		System.out.printf("\n打印dLink的值:\n%s",dLink.toString());
		
		//将双链表转换成数组
		System.out.println("\ndLinke to array:"+ dLink.toArray().toString());
		
	}
}

/**
 * 双向链表"节点 "对应的结构体
 * @author VM_ZXY_WIN
 *
 * @param <T>
 */
class DNode<T>{
	
	public DNode<T> prev;
	public DNode<T> next;
	public T value;
	
	public DNode(T value, DNode<T> prev, DNode<T> next){
		this.value = value;
		this.prev = prev;
		this.next = next;
	}
}




  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值