<数据结构基础学习>(四)链表 Part 2
一.使用链表实现栈
增,删,查只对链表头进行操作,时间复杂度都为O(1)
链表头作为栈顶
LinkedListStack<E> implements Stack<E>
public class LinkedListStack<E> implements Stack<E> {
    private LinkedList<E> list;
    public LinkedListStack(){
        list = new LinkedList<>();
    }
    @Override
    public int getSize() {
        return list.getSize();
    }
    @Override
    public boolean isEmpty() {
        return list.isEmpty();
    }
    @Override
    public void push(E e) {
        list.addFirst(e);
    }
    @Override
    public E pop() {
        return list.removeFirst();
    }
    @Override
    public E peek() {
        return list.getFirst();
    }
    @Override
    public String toString() {
        StringBuilder res = new StringBuilder();
        res.append("Stack: top");
        res.append(list);
        return res.toString();
    }
}
二.使用链表实现队列

从两端添加元素很容易
从tail端删除元素不容易
所以,从head端删除元素,从tail端插入元素
不使用虚拟头节点,因为不从中间插入元素
由于没有设置dummyHead,要注意链表为空的情况
以下来设计方法:
新建一个类LinkedListQueue<E> implements Queue<e>
1.内部类Node
public class LinkedListQueue<E> implements Queue<E>{
    private class Node{
        public E e;
        public Node next;
        public Node(E e, Node next){
            this.e = e;
            this.next = next;
        }
        public Node(E e){
            this(e, null);
        }
        public Node(){
            this(null,null);
        }
        @Override
        public String toString() {
            return super.toString();
        }
    }
2.基本成员变量
private Node head, tail;
private int size;
3.基本方法
   public LinkedListQueue(){
        head = null;
        tail = null;
        size = 0;
    }
    @Override
    public int getSize() {
        return size;
    }
    @Override
    public boolean isEmpty() {
        return size == 0;
    }
4.入队操作
a.先判断tail是否为空,直接有tail = new Node(e),令head = tail。
b.否则有tail.next = new Node(e),tail = tail.next。
c.最后维护size,size ++。
@Override
public void enqueue(E e) {
if(tail == null){
tail = new Node(e);
head = tail;
}else{
tail.next = new Node(e);
tail = tail.next;
}
size ++;
}
5.出队操作
a.先判断队列是否为空,若为空则抛出异常
b.先令头节点Node retNode = head;
让头节点指向原头节点的next,head = head.next
令retNode与链表断开,即retNode.next = null
c.如果原来队列里只有一个元素,此时head == null,则需要维护tail,使tail = null
d.最后维护size,size --,并返回retNode.e
@Override
public E dequeue() {
if(isEmpty())
throw new IllegalArgumentException("Cannot dequeue from an empty queue"); Node retNode = head;
head = head.next;
retNode.next = null; //原来只有一个元素
if(head == null){
tail = null;
}
size --;
return retNode.e;
}
6.查看队首元素
@Override
public E getFront() {
if(isEmpty())
throw new IllegalArgumentException("Cannot dequeue from an empty queue");
return head.e;
}
7.重写toString()方法
@Override
public String toString() {
StringBuilder res = new StringBuilder();
// Node cur = dummyhead.next;
// while(cur != null){
// res.append(cur+"->");
// cur = cur.next;
// }
res.append("Queue: front:");
for(Node cur = head ; cur != null ; cur = cur.next){
res.append(cur + "—>");
}
res.append("NULL tail");
return res.toString();
}
<数据结构基础学习>(四)链表 Part 2的更多相关文章
- Python基础学习四
		Python基础学习四 1.内置函数 help()函数:用于查看内置函数的用途. help(abs) isinstance()函数:用于判断变量类型. isinstance(x,(int,float) ... 
- <数据结构基础学习>(四)链表 Part 1
		一.链表基础 动态数组.栈.队列底层都是依托静态数组实现的,靠resize来解决固定容量问题. 链表是真正的动态数据结构,是一种最简单的一种动态数据结构. 更深入的理解引用(或者指针). 更深入的理解 ... 
- Java数据结构和算法(四)--链表
		日常开发中,数组和集合使用的很多,而数组的无序插入和删除效率都是偏低的,这点在学习ArrayList源码的时候就知道了,因为需要把要 插入索引后面的所以元素全部后移一位. 而本文会详细讲解链表,可以解 ... 
- C语言数据结构基础学习笔记——树
		树是一种一对多的逻辑结构,树的子树之间没有关系. 度:结点拥有的子树数量. 树的度:树中所有结点的度的最大值. 结点的深度:从根开始,自顶向下计数. 结点的高度:从叶结点开始,自底向上计数. 树的性质 ... 
- Mybatis基础学习(四)—关系映射
		一.模型分析 user和orders user---->orders 一个用户可以创建多个订单,一对多. orders--->user 一个订单只由一个用户创建,一对一. orders ... 
- <数据结构基础学习>(三)Part 2 队列
		一.队列 Queue 队列也是一种线性结构 相比数组,队列对应的操作是数组的子集 只能从一端(队尾)添加元素,只能从另一端(队首)取出元素. (排队) 队列是一种先进先出的数据结构(先到先得)FIFO ... 
- <数据结构基础学习>(三)Part 1 栈
		一.栈 Stack 栈也是一种线性的数据结构 相比数组,栈相对应的操作是数组的子集. 只能从一端添加元素,也只能从一端取出元素.这一端成为栈顶. 1,2,3依次入栈得到的顺序为 3,2,1,栈顶为3, ... 
- Node.js基础学习四之注册功能
		前言:在Node.js学习(二)和(三)中介绍了如何在Node.js 中获取登录的用户名和密码与数据库进行验证并返回数据给客户端 需求:实现注册功能 为了区分登录和注册是两个不同的请求,在端口后面加上 ... 
- C语言数据结构基础学习笔记——B树
		2-3树:是一种多路查找树,包含2结点和3结点两种结点,其所有叶子结点都在同一层次. 2结点:包含一个关键字和两个孩子(或没有孩子),其左孩子的值小于该结点,右孩子的值大于该结点. 3结点:包含两个关 ... 
随机推荐
- LEDAPS1.3.0版本移植到windows平台----HuPm参数初始化模块
			这个是2012年左右放在百度空间的,谁知百度空间关闭...转移到博客园. 最近项目用到3.1.2版本的LEDAPS,新版本的使用情况会在后续文章中慢慢丰富. LEDAPS的调用顺序是:HuPm--&g ... 
- SpringBoot数据库读写分离之基于Docker构建主从数据库同步实例
			看了好久的SpringBoot结合MyBatista实现读写,但是一直没有勇气实现他,今天终于接触到了读写分离的东西,读写分离就是讲读操作执行在Slave数据库(从数据库),写操作在Master数据库 ... 
- C#List<object>排序
			//定义一个集合 var list = new List<Object>();//这里的Object为对象类型 //假设list已经有数据存进去,根据对象的某个字段升序或降序 var or ... 
- .net向文件写入字符串流内存溢出的问题
			字符串过大导致抛出异常: exceptopm of type 'system.outOfmemoryexception' was thrown 解决方法:逐块写入可以避免这个问题 
- Linux内存描述之内存节点node--Linux内存管理(二)
			1 内存节点node 1.1 为什么要用node来描述内存 这点前面是说的很明白了, NUMA结构下, 每个处理器CPU与一个本地内存直接相连, 而不同处理器之前则通过总线进行进一步的连接, 因此相对 ... 
- c/c++ linux 进程间通信系列3,使用socketpair,pipe
			linux 进程间通信系列3,使用socketpair,pipe 1,使用socketpair,实现进程间通信,是双向的. 2,使用pipe,实现进程间通信 使用pipe关键点:fd[0]只能用于接收 ... 
- Python爬虫之正则表达式(2)
			# 最常规的匹配 import re content = 'Hello 123 4567 World_This is a Regex Demo' print(len(content)) result ... 
- windows批处理添加AD域账户
			因为要用个批处理命令在Windows Server里面批量添加域用户,所以需要使用批处理命令. 我这篇是纯新手教程,在百度上搜了一些批处理命令感觉属于进阶教程,研究了两天才完成我要完成的目标. 下面从 ... 
- LVS负载均衡基础介绍及NET、DR模式配置
			LVS:术语: CIP:Client IP:客户端IP: VIP:Virtual Server IP:虚拟主机对外IP: RIP:Real Server IP:真实主机IP: DIP:Director ... 
- JetBrains 注册码
			C40PF37RR0-eyJsaWNlbnNlSWQiOiJDNDBQRjM3UlIwIiwibGljZW5zZWVOYW1lIjoiemhhbmcgeW9uZyIsImFzc2lnbmVlTmFtZ ... 
