欧博亚洲app下载:《算法》- 行列和栈

admin 2周前 (09-15) 科技 40 1

1、行列: 先进先出(FIFO),例如超市的收银台、排队买票的主顾。在JAVa中,它和List的区别在于,List可以在随便位置添加和删除元素,而Queue只有两个操作:

  • 把元素添加到行列末尾;
  • 从行列头部取出元素。

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

3、双栈算术表达式求值:
例如盘算(1+((2+3)*(4*5)))的值:用两个栈,一个保留运算符(运算符栈),一个保留数字(操作数栈)。

从左到右逐个将实体送入栈处置:
1、遇到数字时,将数字压入操作数栈,遇到运算法时,压入运算符栈;
2、遇到左括号时忽略;
3、遇到右括号,弹出一个运算符,弹出所需数目的数字,并将运算符和数字的运算效果压入操作数栈。

双栈算术表达式求值算法(为了代码简练未思量异常):

import java.util.Stack;

public class EvaluateTest {
    public static void mAIn(String[] args) {
        // 需要盘算的表达式
        String str = "(1+((2+3)*(4*5)))".trim();

        // 运算符栈和操作数栈
        Stack<String> ops = new Stack<>();
        Stack<Double> 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());
    }
}

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

链表的特点:

  • 插入和删除元素利便;
  • 查找数据时效率低,接见某个位置的数据要从第一个节点最先接见,凭据第一个节点保留的下一个节点的地址找到第二个节点,以此类推;

可以看完下面的流程再来明白它的特点。这里主要先容单向链表:

// 一个节点
public class Node {
    public Object item;
    public Node next;
}

伪代码组织一条链表:

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

在表头删除一个节点,将first指向first.next即可。曾经的第一个节点工具变成了一个孤儿,Java的内存治理最终将接纳它所占用的内存:
欧博亚洲app下载:《算法》- 行列和栈 第1张

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

那么在表尾插入节点可以示意为:
欧博亚洲app下载:《算法》- 行列和栈 第2张

以前链表操作只需要几行赋值代码,所需时间和链表的长度无关。但若是需要删除表尾节点,就要遍历整条链表并找出指向last节点的节点,这样所需的时间和链表的长度成正比。
要想实现随便插入和删除操作,可以使用双向链表,这里不作先容。

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

for (Node x = first; x != null; x = x.next) {
   // 处置 x.item
}

6、客栈的链表实现
直接上代码:

import java.util.Iterator;
import java.util.NoSuchElementException;

public class Stack<Item> implements IterABLe<Item> {
    private Node<Item> first;     // 栈顶(最近添加的元素)
    private int n;                // 元素数目

    private static class Node<Item> {
        private Item item;
        private Node<Item> 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<Item> oldfirst = first;
        first = new Node<Item>();
        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<Item> iterator() {
        return new LinkedIterator(first);
    }
    
    private class LinkedIterator implements Iterator<Item> {
        private Node<Item> current;

        public LinkedIterator(Node<Item> first) {
            current = first;
        }
        public boolean hasNext() {
            return current != null;
        }
        public void remove() {
            throw new UnsupportedOperatIZ*ONException();
        }
        public Item next() {
            if (!hasNext()) throw new NoSuchElementException();
            Item item = current.item;
            current = current.next;
            return item;
        }
    }
}

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

import java.util.Iterator;
import java.util.NoSuchElementException;

public class Queue<Item> implements Iterable<Item> {
    private Node<Item> first;    // 指向最早添加的节点的引用
    private Node<Item> last;     // 队尾,最近添加
    private int n;

    private static class Node<Item> {
        private Item item;
        private Node<Item> 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<Item> oldlast = last;
        last = new Node<Item>();
        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<Item> iterator()  {
        return new LinkedIterator(first);
    }

    private class LinkedIterator implements Iterator<Item> {
        private Node<Item> current;

        public LinkedIterator(Node<Item> 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;
        }
    }
}

相关文献:
Bags, Queues, and Stacks

,

欧博app下载

www.baodingxsls.com欢迎进入欧博app下载网站,欧博app下载网站是欧博官方网站。欧博app下载网站开放欧博注册、欧博代理、欧博电脑客户端、欧博app下载等业务。

皇冠APP声明:该文看法仅代表作者自己,与本平台无关。转载请注明:欧博亚洲app下载:《算法》- 行列和栈

网友评论

  • (*)

最新评论

  • 联博以太坊 2020-09-15 00:02:09 回复

    欧博亚洲客户端欢迎进入欧博亚洲客户端(Allbet Game):www.aLLbetgame.us,欧博官网是欧博集团的官方网站。欧博官网开放Allbet注册、Allbe代理、Allbet电脑客户端、Allbet手机版下载等业务。走一波走心评论

    1

站点信息

  • 文章总数:527
  • 页面总数:0
  • 分类总数:8
  • 标签总数:882
  • 评论总数:153
  • 浏览总数:3851