Java -- 栈、队列等数据结构的简单链表实现

Java -- 栈、队列等数据结构的链表实现


链表是一种递归的数据结构,它或者为null,或者是指向一个节点的引用,该节点含有一个泛型的元素和一个指向另一条链表的引用。在链表头部插入元素,插入的原始最后出现在链表的首部;在链表尾部插入元素,插入的元素最后出现在链表的尾部;删除链表中间部分的节点,则需要遍历链表(左向右是首到尾)。
一般在某个数据结构类的内部定义一个表示链表节点的内部类:
    private static class Node<T>{
        private T item;
        private Node<T> next;
    }  
背包基本实现:
/**
 * 背包是一种不支持从中删除元素的集合数据类型,它的目的就是帮助用例收集元素并迭代遍历所有收集到的元素,链表实现
 * 
 * @author xzm
 *
 * @param <T>
 */
public class BagMain<T> implements Iterable<T> { //实现Iterable接口允许我们使用增强for循环遍历元素
    /**
     * 数据域、指针域
     * @author xzm
     *
     */
    private static class Node<T>{
         private T item; 
         private Node<T> next;
    }
    
    private int count;
    private Node<T> first;
    
    public BagMain() {
        first = null;
        count = 0;
    }
    
    /**
     * 表头出插入一个节点
     * @param item
     */
    public void add(T item) {
        Node<T> oldlast = first;
        first = new Node<T>();
        first.item = item;
        first.next = oldlast;
        count++;
    }
    public boolean isEmpty() {
        return first == null;
    }
    public int size() {
        return count;
    }
    @Override
    public Iterator<T> iterator() {
        // TODO Auto-generated method stub
        return new BagIterator();
    }
    private class BagIterator implements Iterator<T> {
        
        private Node<T> current = first;
        @Override
        public boolean hasNext() {
            return current != null;
        }
        @Override
        public T next() {
            T item = current.item;
            current = current.next;
            return item;
        }
    }
}
队列基本实现:
/**
 * 先进先出队列是一种基于先进先出策略的集合模型,在表尾插入元素
 * 
 * @author xzm
 *
 */
public class QueueMain<T> implements Iterable<T> {
    private Node<T> head;// 表头节点
    private Node<T> tail;// 表尾节点
    private int count;
    private static class Node<T> {
        private T item;
        private Node<T> next;
    }
    public QueueMain() {
        head = null;
        tail = null;
        count = 0;
    }
    /**
     * 队列尾部添加元素
     * 
     * @param item
     */
    public void enqueue(T item) {
        Node<T> oldlast = tail;
        tail = new Node<T>();
        tail.item = item;
        tail.next = null;
        if (isEmpty())
            head = tail;
        else
            oldlast.next = tail;
        count++;
    }
    /**
     * 队列头部删除最早添加的元素
     * 
     * @return
     */
    public T dequeue() {
        T item = head.item;
        head = head.next;
        if (isEmpty())
            tail = null;
        count--;
        return item;
    }
    public boolean isEmpty() {
        return head == null;
    }
    public int size() {
        return count;
    }
    @Override
    public Iterator<T> iterator() {
        return new QueueIterator();
    }
    private class QueueIterator implements Iterator<T> {
        private Node<T> current = head;
        @Override
        public boolean hasNext() {

            return current != null;
        }
        @Override
        public T next() {
            T item = current.item;
            current = current.next;
            return item;
        }
    }
}
栈基本实现:
/**
 * 栈是一种基于先进后出策略的集合模型,在表头插入元素
 * 
 * @author xzm
 *
 */
public class StackMain<T> implements Iterable<T> {
    private Node<T> head; // 表头节点
    private int count;
    private static class Node<T> {
        private T item;
        private Node<T> next;
    }
    public StackMain() {
        head = null;
        count = 0;
    }
    /**
     * 表头添加一个元素
     */
    public void push(T item) {
        Node<T> oldhead = head;
        head = new Node<T>();
        head.item = item;
        head.next = oldhead;
        count++;
    }
    /**
     * 删除最近添加的元素
     * 
     * @return
     */
    public T pop() {
        T item = head.item;
        head = head.next;
        count--;
        return item;
    }
    public boolean isEmpty() {
        return head == null;
    }
    public int size() {
        return count;
    }
    @Override
    public Iterator<T> iterator() {
        return new StackIterator();
    }
    private class StackIterator implements Iterator<T> {
        private Node<T> currnet = head;
        @Override
        public boolean hasNext() {
            return currnet != null;
        }
        @Override
        public T next() {
            T item = currnet.item;
            currnet = currnet.next;
            return item;
        }
    }
}
双向链表基本实现:
/**
 * 双向链表
 * 
 * @author xzm
 *
 * @param <T>
 */
