双向链表
package com.wx.ListTest;
/**
* Java 实现的双向链表。
* 注:java自带的集合包中有实现双向链表,路径是:java.util.LinkedList
* @author ThinkPad
*
*/
public class DoubleLink<T> {
// 表头
private DNode<T> mHead;
// 节点个数
private int mCount;
// 双向链表“节点”对应的结构体
private class DNode<T>{
public DNode prev;
public DNode next;
public T value;
public DNode(T value,DNode prev, DNode next) {
this.prev = prev;
this.next = next;
this.value = value;
}
}
// 构造函数
public DoubleLink() {
// 创建“表头”。注意:表头没有存储数据!
mHead=new DNode<T>(null, null, null);
mHead.prev=mHead.next=mHead;
// 初始化“节点个数”为0
mCount=0;
}
// 返回节点数目
public int size(){
return mCount;
}
// 返回链表是否为空
public boolean isEmpty(){
return mCount==0;
}
/**
* @param index
* @return
* 获取第index位置的节点
* 节点数:8
* 寻找:第3个节点的值 对应的是2
* 发现小于8>>1 4
* node=1
* 从第一个节点查找 从I=0 循环到 i<2
* i=0 循环完毕 node=2
* i=1 循环完毕 node=3
*
* 寻找:第1个节点的值 对应的是0
* 发现小于8>>1 4
* node=1
* 从第一个节点查找 从I=0 循环到 i<0
*
* 寻找:第5个节点的值 对应的是4
* 发现大于8>>1 4
* 从最后一个节点查找 从i=0 循环到 i<(8-4-1=3)
* node=7
* i=0 循环完毕 node=6
* i=1 循环完毕 node=5
* i=2 循环完毕 node=4
*/
private DNode<T> getNode(int index){
if(index<0||index>=mCount){
throw new IndexOutOfBoundsException();
}
// 正向查找(index <= mCount/2)
if(index <= mCount>>1){
DNode<T> node=mHead.next;
for(int i=0;i<index;i++){
node=node.next;
}
return node;
}
//反向查找
DNode<T> rnode=mHead.prev;
int rindex=mCount-index-1;
for (int i = 0; i < rindex ; i++) {
rnode=rnode.prev;
}
return rnode;
}
// 获取第index位置的节点的值
public T get(int index){
return getNode(index).value;
}
// 获取第1个节点的值
public T getFirst(){
return getNode(0).value;
}
// 获取最后一个节点的值
public T getLast(){
return getNode(mCount-1).value;
}
// 将节点插入到第index位置之前
public void insert(int index,T t){
if(index==0){
DNode<T> newNode=new DNode<T>(t, mHead, mHead.next);
mHead.next.prev=newNode;
mHead.next=newNode;
mCount++;
return;
}
DNode<T> node=getNode(index);
DNode<T> newNode=new DNode<T>(t, node.prev, node);
node.prev.next=newNode;
node.prev=newNode;//>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>存在异议
mCount++;
}
// 将节点插入第一个节点处。
public void insertFirst(T t){
insert(0,t);
}
// 将节点追加到链表的末尾
public void appendLast(T t){
DNode<T> newNode=new DNode<T>(t, mHead.prev, mHead);
mHead.prev.next=newNode;
mHead.prev=newNode;
mCount++;
}
// 删除index位置的节点
public void delete(int index){
DNode<T> node=getNode(index);
node.prev.next=node.next;
node.next.prev=node.prev;
node=null;
mCount--;
}
// 删除第一个节点
public void deleteFirst(){
delete(0);
}
// 删除最后一个节点
public void deleteLast(){
delete(mCount-1);
}
}
测试
package com.wx.ListTest;
/**
* 双向链表测试
* @author ThinkPad
*
*/
public class DoublelinkTest {
public static void main(String[] args) {
intTest();
}
// 双向链表操作int数据
public static void intTest(){
System.out.println("\n----int_test----");
// 创建双向链表
DoubleLink<Integer> doubleLink=new DoubleLink<Integer>();
doubleLink.insertFirst(000);
doubleLink.insert(0, 111);
doubleLink.appendLast(332);
// 双向链表是否为空
System.out.printf("isEmpty()=%b\n", doubleLink.isEmpty());
// 双向链表的大小
System.out.printf("size()=%d\n", doubleLink.size());
for (int i = 0; i < doubleLink.size(); i++) {
System.out.println("第"+(i+1)+"个节点是:"+ doubleLink.get(i));
}
System.out.println("--------在第3个节点前插入数据42324234-------------------");
doubleLink.insert(2, 42324234);
for (int i = 0; i < doubleLink.size(); i++) {
System.out.println("第"+(i+1)+"个节点是:"+ doubleLink.get(i));
}
System.out.println("--------第二次在第3个节点前插入数据66666-------------------");
doubleLink.insert(2, 66666);
for (int i = 0; i < doubleLink.size(); i++) {
System.out.println("第"+(i+1)+"个节点是:"+ doubleLink.get(i));
}
System.out.println("--------第三次在第3个节点前插入数据888-------------------");
doubleLink.insert(2, 888);
for (int i = 0; i < doubleLink.size(); i++) {
System.out.println("第"+(i+1)+"个节点是:"+ doubleLink.get(i));
}
}
}
对照着写的,做出来后感觉太棒了,有些地方可以考虑修改,以后再说吧