栈和队列

栈(stack)是一种后进先出(Last In First Out,LIFO)的数据结构。用栈做辅助可以实现深度优先算法。
队列(queue)是一种先进先出(First In First Out,LIFO)的数据结构。用队列做辅助可以实现广度优先算法。

一. 栈和队列的定义和简单操作的实现

栈的实现

  • 通过链表实现
/* 
 * 定义一个结点类 
 */ 
public class Node {
    Node next;
    int data;

    public Node(int data){
        this.data = data;
    }
}

/* 
 * 通过链表定义一个栈类,并且定义各种对栈操作的方法 
 */ 
public class Stack1 {
    public Node head;          //头指针
    int size = 0;              //栈的容量
    int count = 0;             //栈内元素个数

    //构造函数,生成一个指定容量的空栈
    public Stack1(int size){
        head = null;
        this.size = size;
    }

    //push方法(讲一个元素压入栈中)
    public void push(int data){
        if(isFull()){
            System.out.println("此栈已满!");
        }else{
            Node node = head;
            head = new Node(data);
            head.next = node;
            count += 1;
        }

    }

    //pop方法(将栈顶元素推出)
    public void pop(){
        head = head.next;
        count -= 1;
    }

    //peek方法(查看栈顶元素)
    public int peek(){
        if(this.isEmpty()){
            System.out.println("此栈为空!");
        }else{
            System.out.println("栈顶元素为:" + head.data);
        }
        return head.data;
    }

    //判断栈是否为空
    public boolean isEmpty(){
        if(count == 0)
            return true;
        return false;
    }

    //判断栈是否已满
    public boolean isFull(){
        if(count == size)
            return true;
        return false;
    }

    //遍历栈
    public void ShowAllElement(){
        Node node = head;
        for(int i = 0; i < count;i++){
            System.out.print(node.data + " ");
            node = node.next;
        }
        System.out.println();
    }
}
  • 通过数组实现
/* 
 * 通过数组定义一个栈类,并且定义各种对栈操作的方法 
 */
public class Stack2 {
    int size;              //栈的容量
    public int []stack;
    int top;               //栈顶位置

    //构造函数,生成一个指定大小的空栈
    Stack2(int size){
        this.size = size;
        stack = new int[size];
        top = -1;
    }

    //push方法(讲一个元素压入栈中)
    public void push(int data){
        if(isFull()){
            System.out.println("此栈已满!");
        }else{
            top += 1;
            stack[top] = data;
        }
    }

    //pop方法(将栈顶元素推出)
    public void pop(){
        if(isEmpty()){
            System.out.println("此栈为空!");
        }else{
            stack[top] = 0;
            top -= 1;
        }
    }

    //peek方法(查看栈顶元素)
    public int peek(){
        System.out.println(stack[top] + " ");
        return stack[top];
    }

    //判断栈是否为空
    public boolean isEmpty(){
        if(top == -1)
            return true;
        return false;
    }

    //判断栈是否为空
    public boolean isFull(){
        if(top == size-1)
            return true;
        return false;
    }

    //遍历栈
    public void showAllElement(){
        for(int i = top; i >= 0;i--){
            System.out.print(stack[i] + " ");
        }
        System.out.println();
    }
}

队列的实现

  • 通过链表实现
/* 
 * 定义一个结点类 
 */ 
public class Node {
    Node next;
    int data;

    public Node(int data){
        this.data = data;
    }
}

/* 
 * 通过链表定义一个队列类,并且定义各种对队列操作的方法 
 */
public class Queue1 {
    public Node head;          //头指针
    public Node tail;          //尾指针
    int size;                  //队列的最大长度
    int count;                 //队列内元素个数

    //定义一个指定最大长度的队列
    public Queue1(int size){
        head = null;
        tail = head;
        this.size = size;
        count = -1;
    }

    //进队方法(往队列中添加一个元素)
    public void enqueue(int data){
        if(isFull()){
            System.out.println("此队列已满!");
        }else{
            count += 1;
            Node node = new Node(data);
            if(head == null){
                head = node;
            }else{
                tail.next = node;
            }
            tail = node;
        }
    }

    //出队方法(移除最早进入队列的元素并返回出队的元素)
    public void dequeue(){
        if(isEmpty()){
            System.out.println("此队列为空!");
        }else{
            head = head.next;
            count -= 1;
        }
    }

    //p判断队列是否为空
    public boolean isEmpty(){
        if(count == -1)
            return true;
        return false;
    }

    //判断队列是否已满
    public boolean isFull(){
        if(count == size-1)
            return true;
        return false;
    }

    //遍历队列
    public void showAllElement(){
        Node node = head;
        if(isEmpty()){
            System.out.println("此队列为空!");
        }else{
            while(node != null){
                System.out.print(node.data + " ");
                node = node.next;
            }
            System.out.println();
        }
    }
}
  • 通过数组实现
/* 
 * 通过数组定义一个栈类,并且定义各种对栈操作的方法 
 */
public class Queue2 {
    int size;          //队列最大长度
    int []queue;
    int head;          //最初进入队列的元素位置


    public Queue2(int size){
        this.size = size;
        queue= new int[size];
        head = -1;
    }

    //进队方法(往队列中添加一个元素)
    public void enqueue(int data){
        if(isFull()){
            System.out.println("此队列已满!");
        }else{
            head += 1;
            int temp = head;
            for(int i = head; i > 0; i--){
                queue[temp] = queue[temp - 1];
                temp -= 1;
            }
            queue[0] = data;
        }
    }

    //出队方法(移除最早进入队列的元素并返回出队的元素)
    public void dequeue(){
        if(isEmpty()){
            System.out.println("此队列为空!");
        }else{
            queue[head] = 0;
            head -= 1;
        }
    }

    //判断队列是否为空
    public boolean isEmpty(){
        if(head == -1)
            return true;
        return false;
    }

    //判断队列是否已满
    public boolean isFull(){
        if(head == size-1)
            return true;
        return false;
    }

    //遍历队列
    public void showAllElement(){
        if(isEmpty()){
            System.out.println("此队列为空!");
        }else{
            for(int i = head; i >= 0; i--){
                System.out.print(queue[i] + " ");
            }
            System.out.println();
        }
    }
}

二. 面试中常见的栈和队列相关问题

(没有实现的,后续一一补充)

  1. 实现一个栈,要求Push(入栈),Pop(出栈),Min(返回最小值的操作)的时间复杂度为O(1)。

  2. 使用两个栈实现一个队列。

  3. 使用两个队列实现一个栈。

  4. 按照升序来输出栈内元素。

  5. 给定一个字符串,它只包含如下的字符:’(‘、’)’、’{‘、’}’、’[‘和’]’,判断输入的字符串是否是一个有效的圆括号字符串。例如,“(([]))”是有效的,而“(}”和“((”则不是。

  6. 给定一个二叉树,使用栈实现中序遍历。

  7. 不用递归实现汉诺塔问题

posted @ 2017-07-11 15:34  xs_zhou  阅读(119)  评论(0编辑  收藏  举报