public class BidirectionalLinkedListMain<T> implements Iterable<T> {
    private DoubleNode<T> head;
    private DoubleNode<T> tail;
    private int count;
    private static class DoubleNode<T> {
        private T item;
        private DoubleNode<T> previousNode; // 前驱节点
        private DoubleNode<T> posteriorNode; // 后驱节点
    }
    public BidirectionalLinkedListMain() {
        head = null;
        tail = null;
        count = 0;
    }
    /**
     * 首部插入元素
     * 
     * @param item
     */
    public void insertAtHead(T item) {
        DoubleNode<T> oldhead = head;
        head = new DoubleNode<>();
        head.item = item;
        head.posteriorNode = oldhead;
        head.previousNode = null;
        if (isEmpty()) {
            tail = head;
        } else if (oldhead != null) {
            oldhead.previousNode = head;
        }
        count++;
    }
    /**
     * 尾部插入元素
     * 
     * @param item
     */
    public void insertAtTail(T item) {
        DoubleNode<T> oldtail = tail;
        tail = new DoubleNode<>();
        tail.item = item;
        tail.posteriorNode = null;
        tail.previousNode = oldtail;
        if (isEmpty())
            head = tail;
        else if (oldtail != null) {
            oldtail.posteriorNode = tail;
        }
        count++;
    }
    /**
     * 首部删除元素
     * 
     * @return
     * @throws NoElementException
     */
    public T delectAtHead() throws NoElementException {
        if (count <= 0)
            throw new NoElementException("链表中没有元素,首部删除失败");
        T item = head.item;
        if (size() == 1) {
            System.out.println("链表中只有一个元素");
            tail = head = null;
        } else {
            DoubleNode<T> newhead = head.posteriorNode;
            newhead.previousNode = null;
            head.posteriorNode = null;
            head = newhead;
        }
        count--;
        return item;
    }
    /**
     * 尾部删除元素
     * 
     * @return
     * @throws NoElementException
     */
    public T delectAtTail() throws NoElementException {
        if (count <= 0)
            throw new NoElementException("链表中没有元素,尾部删除失败");
        T item = tail.item;
        if (size() == 1) {
            System.out.println("链表中只有一个元素");
            head = tail = null;
        } else {
            DoubleNode<T> newtail = tail.previousNode;
            newtail.posteriorNode = null;
            tail.previousNode = null;
            tail = newtail;
        }
        count--;
        return item;
    }
    /**
     * 在某个节点之前插入元素,注意更新在首部插入节点时,更新head指针
     * 
     * @param data
     *            节点的值
     * 
     * @param insertItem
     *            插入的值
     * @throws NoElementException 
     */
    public boolean insertBeforeNode(T data, T insertItem) throws NoElementException {
        if (count <= 0)
            throw new NoElementException("链表中没有元素,插入失败");
        
        DoubleNode<T> other = head;
        while (other != null) {
            if (other.item.equals(data)) {
                DoubleNode<T> insert = new DoubleNode<>();
                insert.item = insertItem;
                insert.posteriorNode = other;
                insert.previousNode = other.previousNode;
                other.previousNode = insert;
                if (insert.previousNode != null) {
                    insert.previousNode.posteriorNode = insert;
                } else
                    head = insert;
                count++;
                return true;
            }
            other = other.posteriorNode;
        }
        System.out.println("没有找到值为" + data + "的节点,插入失败");
        return false;
    }
    /**
     * 在某个节点之前插入元素,注意在尾部插入节点时,更新tail指针
     * 
     * @param data
     *            节点的值
     * 
     * @param insertItem
     *            插入的值
     * @throws NoElementException 
     */
    public boolean insertAfterNode(T data, T insertItem) throws NoElementException {
        
        if (count <= 0)
            throw new NoElementException("链表中没有元素,插入失败");
        
        DoubleNode<T> other = head;
        while (other != null) {
            if (other.item.equals(data)) {
                DoubleNode<T> insert = new DoubleNode<>();
                insert.item = insertItem;
                insert.previousNode = other;
                insert.posteriorNode = other.posteriorNode;
                other.posteriorNode = insert;
                if (insert.posteriorNode != null)
                    insert.posteriorNode.previousNode = insert;
                else
                    tail = insert;
                count++;
                return true;
            }
            other = other.posteriorNode;
        }
        System.out.println("没有找到值为" + data + "的节点,插入失败");
        return false;
    }
    /**
     * 删除某个节点
     * 
     * @param data
     *            节点的值,从链表首部开始计算
     * @throws NoElementException
     */
    public boolean delectNode(int data) throws NoElementException {
        if (count <= 0)
            throw new NoElementException("链表中没有元素,无法删除元素");
        
        DoubleNode<T> other = head;
        while (other != null) {
            if (other.item.equals(data)) {
                if(size() == 1){
                    tail = head = null;
                }else if (other.previousNode == null) {
                    DoubleNode<T> newhead = head.posteriorNode;
                    newhead.previousNode = null;
                    other.posteriorNode = null;
                    head = newhead;
                } else if (other.posteriorNode == null) {
                    DoubleNode<T> newtail = other.previousNode;
                    newtail.posteriorNode = null;
                    other.previousNode = null;
                    tail = newtail;
                } else {
                    other.previousNode.posteriorNode = other.posteriorNode;
                    other.posteriorNode.previousNode = other.previousNode;
                    other.previousNode = null;
                    other.posteriorNode = null;
                }
                count--;
                return true;
            }
            other = other.posteriorNode;
        }
        System.out.println("没有找到值为" + data + "的节点,删除失败");
        return false;
    }
    public boolean isEmpty() {
        return count == 0;
    }
    public int size() {
        return count;
    }
    @Override
    public Iterator<T> iterator() {
        return new BidirectionalIterator();
    }
    private class BidirectionalIterator implements Iterator<T> {
        private DoubleNode<T> current = head;
        @Override
        public boolean hasNext() {
            return current != null;
        }
        @Override
        public T next() {
            T item = current.item;
            current = current.posteriorNode;
            return item;
        }
    }
} 
双向链表基本测试代码:
		BidirectionalLinkedListMain<Integer> listMain = new BidirectionalLinkedListMain<>();
		
		System.out.println("首部插入1");
		listMain.insertAtHead(1);
		System.out.println("isEmpyt: " + listMain.isEmpty() + " size: " + listMain.size());
		for (Integer integer : listMain) {
			System.out.print(" " + integer);
		}
		System.out.println();
		
		System.out.println("尾部插入3");
		listMain.insertAtTail(3);
		System.out.println("isEmpyt: " + listMain.isEmpty() + " size: " + listMain.size());
		for (Integer integer : listMain) {
			System.out.print(" " + integer);
		}
		System.out.println();
		
		System.out.println("在3之后插入4");
		listMain.insertAfterNode(3, 4);
		System.out.println("isEmpyt: " + listMain.isEmpty() + " size: " + listMain.size());
		for (Integer integer : listMain) {
			System.out.print(" " + integer);
		}
		System.out.println();
		
		System.out.println("3之前插入5");
		listMain.insertBeforeNode(3,5);
		System.out.println("isEmpyt: " + listMain.isEmpty() + " size: " + listMain.size());
		for (Integer integer : listMain) {
			System.out.print(" " + integer);
		}
		System.out.println();
		
		System.out.println("删除4");
		listMain.delectNode(4);
		System.out.println("isEmpyt: " + listMain.isEmpty() + " size: " + listMain.size());
		for (Integer integer : listMain) {
			System.out.print(" " + integer);
		}
		System.out.println();
输出结果:
测试双向链表
首部插入1
isEmpyt: false size: 1
 1
尾部插入3
isEmpyt: false size: 2
 1 3
在3之后插入4
isEmpyt: false size: 3
 1 3 4
3之前插入5
isEmpyt: false size: 4
 1 5 3 4
删除4
isEmpyt: false size: 3
 1 5 3
以上。







评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值