MinStack

Design a stack that supports push, pop, top, and retrieving the minimum element in constant time.

  • push(x) -- Push element x onto stack.
  • pop() -- Removes the element on top of the stack.
  • top() -- Get the top element.
  • getMin() -- Retrieve the minimum element in the stack.

题目的意思是实现一个栈,能够实现推入,推出,返回顶端元素,获得最小元素的功能

 

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());
    }
}

  

 

拓  展


 

图片来自于维基

堆栈(英语stack),也可直接称栈 由于堆栈数据结构只允许在一端进行操作,因而按照后进先出(LIFO, Last In First Out)的原理运作。栈空间有操作系统自动分配,使用完成后有编译器自动释放,通常用来存放函数的参数值、局部变量的值等。

栈使用的是靠近ALU的一级缓存,他们通常是在调用时处于存储空间中,调用完毕后就会立即释放。与“堆(Heap)"不同,堆内存有程序员释放那个,存放于二级缓存中,结构类似于链表,程序员分配时内存变量的值不一定是连续的,因此,堆处理的速度相比与栈来说速度要慢一些!

 

(截图来自 计算机系统概论)

如图所示,a)有5个连续的存储空间,每个存储单元为1个字节(这也是目前操作系统内存结构的排列方式,类似于一个大的字节数组)。R6代表栈顶寄存器,用来存储栈顶元素的指针。b)当往栈中push一个元素18以后,栈顶元素指针加1,其他地址不变。c)往栈中压入3个元素后的结果,可以看到不断修改栈顶指针的大小。d)弹出2个元素的结果

下面我们用Java代码实现栈,前文已经说明,实现栈的方式可以有数组,也可以有链表来实现(因为这两个数据结构都是线性结构)

Java的SDK中封装好的有一个Stack,他的常用方法有

empty()

Tests if this stack is empty
peek()
Looks at the object at the top of this stack without removing it from the stack.
pop()
Removes the object at the top of this stack and returns that object as the value of this function.
push(E item)
Pushes an item onto the top of this stack.
栈的数组实现:
/**
 * 栈的数组实现方式
 * @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给出了比较好的解释。

 
 

 

posted @ 2014-11-23 21:59  CBDoctor  阅读(901)  评论(0编辑  收藏  举报