Design a stack that supports push, pop, top, and retrieving the minimum element in constant time.html
題目的意思是實現一個棧,可以實現推入,推出,返回頂端元素,得到最小元素的功能java
public class MinClass { private Stack<Integer> a = new Stack<Integer>() ; private Stack<Integer> minStack = new Stack<Integer>(); public void push(int x) { /** * 判斷最小棧,若是棧爲空或者壓入的棧值小於棧頂元素,將x壓入最小棧 */ if(minStack.isEmpty() || x<minStack.peek()){ minStack.push(x); } a.push(x); } public void pop() { /** * 若是不相等,會把minStack中保存的最小值給推出。因此必須保證minStack中推出 * 的值必須和a中的值同樣 */ if(minStack.peek().equals(a.peek())){ minStack.pop(); } a.pop(); } public int top() { return a.peek(); } public int getMin() { return minStack.peek(); } /** * 測試 */ public static void main(){ MinClass obj = new MinClass(); obj.push(10); obj.push(20); obj.pop(); obj.push(30); System.out.println(obj.getMin()); } }
拓 展node
圖片來自於維基程序員
堆棧(英語:stack),也可直接稱棧 因爲堆棧數據結構只容許在一端進行操做,於是按照後進先出(LIFO, Last In First Out)的原理運做。棧空間有操做系統自動分配,使用完成後有編譯器自動釋放,一般用來存放函數的參數值、局部變量的值等。api
棧使用的是靠近ALU的一級緩存,他們一般是在調用時處於存儲空間中,調用完畢後就會當即釋放。與「堆(Heap)"不一樣,堆內存有程序員釋放那個,存放於二級緩存中,結構相似於鏈表,程序員分配時內存變量的值不必定是連續的,所以,堆處理的速度相比與棧來講速度要慢一些!數組
(截圖來自 計算機系統概論)緩存
如圖所示,a)有5個連續的存儲空間,每一個存儲單元爲1個字節(這也是目前操做系統內存結構的排列方式,相似於一個大的字節數組)。R6表明棧頂寄存器,用來存儲棧頂元素的指針。b)當往棧中push一個元素18之後,棧頂元素指針加1,其餘地址不變。c)往棧中壓入3個元素後的結果,能夠看到不斷修改棧頂指針的大小。d)彈出2個元素的結果安全
下面咱們用Java代碼實現棧,前文已經說明,實現棧的方式能夠有數組,也能夠有鏈表來實現(由於這兩個數據結構都是線性結構)數據結構
Java的SDK中封裝好的有一個Stack,他的經常使用方法有oracle
empty()
peek()
pop()
push(E item)
/** * 棧的數組實現方式 * @author CYW */ public class ArrayStack { private long[] stackArray;//數組 private int stackSize;//記錄存儲記錄的最大的條數 private int top = -1;//記錄棧頂位置 // 記錄分配存儲空間的大小 public ArrayStack(int s){ stackArray = new long[s]; top = -1; stackSize = s; } public long pop(){ return stackArray[top--]; } public void push(int x){ stackArray[++top] = x; } public long peek(){ return stackArray[top]; } public boolean isEmpty(){ return (stackArray.length == 0); } // 測試 public static void main(){ ArrayStack obj = new ArrayStack(100); obj.push(100); obj.push(20); obj.push(10); obj.push(200); obj.push(1000); obj.pop(); /** * */ for (int i = 0;i<obj.top;i++){ System.out.println(obj.stackArray[i]); } } }
須要注意的一點是:咱們在輸出數組元素的時候不能根據數組的長度來判斷,而必須根據站頂的top來判斷!
C++代碼
struct Node{ struct Node* pPre; int data; }; class ListStack{ private: //定義指向棧頂元素的指針 struct Node *top; public: void push(int data){ //建立新的變量 struct Node *node = new struct Node(); node->data = data; node->pPre = top; //從新定義top的指向 top = node; } int pop(){ //從新定義top的指向 int temp = top->data; top =top->pPre; //返回輸出結果 return temp; } int peek(){ return top->data; } //判斷是否爲空 bool isEmpty(){ if(top){ return true; }else{ return false; } } }; int _tmain(int argc, _TCHAR* argv[]) { ListStack stack; stack.push(10); stack.push(20); stack.push(30); stack.push(40); stack.push(50); cout<<stack.pop()<<endl; cout<<stack.peek()<<endl; cout<<stack.pop()<<endl; cout<<stack.pop()<<endl; cout<<stack.pop()<<endl; cout<<stack.peek()<<endl; cout<<stack.pop()<<endl; if(stack.isEmpty()){ cout<<"棧中數據爲空!"<<endl; }else{ stack.pop(); } return 0; }
固然,上面代碼中有不少不安全的地方,僅僅是學習的目的,http://shmilyaw-hotmail-com.iteye.com/blog/1825171 從Java給出了比較好的解釋。