集合栈-程序员面试金典

数据结构由多个栈组成,用链表连接,并且在前一个栈填满之时,新建一个栈,且push()方法和pop()方法和top()方法与普通栈的方法一样。且实现了一个popAt(int index)方法,指定子栈,并执行pop()操作,当一个非最后的栈pop时,用后续栈将其填满。为实现popAt()需要访问后一个栈的底部,所以不能使用Stack模板,而是使用deque。pop(),push(),top()都是通过back而访问底部(bottom)则是通过front。链表结点的创建用CreateListNode(deque<int> value)删除用RemoveNode(ListNode** pHead, deque<int> value)。

代码如下:

#include<iostream>
#include<deque>
using namespace std;

struct ListNode{
	deque<int> m_nValue;
	ListNode* m_pNext;
};

ListNode* CreateListNode(deque<int> value)
{
	ListNode* pNode = new ListNode();
	pNode->m_nValue = value;
	pNode->m_pNext = NULL;

	return pNode;
}

void ConnectListNodes(ListNode* pCurrent, ListNode* pNext)
{
	if (pCurrent == NULL)
	{
		printf("Error to connect two nodes.\n");
		exit(1);
	}

	pCurrent->m_pNext = pNext;
}

void PrintListNode(ListNode* pNode)
{
	if (pNode == NULL)
	{
		printf("The node is NULL\n");
	}
	else
	{
		printf("The key in node is %d.\n", pNode->m_nValue);
	}
}

void PrintList(ListNode* pHead)
{
	printf("PrintList starts.\n");

	ListNode* pNode = pHead;
	while (pNode != NULL)
	{
		printf("%d\t", pNode->m_nValue);
		pNode = pNode->m_pNext;
	}

	printf("\nPrintList ends.\n");
}

void DestroyList(ListNode* pHead)
{
	ListNode* pNode = pHead;
	while (pNode != NULL)
	{
		pHead = pHead->m_pNext;
		delete pNode;
		pNode = pHead;
	}
}

void AddToTail(ListNode** pHead, deque<int> value)
{
	ListNode* pNew = new ListNode();
	pNew->m_nValue = value;
	pNew->m_pNext = NULL;

	if (*pHead == NULL)
	{
		*pHead = pNew;
	}
	else
	{
		ListNode* pNode = *pHead;
		while (pNode->m_pNext != NULL)
			pNode = pNode->m_pNext;

		pNode->m_pNext = pNew;
	}
}

void RemoveNode(ListNode** pHead, deque<int> value)
{
	if (pHead == NULL || *pHead == NULL)
		return;

	ListNode* pToBeDeleted = NULL;
	if ((*pHead)->m_nValue == value)
	{
		pToBeDeleted = *pHead;
		*pHead = (*pHead)->m_pNext;
	}
	else
	{
		ListNode* pNode = *pHead;
		while (pNode->m_pNext != NULL && pNode->m_pNext->m_nValue != value)
			pNode = pNode->m_pNext;

		if (pNode->m_pNext != NULL && pNode->m_pNext->m_nValue == value)
		{
			pToBeDeleted = pNode->m_pNext;
			pNode->m_pNext = pNode->m_pNext->m_pNext;
		}
	}

	if (pToBeDeleted != NULL)
	{
		delete pToBeDeleted;
		pToBeDeleted = NULL;
	}
}

int length(ListNode* head){
	if (head == NULL)
		return 0;
	ListNode* n = head;
	int count = 1;
	while (n->m_pNext != NULL){
		n = n->m_pNext;
		++count;
	}
	return count;
}

ListNode* get(ListNode* head,int n){
	if (n < 0||head==NULL)
		return NULL;
	int count = 0;
	ListNode* node = head;
	while (node->m_pNext != NULL&&n!=count){
		node = node->m_pNext;
		++count;
	}
	if (node->m_pNext == NULL&&n!= count){
		cout << "n>length error" << endl;
		return NULL;
	}

	return node;
}

class SetOfStacks{
public:
	ListNode* stacks;
	int capacity;
	SetOfStacks(int c) :capacity(c){ stacks = NULL; }
	~SetOfStacks(){};



	ListNode* getLastStack(){
		if (stacks == NULL)
			return NULL;
		return get(stacks, length(stacks)-1);
	}

	void push(int v){
		if (getLastStack() == NULL){
			deque<int> stack;
			stack.push_back(v);
			ListNode* outset = CreateListNode(stack);
			stacks = outset;
			return;
		}

		deque<int>& last = getLastStack()->m_nValue;
		if (getLastStack() != NULL&&!(last.size() == capacity)){
			last.push_back(v);
		}
		else{
			deque<int> stack;
			stack.push_back(v);
			ListNode* another= CreateListNode(stack);
			ConnectListNodes(getLastStack(), another);
		}
	}

	void pop(){
		deque<int>& last = getLastStack()->m_nValue;
		last.pop_back();
		if (last.size() == 0)
			RemoveNode(&stacks, last);
	}

	int top(){
		return getLastStack()->m_nValue.back();
	}

	bool Empty(){
		deque<int> last = getLastStack()->m_nValue;
		return (getLastStack() == NULL) || last.empty();
	}

	int leftShift(int index,bool removeTop){
		deque<int>& stack = get(stacks, index)->m_nValue;
		int removed_item;
		if (removeTop){
			removed_item = stack.back();
			stack.pop_back();
		}
		else{
			removed_item = stack.front();
			stack.pop_front();
		}
		if (stack.empty())
			RemoveNode(&stacks, stack);
		else if (length(stacks) > index + 1){
			int v = leftShift(index + 1, false);
			stack.push_back(v);
		}
		return removed_item;
	}

	int popAt(int index){
		return leftShift(index, true);
	}

};

int main(){
	SetOfStacks s(3);
	s.push(1); s.push(2); s.push(3); s.push(4); s.push(5); s.push(6);
	cout << s.popAt(0) << endl;
	cout << s.popAt(0) << endl;
	cout << s.top() << endl;
	s.pop();
	cout << s.top() << endl;
	s.pop();
	cout << s.top() << endl;
	s.pop();
	cout << s.top() << endl;
	s.pop();


	cin.get();
	return 0;
}

最后,心得:一定要记得引用啊!一定要记得引用啊!一定要记得引用啊!重要的话说三遍,它不是Java,没有引用就是传递临时对象了。

最近频频转换java和C++,头都乱了。。。


这是结果,嗯嗯。

吃饭去了。



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值