3.2 栈的最小值

     《程序员面试金典》(第六版)习题:仅为记录一下以加强印象,不为商业用途,如有侵权请联系删除。以下源码和解释参考了书中源码以及解释。
     以下算法通过在栈中的每一个节点存储节点值以及当该节点为栈顶时整个栈的最小值,实现了求栈中最小值的函数 i n t    m i n i m u m ( ) int \;minimum() intminimum(),其时间复杂度为 O ( 1 ) O(1) O(1)。该算法的缺点是当栈中元素较多时浪费了较多空间。以下是实现代码和测试代码。测试结果如图1所示。

//实现代码
class NodeWithMin
{
    private:
		int value;
		int minimum;
    public:
		NodeWithMin(int v=0, int min=0)
		{
			value = v;
			minimum = min;
		}
		NodeWithMin operator=(NodeWithMin copyObject)
		{
			cout << "=;     ";
			this->value = copyObject.value;
			this->minimum = copyObject.minimum;
			return (*this);
		}
		int getValue()
		{
			return value;
		}
		int getMinimum()
		{
			return minimum;
		}
		void setValue(int va)
		{
			 value=va;
		}
		void setMinimum(int min)
		{
		     minimum=min;
		}
};

class MyStack
{
public:
	MyStack(int capacity=0)
	{
		stack_capacity = capacity;	
		values = new NodeWithMin[stack_capacity];
		topIndex = 0;
	};

	~MyStack()
	{
		delete[] values;
	};

	bool isFull()
	{
		return topIndex == stack_capacity;
	};

	bool isEmpty()
	{
		return topIndex == 0;
	};

	NodeWithMin peek()
	{
		assert(!isEmpty());
		return values[topIndex-1];
	};

	void push(NodeWithMin value)
	{
		assert(!isFull());
		values[topIndex]=value;
		if (topIndex == 0)
		{
			values[topIndex].setMinimum(value.getValue());
		}
		else
		{
			if (value.getValue() < values[topIndex - 1].getValue())
			{
				values[topIndex].setMinimum(value.getValue());
			}
			else
			{
				values[topIndex].setMinimum(values[topIndex - 1].getMinimum());
			}
		}

		topIndex++;
	};

	NodeWithMin pop()
	{
		assert(!isEmpty());
		NodeWithMin value = values[topIndex-1];
		values[topIndex-1].setValue(0) ;
		values[topIndex - 1].setMinimum(0);
		topIndex--;
		return value;
	};
	int minimum()
	{
		assert(!isEmpty());
		return values[topIndex - 1].getMinimum();
	}
	void printMyStack()
	{
		    assert(!isEmpty());
			cout << "MyStack " <<"is:" << endl;
			for (int index = 0; index < topIndex; index++)
			{
				cout << values[index].getValue() <<" "<< values[index].getMinimum() << endl;
			}
			cout << "MyStack's minimum value " <<"is " << minimum() <<endl;
			cout << "MyStack's topIndex " << "is " << topIndex << endl;
	}
private:
	int stack_capacity;
	NodeWithMin* values;
	int topIndex;
};
//测试代码
int main()
{
	MyStack testStack(4);
	NodeWithMin one(7);
	NodeWithMin two(19);
	NodeWithMin three(99);
	NodeWithMin four(4);
	testStack.push(one);
	testStack.push(two);
	testStack.push(three);
	testStack.push(four);
	testStack.printMyStack();
	testStack.pop();
	testStack.printMyStack();
	return 0;
}
 
图1.

     以下算法是对以上算法的一种改进,可以减少用来存储当前栈的最小值的额外的空间,特别是当前面进栈的数据值较小时,效果更好。该算法用另外一个栈来存储数据栈的当前最小值。当第一个值入数据栈时,存储最小值的栈之后只会存储第一个数据栈的值以及之后比该值小的数据栈的值,因此节省了空间。求栈中最小值的函数为 i n t    m i n i m u m ( ) int \;minimum() intminimum(),其时间复杂度为 O ( 1 ) O(1) O(1)
     以下是实现代码和测试代码。测试结果如图2所示。

// 实现代码
class MyStack
{
public:
	MyStack(int capacity=0)
	{
		stack_capacity = capacity;	
		values = new int[stack_capacity];
		topIndex = 0;
	};

	~MyStack()
	{
		delete[] values;
	};

	bool isFull()
	{
		return topIndex == stack_capacity;
	};

	bool isEmpty()
	{
		return topIndex == 0;
	};

	int peek()
	{
		assert(!isEmpty());
		return values[topIndex-1];
	};

	void push(int value)
	{
		assert(!isFull());
		values[topIndex]=value;
		topIndex++;
	};

	int pop()
	{
		assert(!isEmpty());
		int value = values[topIndex-1];
		topIndex--;
		return value;
	};
	void printMyStack()
	{
		assert(!isEmpty());
		cout << "MyStack " <<"is:" << endl;
		for (int index = 0; index < topIndex; index++)
		{
			cout << values[index] <<" "<< endl;
		}
		cout << "MyStack's topIndex " << "is " << topIndex << endl;
	}
	int getCapacity()
	{
		return stack_capacity;
	}
	void setCapacity(int value)
	{
		stack_capacity = value;
	}
	void setValues(int *value)
	{
		values = value;
	}
	int* getValues()
	{
		return values;
	}
	void setTopindex(int top=0)
	{
		topIndex=top;
	}
	int getTopindex()
	{
		return topIndex;
	}
private:
	int stack_capacity;
	int* values;
	int topIndex;
};

class MyStackWithMIn :public MyStack
{
    public:
		MyStackWithMIn(int capacity)
		{
			s = new MyStack(capacity);
			setCapacity(capacity);
			setValues(new int[capacity]);
			setTopindex();
		}
		~MyStackWithMIn()
		{
		    delete s;
		}
		void push(int value)
		{
			assert(!isFull());
			MyStack::push(value);
			if ((value <= minimum()))
			{
				s->push(value);
			}
		};
		int pop()
		{
			assert(!isEmpty());
			int popValue=MyStack::pop();
			if (popValue == minimum())
			{
				s->pop();
			}
			return popValue;
		};
		int minimum()
		{
			if((*s).isEmpty())
			{
				return INT32_MAX;
			}
			return (*s).peek();
		}
    private:
		MyStack *s;

};
//测试代码
int main()
{
	MyStackWithMIn testStack(4);
	testStack.push(7);
	testStack.printMyStack();
	cout << "MyStack's minimum value " << "is " << testStack.minimum() << endl;
	testStack.push(5);
	testStack.printMyStack();
	cout << "MyStack's minimum value " << "is " << testStack.minimum() << endl;
	testStack.push(6);
	testStack.printMyStack();
	cout << "MyStack's minimum value " << "is " << testStack.minimum() << endl;
	testStack.push(3);
	testStack.printMyStack();
	cout << "MyStack's minimum value " << "is " << testStack.minimum() << endl;
	return 0;
}
 
图2.
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

qqssss121dfd

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值