双向循环链表的实现
设计要求
1.建立一个空表。
2.在第i个位置插入新的元素x。
3.删除第i个位置上的元素。
4.取第i个位置上的元素。
5.返回元素x第一次出现在双向循环链表中的位置号。
6.求双向循环链表的长度,即元素个数。
7.输出双向循环链表中所有的元素值。
8.实现双向循环链表的就地逆置。
代码
package course.com.java.list;
import java.util.Iterator;
/**
* @author xlorb
*/
public interface IList<T> {
int size();// 返回数据个数
void clear();// 清楚线性表中的所有数据
boolean isEmpty();// 是不是为空表
int indexOf(T x);// 找到x的索引号
T get(int index);// 返回索引号为index的数据的值
void add(int index, T x);// 加入数据x, 索引号为index
T remove(int index);// 删除索引号为index的的数据
Iterator<T> iterator();// 迭代器,枚举线性表中的数据
public void localReverse();//就地逆转
}
package course.com.java.list;
import java.util.Iterator;
/**
* @author xlorb
*/
public class CList<T>implements Iterable<T>, IList<T> {
//结点内部类
static class Node<T>{
T data;
Node<T> pre,next;
public Node(T data,Node<T> pre,Node<T> next){
this.data = data;
this.pre = pre;
this.next = next;
}
}
//尾循环
Node<T> tail;
int size;
//建立一个空表
public CList(){
tail = null;
size = 0;
}
//返回元素的个数
public int size(){
return size;
}
@Override
public void clear() {
if (tail == null)
return;
while (tail.next != tail) {// 从第1个结点开始,逐个删除
Node<T> q = tail;// q待删除结点
tail = tail.next;// 下一个结点
q.next.pre = q.pre;
q.pre.next = q.next; //将q提取出来
q.data = null;// 帮助GC
q.next = q.pre = null;
size --;
}
tail = null;
size = 0;
}
//链表是否为空
public boolean isEmpty(){
return size == 0;
}
//ADD方法使用
private void rangeCheckForAdd(int index) {
if (index < 0 || index > size)
throw new IndexOutOfBoundsException(String.valueOf(index));
}
//其他方法使用
private void rangeCheck(int index) {
if (index < 0 || index > size - 1)
throw new IndexOutOfBoundsException(String.valueOf(index));
}
//在index位置上添加元素
public void add(int index,T x){
rangeCheckForAdd(index);
if (index == size){
if (size == 0) {
tail = new Node<>(x,null,null);
tail.pre =tail.next = tail;
}
else {
Node<T> p = tail.next;
tail.next = new Node<>(x, tail, tail.next);
p.pre = tail = tail.next;
}
}else {
Node<T> p = tail.next;
if ((size>>1)<index)
for (int i = 0; i < index; i++)
p = p.next;
else
for (int i = size; i>index;i--)
p = p.pre;
Node<T>q = p.pre;
p.pre = q.next = new Node<>(x,q,p);
}
size++;
}
//删除结点
public T remove(int index){
Node<T> p = findNode(index);
T result = p.data;
if (size == 1)
tail = null;
else {
if (index == size() - 1)
tail = tail.next;
p.pre.next = p.next;
p.next.pre = p.pre;
p.pre = p.next = null;//gc帮助
p.data = null;
}
size--;
return result;
}
//找到此结点
private Node<T> findNode(int index) {
rangeCheck(index);
Node<T> p = tail;
if ((size()>>1)<index)
for (int i = 0; i <= index; i++)
p = p.next;
else
for (int i = size; i>index+1;i--)
p = p.pre;
return p;
}
//得到此结点
public T get(int index){
return findNode(index).data;
}
//找到第一个数的下标
public int indexOf(T data){
int i = 0;
for (T x : this){
if(x.equals(data))
return i;
i++;
}
return -1;
}
@Override
public Iterator<T> iterator() {
return new Itr();
}
private class Itr implements Iterator<T> {
private Node<T> currentNode;
boolean flag ;
public Itr() {
currentNode = tail;
flag = true;
}
public boolean hasNext() {
return flag;
}
public T next() {
currentNode = currentNode.next;
if (currentNode==tail)
flag = false;
return currentNode.data;
}
}
public void display() {
StringBuilder result = new StringBuilder(getClass().getName() + ":");
if (size == 0);
else
for (T data : this)
result.append(" ").append(data);
System.out.println(result);
}
//就地逆置:
public void localReverse(){
if (size>1){
Node<T> p = tail;
while (p.next!=tail){
reverse(p);
p = p.pre;
}
reverse(p);
tail = tail.pre;
}
}
private void reverse(Node<T> p) {
Node<T> q;
Node<T> r;
q = p;
r = p.next;
q.next = q.pre;
q.pre = r;
}
public static void main(String[] args) {
CList<Integer> ints = new CList<>();
System.out.println("isEmpty :" +ints.isEmpty());
ints.add(0,1);
ints.add(0,2);
ints.add(1,3);
ints.add(2,6);
ints.add(0,4);
ints.add(3,8);
System.out.println(ints.isEmpty());
ints.display();
System.out.println("remove 0 : "+ints.remove(0));
System.out.println("get 0 : "+ints.get(0));
ints.display();
ints.localReverse();
ints.display();
System.out.println("index 2 : "+ints.indexOf(2));
ints.clear();
ints.display();
}
}
测试方法: