自定义栈-pop-push-min-时间复杂度都为O(1)
2011-08-12 14:52
375 查看
1. 简述
首先要决定使用链表结构实现还是顺序结构实现,对于顺序结构实现,当数据满的情况下进行Push时,需要开辟新的数组,进行复制,因此不能保证Push的时间复杂度为O(1);链表结构能够保证Push和Pop的时间复杂度为O(1)。Min的时间复杂度也要求O(1),通过空间换时间,分别记录链表,当包含一个节点时,最小值所在的节点,当包含两个节点时,最小值所在的节点,等等,直到所有节点时,最小值所在的节点。这样相当于两个链表,一个链表保存数值,另一个链表保存第一个链表中,对应节点范围内的最小值所在节点。
2. 实现
#include <iostream>
using namespace std;
// 友元,链接结构
template<class T>
class Stack;
template<class T>
class Node {
friend class Stack<T>;
private:
T data;
Node<T>* link;
};
template<class T>
class MinNode {
friend class Stack<T>;
private:
Node<T>* min_node;
MinNode<T>* link;
};
template<class T>
class Stack {
private:
Node<T>* head;
MinNode<T>* min_head;
public:
Stack(): head(0),min_head(0) { }
~Stack() {
Node<T>* tmp;
while(head) {
tmp = head->link;
delete head;
head = tmp;
}
tmp = 0;
MinNode<T>* min_tmp;
while(min_head) {
min_tmp = min_head->link;
delete min_head;
min_head = min_tmp;
}
min_tmp = 0;
}
Stack<T>& Push(const T& data) {
Node<T>* tmp = new Node<T>;
tmp->data = data;
tmp->link = head;
head = tmp;
MinNode<T>* min_tmp = new MinNode<T>;
if(min_head > 0 && min_head->min_node->data < head->data)
min_tmp->min_node = min_head->min_node;
else
min_tmp->min_node = head;
min_tmp->link = min_head;
min_head = min_tmp;
return *this;
}
Stack<T>& Pop() {
assert(head > 0);
Node<T> *tmp = head->link;
delete head;
head = tmp;
tmp = 0;
MinNode<T> *min_tmp = min_head->link;
delete min_head;
min_head = min_tmp;
min_tmp = 0;
return *this;
}
void Min(T& data) {
assert(head > 0);
data = min_head->min_node->data;
}
};
int main() {
Stack<int> stack;
int min;
int array[10] = {3,4,5,6,7,2,1,0,9,8};
for(int i=0; i<10; i++) {
stack.Push(array[i]);
stack.Min(min);
cout << min << endl;
}
system("PAUSE");
return 0;
}
3. 说明
· 对于Node, MinNode这样的节点类,把Stack声明为其友元,方便直接使用节点类的私有成员。
· Push和Pop返回值类型为Stack<int>&,这样做是为了实现stack.push(1).push(2).push(3);这样调用方式。
· 在参考资料中,有一份使用deque来实现内部结构的实现方式。
4. 参考
程序员面试题精选100题(02)-设计包含min函数的栈
http://zhedahht.blog.163.com/blog/static/25411174200712895228171/
首先要决定使用链表结构实现还是顺序结构实现,对于顺序结构实现,当数据满的情况下进行Push时,需要开辟新的数组,进行复制,因此不能保证Push的时间复杂度为O(1);链表结构能够保证Push和Pop的时间复杂度为O(1)。Min的时间复杂度也要求O(1),通过空间换时间,分别记录链表,当包含一个节点时,最小值所在的节点,当包含两个节点时,最小值所在的节点,等等,直到所有节点时,最小值所在的节点。这样相当于两个链表,一个链表保存数值,另一个链表保存第一个链表中,对应节点范围内的最小值所在节点。
2. 实现
#include <iostream>
using namespace std;
// 友元,链接结构
template<class T>
class Stack;
template<class T>
class Node {
friend class Stack<T>;
private:
T data;
Node<T>* link;
};
template<class T>
class MinNode {
friend class Stack<T>;
private:
Node<T>* min_node;
MinNode<T>* link;
};
template<class T>
class Stack {
private:
Node<T>* head;
MinNode<T>* min_head;
public:
Stack(): head(0),min_head(0) { }
~Stack() {
Node<T>* tmp;
while(head) {
tmp = head->link;
delete head;
head = tmp;
}
tmp = 0;
MinNode<T>* min_tmp;
while(min_head) {
min_tmp = min_head->link;
delete min_head;
min_head = min_tmp;
}
min_tmp = 0;
}
Stack<T>& Push(const T& data) {
Node<T>* tmp = new Node<T>;
tmp->data = data;
tmp->link = head;
head = tmp;
MinNode<T>* min_tmp = new MinNode<T>;
if(min_head > 0 && min_head->min_node->data < head->data)
min_tmp->min_node = min_head->min_node;
else
min_tmp->min_node = head;
min_tmp->link = min_head;
min_head = min_tmp;
return *this;
}
Stack<T>& Pop() {
assert(head > 0);
Node<T> *tmp = head->link;
delete head;
head = tmp;
tmp = 0;
MinNode<T> *min_tmp = min_head->link;
delete min_head;
min_head = min_tmp;
min_tmp = 0;
return *this;
}
void Min(T& data) {
assert(head > 0);
data = min_head->min_node->data;
}
};
int main() {
Stack<int> stack;
int min;
int array[10] = {3,4,5,6,7,2,1,0,9,8};
for(int i=0; i<10; i++) {
stack.Push(array[i]);
stack.Min(min);
cout << min << endl;
}
system("PAUSE");
return 0;
}
3. 说明
· 对于Node, MinNode这样的节点类,把Stack声明为其友元,方便直接使用节点类的私有成员。
· Push和Pop返回值类型为Stack<int>&,这样做是为了实现stack.push(1).push(2).push(3);这样调用方式。
· 在参考资料中,有一份使用deque来实现内部结构的实现方式。
4. 参考
程序员面试题精选100题(02)-设计包含min函数的栈
http://zhedahht.blog.163.com/blog/static/25411174200712895228171/
相关文章推荐
- 数据结构---设计一个栈,push, pop, min 时间复杂度都是 O(1)
- 数据结构---设计一个栈,push, pop, min 时间复杂度都是 O(1)
- 定义栈的数据结构在Theta(1)时间复杂度内实现min,pop,push操作
- 定义一个栈的数据结构,实现min函数,要求push,pop,min时间复杂度是0(1);找出字符串中的最长子串,要求子串不含重复字符,时间复杂度是O(n);
- 实现时间复杂度为O(1)的Push,Pop,Min
- 设计栈,在O(1)的时间复杂内实现push,pop,min
- 实现一个栈,要求push,pop,Min的操作时间复杂度为O(1)
- 实现一个栈,要求pop,push,Min,时间复杂度为O(1)
- 设计一个栈,除了pop push 还支持Min,时间复杂度都为o(1);
- 实现一个栈的pop,push,Min(最小值),时间复杂度为O(1)
- 定义一个栈的数据结构,实现min函数,要求push,pop,min时间复杂度是0(1);找出字符串中的最长子串,要求子串不含重复字符,时间复杂度是O(n);
- 满足min.push.pop操作时间复杂度为o(1)的栈
- 【面试题】实现一个栈,要求Push(入栈),Pop(出栈),Min(返回最小值的操作)的时间复杂度为O(1)
- 【每日一题】实现一个栈Stack,要求实现Push(出栈)、Pop(入栈)、Min(返回最小值的操作)的时间复杂度为O(1)
- 实现一个栈Stack,要求实现Push、Pop、Min(返回最小值的操作)的时间复杂度为O(1)
- 自定义栈类型,具有找到站内最小元素的min函数 ,且min(),pop(),push()函数的时间复杂度为O(1)
- 剑指offer 21---实现一个栈, 要求实现Push( 出栈) 、 Pop( 入栈) 、 Min( 返回最小值的操作) 的时间复杂度为O(1)
- 实现一个栈,要求Push/Pop/Min(返回最小值)的时间复杂度为O(1)
- 实现一个栈,要求实现Push(入栈)、Pop(出栈)、Min(返回最小值的操作)的时间复杂度为O(1)
- 设计一个堆栈,函数min、push 以及pop 的时间复杂度都是O(1)