android队列和栈的区别,《算法》- 队列和栈

一、队列: 先进先出(FIFO),例如超市的收银台、排队买票的顾客。在Java中,它和List的区别在于,List能够在任意位置添加和删除元素,而Queue只有两个操做:java

把元素添加到队列末尾;

从队列头部取出元素。

二、栈: 下压栈,后进先出(LIFO),例如你办公桌上的一叠信件,新信件来时将它们放在最上面(push方法),当阅读时从上到下取件(pop方法)。node

三、双栈算术表达式求值:

例如计算(1+((2+3)*(4*5)))的值:用两个栈,一个保存运算符(运算符栈),一个保存数字(操做数栈)。算法

从左到右逐个将实体送入栈处理:

一、遇到数字时,将数字压入操做数栈,遇到运算法时,压入运算符栈;

二、遇到左括号时忽略;

三、遇到右括号,弹出一个运算符,弹出所需数量的数字,并将运算符和数字的运算结果压入操做数栈。数组

6d0e94c64e28a6fc2832f39b6bd547c7.png

双栈算术表达式求值算法(为了代码简洁未考虑异常):数据结构

import java.util.Stack;

public class EvaluateTest {

public static void main(String[] args) {

// 须要计算的表达式

String str = "(1+((2+3)*(4*5)))".trim();

// 运算符栈和操做数栈

Stack ops = new Stack<>();

Stack vals = new Stack<>();

for(int i=0;i < str.length();i++) {

String s = String.valueOf(str.charAt(i));

if(s.equals("(")){

// 左括号时忽略

}else if(s.equals("+") || s.equals("-") || s.equals("*") || s.equals("/") || s.equals("sqrt")){

// 运算符时压运算符栈

ops.push(s);

}else if(s.equals(")")){

// 右括号时,将两个栈都pop,再计算、压栈

String op = ops.pop();

Double v = vals.pop();

if(op.equals("+")){

v = vals.pop() + v;

}else if(op.equals("-")){

v = vals.pop() - v;

}if(op.equals("*")){

v = vals.pop() * v;

}if(op.equals("/")){

v = vals.pop() / v;

}if(op.equals("sqrt")){

v = Math.sqrt(v);

}

vals.push(v);

}else{

// 最后是数字时,转为double压入操做数栈

vals.push(Double.valueOf(s));

}

}

System.out.println("最终运算结果:" + vals.pop());

}

}

四、链表

链表是一种递归的数据结构,它能够为空(null),能够是指向一个节点(node)的引用。该节点包含一个元素(数据域,储存节点含有的信息)和一个指向另外一条链表或节点的引用(引用域)。lua

链表的特色:3d

插入和删除元素方便;

查找数据时效率低,访问某个位置的数据要从第一个节点开始访问,根据第一个节点保存的下一个节点的地址找到第二个节点,以此类推;

能够看完下面的流程再来理解它的特色。这里主要介绍单向链表:code

// 一个节点

public class Node {

public Object item;

public Node next;

}

伪代码构造一条链表:

4545e5e9df9d5e116046fc7d2b47a609.png对象

建立好链表后,在表头插入一个节点很容易,以下图,若是在表头插入字符串"not",先将first保存在oldfirst中,而后将一个新节点赋给first,并将它的item元素设为not,next设为oldfirst。

c4e5cf361bdee75e14cee11ea25ae07a.pngblog

在表头删除一个节点,将first指向first.next便可。曾经的第一个节点对象变成了一个孤儿,Java的内存管理最终将回收它所占用的内存:

8a2f305b9c6fb4f43fd5741eacd95e6f.png

请注意:当链表中只有一个节点时,它既是首节点又是尾节点,另外注意链表为空的状况。

那么在表尾插入节点能够表示为:

d002723102dd0132206c2f9cd3468892.png

之前链表操做只须要几行赋值代码,所需时间和链表的长度无关。但若是须要删除表尾节点,就要遍历整条链表并找出指向last节点的节点,这样所需的时间和链表的长度成正比。

要想实现任意插入和删除操做,能够使用双向链表,这里不做介绍。

五、遍历链表 咱们知道遍历数组能够用for(int i = 0; i < N; i++){...};那么遍历链表也有一个对应方式:

for (Node x = first; x != null; x = x.next) {

// 处理 x.item

}

六、堆栈的链表实现

直接上代码:

import java.util.Iterator;

import java.util.NoSuchElementException;

public class Stack implements Iterable {

private Node first; // 栈顶(最近添加的元素)

private int n; // 元素数量

private static class Node {

private Item item;

private Node next;// 定义了节点的嵌套类

}

/**

* Initializes an empty stack.

*/

public Stack() {

first = null;

n = 0;

}

/**

* 当first==null或者n==0时,栈是空的

*/

public boolean isEmpty() {

return first == null;

}

public int size() {

return n;

}

/**

* 向栈顶添加元素

*/

public void push(Item item) {

Node oldfirst = first;

first = new Node();

first.item = item;

first.next = oldfirst;

n++;

}

/**

* 从栈顶删除元素

*/

public Item pop() {

if (isEmpty()) throw new NoSuchElementException("Stack underflow");

Item item = first.item;

first = first.next;

n--;

return item;

}

/**

* 只取值,不删除

*/

public Item peek() {

if (isEmpty()) throw new NoSuchElementException("Stack underflow");

return first.item;

}

/**

* 按照LIFO的顺序,返回一个迭代器能够迭代此类

*/

public Iterator iterator() {

return new LinkedIterator(first);

}

private class LinkedIterator implements Iterator {

private Node current;

public LinkedIterator(Node first) {

current = first;

}

public boolean hasNext() {

return current != null;

}

public void remove() {

throw new UnsupportedOperationException();

}

public Item next() {

if (!hasNext()) throw new NoSuchElementException();

Item item = current.item;

current = current.next;

return item;

}

}

}

七、队列的链表实现

Queue的实现使用的数据结构和Stack类相同,都是链表,但它实现了不一样的添加和删除算法,这也是FIFO和LIFO的区别所在。

import java.util.Iterator;

import java.util.NoSuchElementException;

public class Queue implements Iterable {

private Node first; // 指向最先添加的节点的引用

private Node last; // 队尾,最近添加

private int n;

private static class Node {

private Item item;

private Node next;

}

public Queue() {

first = null;

last = null;

n = 0;

}

public boolean isEmpty() {

return first == null;

}

public int size() {

return n;

}

/**

* 向表尾添加元素

*/

public void enqueue(Item item) {

Node oldlast = last;

last = new Node();

last.item = item;

last.next = null;

if (isEmpty()){

first = last;

}else{

oldlast.next = last;

}

n++;

}

/**

* 从表头删除元素

*/

public Item dequeue() {

if (isEmpty()) throw new NoSuchElementException("Queue underflow");

Item item = first.item;

first = first.next;

n--;

if (isEmpty()) last = null;

return item;

}

/**

* 从表头获取元素,不删除

*/

public Item peek() {

if (isEmpty()) throw new NoSuchElementException("Queue underflow");

return first.item;

}

public Iterator iterator() {

return new LinkedIterator(first);

}

private class LinkedIterator implements Iterator {

private Node current;

public LinkedIterator(Node first) {

current = first;

}

public boolean hasNext() { return current != null; }

public void remove() { throw new UnsupportedOperationException(); }

public Item next() {

if (!hasNext()) throw new NoSuchElementException();

Item item = current.item;

current = current.next;

return item;

}

}

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值