大數據算法系列3:基本數據結構及應用 一. 數據結構 二. 棧 三. 隊列 四. 棧和棧實戰 參考:

一. 數據結構

1.1 指針的原理

1.2 鏈表

鏈表的基本操作:

鏈表 VS 數組:
數組的長度是固定的,而且存儲二項式很麻煩,所以底層用鏈表比較多。

棧和隊列 都是通過 鏈表或數組來實現的

二. 棧

棧的應用:

  1. 函數或子程序調用
  2. 博弈樹遍歷
  3. 編輯器undo實現

三. 隊列

四. 棧和棧實戰

4.1 棧實戰

http://poj.org/problem?id=2559

package com.suanfa.棧;

import java.util.Stack;

public class 最大矩形面積 {
    public static void main(String[] args) {
        int[] arr1 = {8,7,6,5,4,3,2};
        int rst = 0;
        rst = largestRectangleArea(arr1);
        System.out.println(rst);
        //bubbleSort2(arr1);
    }

    /**
     * 遍歷數組
     * 1.棧爲空則入棧
     * 2.若h[i]>=棧頂元素,入棧
     * 3.若h[i]<棧頂元素,則開始出棧計算面積,並將最後出棧的h[x]值改爲h[i]再重新入棧
     *
     * @param heights 數組,本例會創建個新數組,在數組最後一個位置補個高度爲0的圖
     * @return 最大面積值
     */
    public static int largestRectangleArea(int[] heights) {
        int max = 0;
        Stack<Integer> s = new Stack<>();
        int [] h = new int[heights.length + 1];
        for (int i =0; i < h.length; i++) {
            h[i] = i == heights.length ? 0 : heights[i];
            //System.out.println("i="+i);
            //System.out.println("h[i]=" + h[i]);
            if (s.empty()) {
                //空棧直接入棧
                s.push( i );
                continue;
            }

            //System.out.println("h[s.peek()]:"+h[s.peek()]);
            if (h[i] < h[s.peek()]) {
                //遇到小於棧頂的值,開始出棧,查找最大面積
                int top = 0;
                while (!s.empty() && h[s.peek()] > h[i]) {
                    //top等於棧移出的元素的值
                    top = s.pop();
                    max = Math.max(( i - top ) * h[top], max);
                    //System.out.println("top="+top);
                    //System.out.println("h[top]="+h[top]);
                    //System.out.println("max="+max);

                }
                //將最後出棧的高度改爲h[i]重新入棧
                h[top] = h[i];
                System.out.println("top=" + top + ",");
                s.push( top );
                s.push( i );
            } else {
                s.push( i );
            }

            /*for (Integer s1 : s) {
                System.out.print("棧:"+s1+",");
                System.out.println();
            }*/
            //System.out.println("===================================");

        }
        return max;
    }
}

4.2 隊列實戰

http://poj.org/problem?id=2259

題意:
維護一個team queue,每次入隊列,如果跟這個元素在一個隊裏的元素已經在這個大隊裏,那麼這個元素可以插到他們隊友的後面。給出有幾個隊以及這些隊裏面包含的元素,輸出要求出隊的時候的元素。

分析:
按照題目輸入的順序,給隊編號。因爲屬於同一個隊的可以插隊,所以在隊列中,同一個隊的必然在一起。所以一個總的隊列,只用記錄下來隊伍的編號就可以了,再記錄下來每個隊伍中的順序。

代碼:

package com.suanfa.隊列;

import java.util.*;

public class TeamQueue {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        TeamQueue tq = new TeamQueue();
        int count = 1;
        while (true) {
            List<Set<String>> listSet = new ArrayList<Set<String>>();
            List<Queue<String>> listQueue = new ArrayList<Queue<String>>();
            Queue<Integer> indexs = new LinkedList<Integer>();

            int n = sc.nextInt();
            if (n == 0) {
                break;
            }
            for (int i = 0; i < n; i++) {
                int m = sc.nextInt();
                Queue queue = new LinkedList();
                listQueue.add(queue);
                Set<String> set = new HashSet<String>();
                listSet.add(set);
                for (int j = 0; j < m; j++) {
                    listSet.get(i).add(sc.next());
                }
            }
            System.out.println("Scenario #" + count);
            count++;
            while (true) {
                String str = sc.next();
                if (str.equals("ENQUEUE")) {//入隊
                    String num = sc.next();
                    tq.add(num, listQueue, listSet, indexs);
                } else if (str.equals("DEQUEUE")) {//出隊
                    System.out.println(tq.remove(listQueue, indexs));
                } else if (str.equals("STOP")) {//結束
                    break;
                }
            }
            System.out.println();
        }
    }

    public void add(String num, List<Queue<String>> listQueue, List<Set<String>> listSet, Queue<Integer> indexs) {//入隊
        int index = select(listSet, num);
        if (listQueue.get(index).isEmpty()) {
            indexs.add(index);
            listQueue.get(index).add(num);
        } else {
            listQueue.get(index).add(num);
        }

    }

    public String remove(List<Queue<String>> listQueue, Queue<Integer> indexs) {//出隊
        while (true) {
            int index = indexs.peek();
            String str = listQueue.get(index).poll();
            if (listQueue.get(index).isEmpty()) {
                indexs.remove();
            }
            return str;
        }
    }


    public int select(List<Set<String>> listSet, String num) {//選隊
        for (int i = 0; i < listSet.size(); i++) {
            if (listSet.get(i).contains(num)) {
                return i;
            }
        }
        return -1;
    }
}

參考:

  1. http://www.dataguru.cn/article-5747-1.html
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章