java算法01 - 链表

时间:2021-03-07 11:26:00

1、链表

在Java中实现链表,每个节点都有一个值,然后把它链接到下一个节点。下面来看一下节点的实现

     class Node<E> {
private E e;
private Node<E> next = null;

Node() {
}

Node(E e) {
this.e = e;
}

public void setNext(Node<E> next) {
this.next = next;
}

public Node<E> getNext() {
return next;
}

public E getValue() {
return e;
}

public void setValue(E e) {
this.e = e;
}
}

 

单链表

有了节点,来实现一个简单的单链表

**
* 单链表数据结构简单实现
*
* @author jade
*
*/
public class SingleLinkedList<E> {

private Node<E> head = null; // 每个链表都存有一个空值的头结点。
private Node<E> tail = null; // 链表的最后一个结点,尾结点。
private int size = 0; // 当前链表中的节点数目。

/**
* 建立一个空链表(建立其头结点)。
*/
public SingleLinkedList() {
head
= new Node<E>();
tail
= head;
}

/**
* 在链表的尾部插入数据
*
@param e 待插入的数据
*
@return
*/
public boolean add(E e) {
Node
<E> node = new Node<E>(e); // 将要插入的值封装成一个节点。
tail.setNext(node); // 将待插入结点放到尾结点的下一个结点。
tail = tail.getNext(); // 将新增加的结点设为尾节点。
++size; // 链表大小增1。
return true;
}

/**
*
*
@param index 待插入的位置
*
@param e 待插入的元素
*
@return
*/
public boolean add(int index, E e) {
checkValidateIndex(index);
Node
<E> newNode = new Node<E>(e);
Node preNode
= null;
if (index > 0) {
preNode
= getNode(index - 1);
}
else{
preNode
= head;
}
newNode.setNext(preNode.getNext());
preNode.setNext(newNode);
return true;
}

/**
* 获取指定位置的结点的值
*
@param index 欲获取值的结点的下标
*
@return
*/
public E get(int index) {
checkValidateIndex(index);
Node
<E> node = getNode(index);
return node.getValue();
}

/**
* 删除指定位置的结点
*
@param index 待删除结点的下标
*
@return
*/
public boolean remove(int index) {
Node
<E> curNode = null;
if (0 == index) {
curNode
= head.getNext();
Node
<E> nextNode = curNode.getNext();
head.setNext(nextNode);
}
else {
checkValidateIndex(index);
curNode
= getNode(index); // 获取待删除节点。
Node<E> preNode = getNode(index - 1); // 获取待删除节点的前一个结点。
preNode.setNext(curNode.getNext());
}
curNode.setNext(
null); // 将待删除节点的下一结点置空。
return true;
}

/**
* 设置指定位置结点的值。
*
@param index 待设置值的结点的下标
*
@param e
*/
public void set(int index, E e) {
checkValidateIndex(index);
Node
<E> node = getNode(index);
node.setValue(e);
}

/**
* 获取指定位置的结点
*
@param index 获取结点的下标
*
*/
private Node<E> getNode(int index) {
checkValidateIndex(index);
Node
<E> node = head;
for (int p = 0; p <= index; ++p) {
node
= node.getNext();
}
return node;
}

/**
* 验证下标值是否合法,非法时抛出异常。
*
@param index 待验证的下标值
*
@throws Exception
*
*/
private void checkValidateIndex(int index) {
if (index < 0 || index > size) {
throw new IndexOutOfBoundsException("无效的下标:" + index);
}
}

/**
* 获取链表的大小。
*
@return
*/
public int size() {
return size;
}

 

堆栈和队列是两种特殊的线性表,下面来看一下他们的链式实现

栈(Stack)

java中的Stack是继承Vector的 :public class Stack<E> extends Vector<E>

下面来看一下Stack的简单实现:

class Stack {
Node top;

/**
* 栈顶元素
*
@return
*/
public Node peek() {
if (top != null) {
return top;
}
return null;
}

/**
* 退栈
*
@return
*/
public Node pop() {
if (top == null) {
return null;
}
else {
Node temp
= new Node(top.next);
top
= top.next;
return temp;
}
}

/**
* 入栈
*
@param n
*/
public void push(Node n) {
if (n != null) {
n.next
= top;
top
= n;
}
}
}

 

队列(queue)

下面基于链表实现一个阻塞对列

/**
* 基于链表实现的一个阻塞队列
*
*
@author jade
*
*/
public class BlockingQueue {
private int capacity ; // 阻塞队列容量
private List queue = new LinkedList(); // 基于链表实现的一个阻塞队列

public BlockingQueue() {
this(Integer.MAX_VALUE);
}

public BlockingQueue(int capacity) {
this.capacity = capacity;
}

/**
* 入队列
*
*
@param item
*
@throws InterruptedException
*/
public synchronized void enqueue(Object item) throws InterruptedException {
while (this.queue.size() == this.capacity) {
wait();
}
if (this.queue.size() == 0) {
notifyAll();
}
this.queue.add(item);
}

/**
* 出队列
*
*
@return
*
@throws InterruptedException
*/
public synchronized Object dequeue() throws InterruptedException {
while (this.queue.size() == 0) {
wait();
}
if (this.queue.size() == this.capacity) {
notifyAll();
}
return this.queue.remove(0);
}

}