欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

3.2 栈的最小值

程序员文章站 2022-06-03 14:06:45
...

     《程序员面试金典》(第六版)习题:仅为记录一下以加强印象,不为商业用途,如有侵权请联系删除。以下源码和解释参考了书中源码以及解释。
     以下算法通过在栈中的每一个节点存储节点值以及当该节点为栈顶时整个栈的最小值,实现了求栈中最小值的函数int  minimum()int \;minimum(),其时间复杂度为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;
}
  3.2 栈的最小值
图1.
     以下算法是对以上算法的一种改进,可以减少用来存储当前栈的最小值的额外的空间,特别是当前面进栈的数据值较小时,效果更好。该算法用另外一个栈来存储数据栈的当前最小值。当第一个值入数据栈时,存储最小值的栈之后只会存储第一个数据栈的值以及之后比该值小的数据栈的值,因此节省了空间。求栈中最小值的函数为$int \;minimum()$,其时间复杂度为$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;
}
  3.2 栈的最小值
图1.