您的位置:首页 > 理论基础 > 数据结构算法

java与数据结构(4)---java实现双向循环链表

2013-10-05 21:46 826 查看
线性表之链式存储结构双向循环链表

双向循环链表:每个结点包含了数据、直接前驱地址指针和直接后驱地址指针,头结点的直接前驱指向尾结点,尾结点的直接后驱指向头结点,头尾相连构成一个可正可反的圆环。可以形象的理解成一群孩子手拉手牵成一个圆圈,从头一个孩子开始可以从左往右报数,也可以从右往左开始报数。

优点:双向循环链表可以迅速的获取当前数据的前驱数据,解决了单向循环链表从头开始遍历的麻烦。

接口类

package list;

//************************************************
//*双向循环链表-java实现(画图分析会容易理解得多)
//************************************************

public class TestDoubleLinkedList {
public static void main(String[] args) {
Listable<String> list = new DoubleLinkedList<String>("a");
list.add("b");
list.add("c");
list.addByIndex(3,"e");
list.addByIndex(3,"d");
list.addByIndex(5,"f");
System.out.println(list);
list.addHead("A");
System.out.println(list.Length());
System.out.println(list);
Listable<String> list1 = new DoubleLinkedList<String>("123456");
list.add(list1);
System.out.println(list);
list.remove(100);
list.add("123456");
System.out.println("list="+list);
System.out.println(list1);
list1.removeAll();
System.out.println(list1+"  list1 is Empty??"+list1.isEmpty());
list.remove("123456");
System.out.println("list="+list);
System.out.println("remove item="+list.remove("A"));
System.out.println("list="+list);
}
}

//结点类
class Node<T> {
private Node<T> left,right;
private T data;

Node(T data) {
this(data,null,null);
}

Node() {
this(null,null,null);
}

Node(T data,Node<T> left,Node<T> right) {
this.data = data;
this.left = left;
this.right = right;
}

public T getData() {
return this.data;
}

public Node<T> getLeft() {
return this.left;
}

public Node<T> getRight() {
return this.right;
}

public void setData(T data) {
this.data = data;
}

public void setRight(Node<T> right) {
this.right = right;
}

public void setLeft(Node<T> left) {
this.left = left;
}

public String toString() {
return getData().toString();
}
}

