堆栈

目录:

9、【剑指Offer学习】【面试题09:用两个栈实现队列】

30、【剑指Offer学习】【面试题30:包含min函数的栈】

31、【剑指Offer学习】【面试题31:栈的压入、弹出序列】

9. 【剑指Offer学习】【面试题09:用两个栈实现队列】

/*******************************************************************
Copyright(c) 2016, Harry He
All rights reserved.

Distributed under the BSD license.
(See accompanying file LICENSE.txt at
https://github.com/zhedahht/CodingInterviewChinese2/blob/master/LICENSE.txt)
*******************************************************************/

//==================================================================
// 《剑指Offer——名企面试官精讲典型编程题》代码
// 作者:何海涛
//==================================================================

// 面试题9:用两个栈实现队列
// 题目:用两个栈实现一个队列。队列的声明如下,请实现它的两个函数appendTail
// 和deleteHead,分别完成在队列尾部插入结点和在队列头部删除结点的功能。

include "Queue.h"

// 测试代码
void Test(char actual, char expected)
{
if(actual == expected)
printf("Test passed.\n");
else
printf("Test failed.\n");
}

int main(int argc, char* argv[])
{
CQueue queue;

queue.appendTail('a');
queue.appendTail('b');
queue.appendTail('c');

char head = queue.deleteHead();
Test(head, 'a');

head = queue.deleteHead();
Test(head, 'b');

queue.appendTail('d');
head = queue.deleteHead();
Test(head, 'c');

queue.appendTail('e');
head = queue.deleteHead();
Test(head, 'd');

head = queue.deleteHead();
Test(head, 'e');

return 0;
}


/*******************************************************************
Copyright(c) 2016, Harry He
All rights reserved.

Distributed under the BSD license.
(See accompanying file LICENSE.txt at
https://github.com/zhedahht/CodingInterviewChinese2/blob/master/LICENSE.txt)
*******************************************************************/

//==================================================================
// 《剑指Offer——名企面试官精讲典型编程题》代码
// 作者:何海涛
//==================================================================

// 面试题9:用两个栈实现队列
// 题目:用两个栈实现一个队列。队列的声明如下,请实现它的两个函数appendTail
// 和deleteHead,分别完成在队列尾部插入结点和在队列头部删除结点的功能。

pragma once

include

include

using namespace std;

template class CQueue
{
public:
CQueue(void);
~CQueue(void);

// 在队列末尾添加一个结点
void appendTail(const T& node);

// 删除队列的头结点
T deleteHead();

private:
stack stack1;
stack stack2;
};

template CQueue::CQueue(void)
{
}

template CQueue::~CQueue(void)
{
}

template void CQueue::appendTail(const T& element)
{
stack1.push(element);
}

template T CQueue::deleteHead()
{
if(stack2.size()<= 0)
{
while(stack1.size()>0)
{
T& data = stack1.top();
stack1.pop();
stack2.push(data);
}
}

if(stack2.size() == 0)
throw new exception("queue is empty");

T head = stack2.top();
stack2.pop();

return head;
}

30. 面试题30:包含min函数的栈

//==================================================================
// 《剑指Offer——名企面试官精讲典型编程题》代码
// 作者:何海涛
//==================================================================

// 面试题30:包含min函数的栈
// 题目:定义栈的数据结构,请在该类型中实现一个能够得到栈的最小元素的min
// 函数。在该栈中,调用min、push及pop的时间复杂度都是O(1)。

pragma once

include

include <assert.h>

template class StackWithMin
{
public:
StackWithMin() {}
virtual ~StackWithMin() {}

T& top();
const T& top() const;

void push(const T& value);
void pop();

const T& min() const;

bool empty() const;
size_t size() const;

private:
std::stack m_data; // 数据栈,存放栈的所有元素
std::stack m_min; // 辅助栈,存放栈的最小元素
};

template void StackWithMin::push(const T& value)
{
// 把新元素添加到辅助栈
m_data.push(value);

// 当新元素比之前的最小元素小时,把新元素插入辅助栈里;
// 否则把之前的最小元素重复插入辅助栈里
if(m_min.size() == 0 || value < m_min.top())
m_min.push(value);
else
m_min.push(m_min.top());
}

