最近可能要出去面试,简单的复习了一下数据结构双链表。原文请参见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;
}
}