Java
public class DeList<E> implements Deque<E> {
/**
* 头哨兵
*/
private final Node<E> head_sentinel;
/**
* 尾哨兵
*/
private final Node<E> tail_sentinel;
public DeList() {
this.head_sentinel = new Node<>();
this.tail_sentinel = new Node<>();
}
public void dump() {
System.out.println("dump begin");
Node<E> head = head_sentinel.next;
while (head != null) {
System.out.println(head.data);
head = head.next;
}
System.out.println("dump end");
}
public void reserveDump() {
System.out.println("reserve dump begin");
Node<E> tail = tail_sentinel.prev;
while (tail != null) {
System.out.println(tail.data);
tail = tail.prev;
}
System.out.println("reserve dump end");
}
@Override
public void addFirst(E e) {
Node<E> newNode = new Node<>(e);
Node<E> head = head_sentinel.next;
if (head == null) {
tail_sentinel.prev = newNode;
} else {
newNode.next = head;
head.prev = newNode;
}
head_sentinel.next = newNode;
}
@Override
public void addLast(E e) {
Node<E> newNode = new Node<>(e);
Node<E> tail = tail_sentinel.prev;
if (tail == null) {
head_sentinel.next = newNode;
} else {
newNode.prev = tail;
tail.next = newNode;
}
tail_sentinel.prev = newNode;
}
@Override
public boolean offerFirst(E e) {
addFirst(e);
return true;
}
@Override
public boolean offerLast(E e) {
addLast(e);
return true;
}
@Override
public E removeFirst() {
Node<E> head = head_sentinel.next;
if (head == null)
throw new NoSuchElementException();
Node<E> next = head.next;
if (next != null) {
next.prev = null;
} else {
tail_sentinel.prev = null;
}
head_sentinel.next = next;
return head.data;
}
@Override
public E removeLast() {
Node<E> tail = tail_sentinel.prev;
if (tail == null)
throw new NoSuchElementException();
Node<E> prev = tail.prev;
if (prev != null) {
prev.next = null;
} else {
head_sentinel.next = null;
}
tail_sentinel.prev = prev;
return tail.data;
}
@Override
public E pollFirst() {
Node<E> head = head_sentinel.next;
if (head == null)
return null;
Node<E> next = head.next;
if (next != null) {
next.prev = null;
} else {
tail_sentinel.prev = null;
}
head_sentinel.next = next;
return head.data;
}
@Override
public E pollLast() {
Node<E> tail = tail_sentinel.prev;
if (tail == null)
return null;
Node<E> prev = tail.prev;
if (prev != null) {
prev.next = null;
} else {
head_sentinel.next = null;
}
tail_sentinel.prev = prev;
return tail.data;
}
@Override
public E getFirst() {
Node<E> head = head_sentinel.next;
if (head == null)
throw new NoSuchElementException();
return head.data;
}
@Override
public E getLast() {
Node<E> tail = tail_sentinel.prev;
if (tail == null)
throw new NoSuchElementException();
return tail.data;
}
@Override
public E peekFirst() {
return head_sentinel.next.data;
}
@Override
public E peekLast() {
return tail_sentinel.prev.data;
}
@Override
public boolean removeFirstOccurrence(Object o) {
return false;
}
@Override
public boolean removeLastOccurrence(Object o) {
return false;
}
@Override
public boolean add(E e) {
addLast(e);
return true;
}
@Override
public boolean offer(E e) {
offerLast(e);
return true;
}
@Override
public E remove() {
return removeFirst();
}
@Override
public E poll() {
return pollFirst();
}
@Override
public E element() {
return getFirst();
}
@Override
public E peek() {
return peekFirst();
}
@Override
public void push(E e) {
addFirst(e);
}
@Override
public E pop() {
return removeFirst();
}
@Override
public boolean remove(Object o) {
Node<E> head = head_sentinel.next;
while (head != null) {
if ((o == null && head.data == null) || (o != null && o.equals(head.data))) {
// unlink head
Node<E> prev = head.prev;
Node<E> next = head.next;
if (prev == null) {
head_sentinel.next = next;
} else {
prev.next = next;
head.prev = null;
}
if (next == null) {
tail_sentinel.prev = prev;
} else {
next.prev = prev;
head.next = null;
}
head.data = null;
return true;
}
head = head.next;
}
return false;
}
@Override
public boolean containsAll(Collection<?> c) {
for (Object e : c)
if (!contains(e))
return false;
return true;
}
@Override
public boolean addAll(Collection<? extends E> c) {
boolean modified = false;
for (E e : c)
if (add(e))
modified = true;
return modified;
}
@Override
public boolean removeAll(Collection<?> c) {
Objects.requireNonNull(c);
boolean modified = false;
Iterator<?> it = iterator();
while (it.hasNext()) {
if (c.contains(it.next())) {
it.remove();
modified = true;
}
}
return modified;
}
@Override
public boolean retainAll(Collection<?> c) {
Objects.requireNonNull(c);
boolean modified = false;
Iterator<E> it = iterator();
while (it.hasNext()) {
if (!c.contains(it.next())) {
it.remove();
modified = true;
}
}
return modified;
}
@Override
public void clear() {
Iterator<E> it = iterator();
while (it.hasNext()) {
it.next();
it.remove();
}
}
@Override
public boolean contains(Object o) {
Iterator<E> it = iterator();
if (o == null) {
while (it.hasNext()) {
if (it.next() == null) {
it.remove();
return true;
}
}
} else {
while (it.hasNext()) {
if (o.equals(it.next())) {
it.remove();
return true;
}
}
}
return false;
}
@Override
public int size() {
return 0;
}
@Override
public boolean isEmpty() {
return false;
}
@Override
public Iterator<E> iterator() {
return null;
}
@Override
public Object[] toArray() {
return new Object[0];
}
@Override
public <T> T[] toArray(T[] a) {
return null;
}
@Override
public Iterator<E> descendingIterator() {
return null;
}
private static class Node<E> {
private Node<E> prev;
private Node<E> next;
private E data;
public Node() {
}
public Node(E data) {
this.data = data;
}
}
public static void main(String[] args) {
DeList<String> deList = new DeList<>();
deList.addFirst("1");
deList.addFirst("2");
deList.removeFirst();
deList.dump();
deList.reserveDump();
deList.addLast("4");
deList.dump();
deList.reserveDump();
deList.addFirst("3");
deList.removeLast();
deList.dump();
deList.reserveDump();
System.out.println(deList.remove("1"));
deList.dump();
deList.reserveDump();
}
}
C
de_list.h
#ifndef __CHAPTER_6_DE_LIST_H__
#define __CHAPTER_6_DE_LIST_H__
struct de_list {
struct de_list *prev;
struct de_list *next;
int data;
};
#endif
de_list.c
#include <stdio.h>
#include <stdlib.h>
#include "de_list.h"
struct de_list head_sentinel = {NULL, NULL, 0};
struct de_list tail_sentinel = {NULL, NULL, 0};
/**
* 头哨兵
*/
struct de_list *head_sentinel_p = &head_sentinel;
/**
* 尾哨兵
*/
struct de_list *tail_sentinel_p = &tail_sentinel;
void dump() {
printf("dump begin\n");
struct de_list *head_p = head_sentinel_p->next;
while (head_p) {
printf("%s\t", head_p->data);
head_p = head_p->next;
}
printf("dump end\n");
}
void reserve_dump() {
printf("reserve dump begin\n");
struct de_list *tail_p = tail_sentinel_p->prev;
while (tail_p) {
printf("%s\t", tail_p->data);
tail_p = tail_p->next;
}
printf("reserve dump end\n");
}
struct de_list *link_first(int data) {
struct de_list *new_node;
new_node = malloc(sizeof (struct de_list));
new_node->data = data;
struct de_list *head_p = head_sentinel_p->next;
if (head_p) {
head_p->prev = new_node;
} else {
tail_sentinel_p->next = new_node;
}
new_node->next = head_p;
return new_node;
}
struct de_list *link_last(int data) {
struct de_list *new_node;
new_node = malloc(sizeof (struct de_list));
new_node->data = data;
struct de_list *tail_p = tail_sentinel_p->prev;
if (tail_p) {
tail_p->next = new_node;
} else {
tail_sentinel_p->prev = new_node;
}
new_node->prev = tail_p;
return new_node;
}
void unlink_first() {
struct de_list *head_p = head_sentinel_p->next;
if (!head_p)
return;
struct de_list *next = head_p->next;
if (next) {
next->prev = NULL;
} else {
tail_sentinel_p->prev = NULL;
}
head_sentinel_p->next = next;
// free head_p
head_p->next = NULL;
head_p->data = 0;
free(head_p);
head_p = NULL;
}
void unlink_last() {
struct de_list *tail_p = tail_sentinel_p->prev;
if (!tail_p)
return;
struct de_list *prev = tail_p->prev;
if (prev) {
prev->next = NULL;
} else {
head_sentinel_p->next = NULL;
}
tail_sentinel_p->prev = prev;
// free tail_p
tail_p->prev = NULL;
tail_p->data = 0;
free(tail_p);
tail_p = NULL;
}
void __unlink(struct de_list *node) {
struct de_list *prev = node->prev;
struct de_list *next = node->next;
if (prev) {
prev->next = next;
} else {
head_sentinel_p->next = next;
node->prev = NULL;
}
if (next) {
next->prev = prev;
} else {
tail_sentinel_p->prev = prev;
node->next = NULL;
}
// free node
node->data = 0;
free(node);
node = NULL;
}