//接口实现类
class DoubleLinkedList<T> implements Listable<T> {
public Node<T> head;

//建空表,带头结点
DoubleLinkedList() {
this(null);
}

//建表,带头结点,表中有一条数据元素
DoubleLinkedList(T element) {
if(element == null) {
head = new Node<T>(element,null,null);
head.setRight(head);
head.setLeft(head);
}else {
Node<T> headRight = new Node<T>(element,null,null);
head = new Node<T>(null,headRight,headRight);
headRight.setLeft(head);
headRight.setRight(head);
}
}

//清空当前链表
public void clear() {}

//判空表
public boolean isEmpty() {
return head.getRight() == head;
}

//表长
public int Length() {
int len = 0;
Node<T> temp = head;
while(temp.getRight() != head) {
len++;
temp = temp.getRight();
}
return len;
}

//取下标index处的数据
public T getElement(int index) {
if(index <= 0) {
return head.getRight().getData();
}
int len = Length();
if(index >=  len) {
return head.getLeft().getData();
}
T element = null;
if(index > 0 && index < len) {
int k = 0;
Node<T> temp = head;
//此处只能用while不能用if,用错好几次
while(k <= index && temp.getRight() != head) {
k++;
temp = temp.getRight();
}
element = temp.getData();
}
return element;
}

//尾添
public boolean add(T element) {
if(element == null) return false;
Node<T> node = new Node<T>(element,head.getLeft(),head);
head.getLeft().setRight(node);
head.setLeft(node);
return true;
}

//首添
public boolean addHead(T element) {
if(element == null) return false;
Node<T> node = new Node<T>(element,head,head.getRight());
head.getRight().setLeft(node);
head.setRight(node);
return false;
}

//表index处,添加新数据element
public boolean addByIndex(int index, T element) {
if(index <= 0) {
return addHead(element);
}else if(index >= Length()) {
return add(element);
}else {
int k = 0;
Node<T> temp = head;
//此处只能用while不能用if,用错好几次
while(k <= index && temp.getRight() != head) {
k++;
temp = temp.getRight();
}
Node<T> node = new Node<T>(element,temp.getLeft(),temp);
temp.getLeft().setRight(node);
temp.setLeft(node);
}
return true;
}

//将参数中的链表添加到当前链表的尾部
public boolean add(Listable<T> slist) {
if(slist.isEmpty() || slist == null) return false;
if(slist instanceof DoubleLinkedList) {
DoubleLinkedList<T> list = (DoubleLinkedList<T>)slist;
//以下操作影响到了添加的slist表,所以需要将slist表重新备份一个
DoubleLinkedList<T> temp = new DoubleLinkedList<T>();
for(int i = 0; i < list.Length(); i++) {
temp.add(list.getElement(i));
}
Node<T> node = temp.head;
Node<T> nodeLeft = node.getLeft();
Node<T> nodeRight = node.getRight();
this.head.getLeft().setRight(node.getRight());
nodeRight.setLeft(this.head.getLeft());
nodeLeft.setRight(this.head);
this.head.setLeft(node.getLeft());
return true;
}else {
return false;
}
}

//删除下标Index处的数据
public T remove(int index) {
if(isEmpty()) return null;
if(index < 0) {
index = 0;
}
int len =  Length();
if(index >= len) {
//当index大于或等于表长是,默认移走表的最后一个元素,即下标为len-1的数据
index = len-1;
}
T element = null;
if(index >= 0 && index < len) {
Node<T> temp = head;
int k = 0;
while(k <= index && temp.getRight() != head) {
k++;
temp = temp.getRight();
}
element = temp.getData();
temp.getRight().setLeft(temp.getLeft());
temp.getLeft().setRight(temp.getRight());
temp.setRight(null);
temp.setLeft(null);
temp = null;
}
return element;
}

//删除当前链表中所有的数据,只剩头结点
public boolean removeAll() {
if(isEmpty()) return false;
Node<T> temp = head.getRight();
while(temp != head) {
head.setRight(temp.getRight());
temp.getRight().setLeft(head);
temp.setLeft(null);
temp.setRight(null);
temp = head.getRight();
}
return true;
}

//删除链表中从head开始的第一个element数据
public T remove(T element) {
if(isEmpty() || element == null) return null;
//从表中第一个元素开始比较
Node<T> temp = head.getRight();
int k=0;
while(temp != head) {
if(element.equals(temp.getData())) {
remove(k);
return element;
}else {
temp = temp.getRight();
k++;
}
}
if(k == (Length()-1)) {
System.out.println("该链表中没有该数据");
}
return element;
}

//修改下标index处的数据,并将原始数据返回
public T setElement(int index,T element) {
if(index < 0 || index >= Length()) return null;
Node<T> temp = head;
int k = 0;
while(k < index && temp.getRight() != head) {
k++;
temp = temp.getRight();
}
T tempEle = temp.getData();
temp.setData(element);
return tempEle;
}

//重写父类toString方法,实际是给list做遍历后将数据打印出来
public String toString() {
StringBuffer sb = new StringBuffer();
/*通过for循环遍历双向循环链表
int length = Length();
sb.append("[ ");
for(int i = 0; i < length; i++) {
sb.append(getElement(i)+" ");
}
sb.append("]");
*/
//从表头开始遍历双向循环链表
sb.append("[ ");
Node<T> node = head;
while(node.getRight() != head) {
sb.append(node.getRight().getData()+" ");
node = node.getRight();
}
sb.append("]");
return sb.toString();
}

}


View Code
后期会添加两个链表求交集等操作。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: