1.双向链表的性能分析
1.1 特征
a.不支持索引访问,所以对某个元素对象的访问的时间复杂度为o(index),其中index是这个索引。
b.支持前驱访问,和单向链表的主要区别。
1.2 实现方式
元素:
Elment的接口是针对于单链表的,但事实上,双链表也会继承单链表的元素的一些特性,我们可以看一下这个元素的
然后我们新增加了一个IIntElement的接口,事实上,我们的链表针对的对象可以不仅仅是Int,String,因为对象繁多,为了保证设计模式里面的:开闭原则,我们尽量去派生特性,保证继承的强大的扩展性能。
该接口的设计其实很简单:
然后使我们的双向链表元素接口,当然是针对整形的,通常接口的第一个字母是I,这个是常用的命名规则
这个元素其实比起单链表是多了一个特性,那就是last的特性
然后我们可以实现这个接口
package DoubleDirTable;
public class IntDoubleDirElement implements IIntDoubleDirTableElement<IntDoubleDirElement> {
private int value;
private IntDoubleDirElement next;
private IntDoubleDirElement last;
public IntDoubleDirElement(int value){
setValue(value);
}
@Override
public String toString() {
return value+"";
}
@Override
public Integer getValue() {
return value;
}
@Override
public void setValue(Integer value) {
this.value = value;
}
@Override
public IntDoubleDirElement getLast() {
return last;
}
@Override
public IntDoubleDirElement getNext() {
return next;
}
@Override
public void setLast(IntDoubleDirElement intDoubleDirElement) {
this.last = intDoubleDirElement;
}
@Override
public void setNext(IntDoubleDirElement intDoubleDirElement) {
this.next = intDoubleDirElement;
}
}
拥有这个元素之后,我们去重写双向线性表,并且测试。至于双向线性表的操作,和单项表差不多,但是因为它多了一个反向遍历的操作,所以我们需要新增一个反向遍历的函数。
至于实现就很简单了:
package DoubleDirTable;
public class IntDoubleDirTable implements IDoubleTable<IntDoubleDirElement> {
private IntDoubleDirElement headElement;
private IntDoubleDirElement endElement;
private int len;
public IntDoubleDirTable(int value){
headElement = new IntDoubleDirElement(value);
}
@Override
public IntDoubleDirElement head() {
return headElement;
}
@Override
public IntDoubleDirElement end() {
return endElement;
}
@Override
public int len() {
return len;
}
@Override
public void add(IntDoubleDirElement intDoubleDirElement) {
IntDoubleDirElement selectElement = headElement;
while (selectElement.getNext()!= null){
selectElement = selectElement.getNext();
}
selectElement.setNext(intDoubleDirElement);
intDoubleDirElement.setLast(selectElement);
endElement = intDoubleDirElement;
len++;
}
@Override
public void delete(int index) {
IntDoubleDirElement selectElement =getIndexElement(index);
selectElement.setNext(selectElement.getNext().getNext());
selectElement.getNext().setLast(selectElement);
len--;
}
@Override
public void insert(IntDoubleDirElement intDoubleDirElement, int index) {
IntDoubleDirElement selectElement = getIndexElement(index);
intDoubleDirElement.setLast(selectElement);
intDoubleDirElement.setNext(selectElement.getNext());
selectElement.getNext().setLast(intDoubleDirElement);
selectElement.setNext(intDoubleDirElement);
}
@Override
public IntDoubleDirElement get(int index) {
return getIndexElement(index);
}
public IntDoubleDirElement getIndexElement(int index){
IntDoubleDirElement selectIndex = headElement;
for (int i = 0;i<index;i++){
selectIndex = selectIndex.getNext();
}
return selectIndex;
}
public static void main(String[] arg){
IntDoubleDirTable table = new IntDoubleDirTable(0);
for (int i =1;i<10;i++){
table.add(new IntDoubleDirElement(i));
}
System.out.println("正向遍历:"+table.toString());
System.out.println("反向遍历:"+table.reverseTraverse());
table.insert(new IntDoubleDirElement(12),5);
System.out.println("插入正向遍历:"+table.toString());
System.out.println("插入反向遍历:"+table.reverseTraverse());
table.delete(7);
System.out.println("删除7正向遍历:"+table.toString());
System.out.println("删除7反向遍历:"+table.reverseTraverse());
IntDoubleDirElement element = table.get(3);
System.out.println(element.toString());
}
@Override
public String toString() {
IntDoubleDirElement arr = headElement;
String value = "";
while (arr!= null){
value+= arr.getValue()+" ";
arr = arr.getNext();
}
return value;
}
@Override
public String reverseTraverse() {
IntDoubleDirElement arr = endElement;
String value = "";
while (arr!= null){
value+= arr +" ";
arr = arr.getLast();
}
return value;
}
}