template void StackWithMin::pop()
{
assert(m_data.size() > 0 && m_min.size() > 0);

m_data.pop();
m_min.pop();
}

template const T& StackWithMin::min() const
{
assert(m_data.size() > 0 && m_min.size() > 0);

return m_min.top();
}

template T& StackWithMin::top()
{
return m_data.top();
}

template const T& StackWithMin::top() const
{
return m_data.top();
}

template bool StackWithMin::empty() const
{
return m_data.empty();
}

template size_t StackWithMin::size() const
{
return m_data.size();
}

31. 面试题31:栈的压入、弹出序列

/*******************************************************************
Copyright(c) 2016, Harry He
All rights reserved.

Distributed under the BSD license.
(See accompanying file LICENSE.txt at
https://github.com/zhedahht/CodingInterviewChinese2/blob/master/LICENSE.txt)
*******************************************************************/

//==================================================================
// 《剑指Offer——名企面试官精讲典型编程题》代码
// 作者:何海涛
//==================================================================

// 面试题31:栈的压入、弹出序列
// 题目:输入两个整数序列,第一个序列表示栈的压入顺序,请判断第二个序列是
// 否为该栈的弹出顺序。假设压入栈的所有数字均不相等。例如序列1、2、3、4、
// 5是某栈的压栈序列,序列4、5、3、2、1是该压栈序列对应的一个弹出序列,但
// 4、3、5、1、2就不可能是该压栈序列的弹出序列。

include

include

bool IsPopOrder(const int* pPush, const int* pPop, int nLength)
{
bool bPossible = false;

if(pPush != nullptr && pPop != nullptr && nLength > 0)
{
const int* pNextPush = pPush;
const int* pNextPop = pPop;

std::stack stackData;

while(pNextPop - pPop < nLength)
{
// 当辅助栈的栈顶元素不是要弹出的元素
// 先压入一些数字入栈
while(stackData.empty() || stackData.top() != *pNextPop)
{
// 如果所有数字都压入辅助栈了,退出循环
if(pNextPush - pPush == nLength)
break;

stackData.push(*pNextPush);

pNextPush ++;
}

if(stackData.top() != *pNextPop)
break;

stackData.pop();
pNextPop ++;
}

if(stackData.empty() && pNextPop - pPop == nLength)
bPossible = true;
}

return bPossible;
}

// 测试代码
void Test(const char* testName, const int* pPush, const int* pPop, int nLength, bool expected)
{
if(testName != nullptr)
printf("%s begins: ", testName);

if(IsPopOrder(pPush, pPop, nLength) == expected)
printf("Passed.\n");
else
printf("failed.\n");
}

void Test1()
{
const int nLength = 5;
int push[nLength] = {1, 2, 3, 4, 5};
int pop[nLength] = {4, 5, 3, 2, 1};

Test("Test1", push, pop, nLength, true);
}

void Test2()
{
const int nLength = 5;
int push[nLength] = {1, 2, 3, 4, 5};
int pop[nLength] = {3, 5, 4, 2, 1};

Test("Test2", push, pop, nLength, true);
}

void Test3()
{
const int nLength = 5;
int push[nLength] = {1, 2, 3, 4, 5};
int pop[nLength] = {4, 3, 5, 1, 2};

Test("Test3", push, pop, nLength, false);
}

void Test4()
{
const int nLength = 5;
int push[nLength] = {1, 2, 3, 4, 5};
int pop[nLength] = {3, 5, 4, 1, 2};

Test("Test4", push, pop, nLength, false);
}

// push和pop序列只有一个数字
void Test5()
{
const int nLength = 1;
int push[nLength] = {1};
int pop[nLength] = {2};

Test("Test5", push, pop, nLength, false);
}

void Test6()
{
const int nLength = 1;
int push[nLength] = {1};
int pop[nLength] = {1};

Test("Test6", push, pop, nLength, true);
}

void Test7()
{
Test("Test7", nullptr, nullptr, 0, false);
}

int main(int argc, char* argv[])
{
Test1();
Test2();
Test3();
Test4();
Test5();
Test6();
Test7();

return 0;
}

posted @ 2019-12-11 20:29  风御之举  阅读(73)  评论(0)    收藏  举报