您的位置:首页 > 职场人生

栈和队列的相关面试题

2017-07-20 18:08 429 查看
栈和队列相关面试题
    栈的特性是先入后出,而队列的特性则是先入先出
    1.使用数组建立一个动态栈
    这个题目其实就是最基础的实现方法,所以就不多介绍,直接贴代码了。
    
   
//1.借助数组实现栈
template
class StackArr
{
public:
StackArr()
:_a(NULL)
, _size(0)
, _capacity(0)
{}
void Push(T data)
{
checkcapacity();
_a[_size] = data;
_size++;
}
void Pop()
{
if (_size)
{
_size--;
return;
}
cout << "栈为空" << endl;
}

void checkcapacity()
{
_capacity = _capacity * 2 + 3;
T* tmp = new T[_capacity];
if (_a)
{

for (int i = 0; i < _size; i++)
{
tmp[i] = _a[i];
}
delete[] _a;
}
_a = tmp;
}
int Size()
{
return _size ;
}
bool Empty()
{
return _size > 0 ? true : false;
}
T Top()
{
return _a[--_size];
}
protected:
T* _a;
int _size;
int _capacity;
};
void testStackArr()
{
StackArr s;
s.Push(1);
s.Push(2);
s.Push(3);
s.Push(4);
cout << s.Size() << endl;
cout << s.Empty() << endl;
cout << s.Top() << endl;
s.Pop();
s.Pop();
s.Pop();
s.Pop();
s.Pop();
s.Pop();
s.Pop();
cout << s.Empty() << endl;

}


    2.包含min函数的栈
    题目:定义栈的数据结构,请在该类型中实现一个能够得到栈的最小元素的min函数。在该栈中,调用min、push、pop的时间复杂度都是O(1)
    这个题目相对简单的做法就是借助辅助栈,每次都把最小的元素(之前最小的元素和新插入的元素间的较小者)存放进另一个辅助栈。每次都将当前的最小值元素存放进辅助栈,不会影响数据栈中的压入、弹出顺序,也能保证辅助栈的栈顶元素始终是当前插入的所有元素中的最小值。
    在这里我借助图来讲解这个过程
    


    由这个图就可以很清晰的看出来这种方法是可行的。实现方法也比较简单,借助STL里的栈可以很容易的实现这个功能。
   
   
//2.包含min函数的栈
class StackMin
{
public:
void Push(int data)
{
data_stack.push(data);
if (min_stack.empty() == true)
{
min_stack.push(data);
}
else if (min_stack.empty() == false && min_stack.top()>=data)
{
min_stack.push(data);
}
}
void Pop()
{
if (data_stack.empty() == true)
{
cout << "栈为空" << endl;
return;
}
if (min_stack.empty() == false && min_stack.top() == data_stack.top())
{
data_stack.pop();
min_stack.pop();
}
else
{
data_stack.pop();
}
}
int Min()
{
return min_stack.top();
}
protected:
stack data_stack;
stack min_stack;
};


    3.栈的压入、弹出序列
    题目:输入两个整数序列,第一个序列表示栈的压入序列,请判断第二个序列是否为该栈的弹出序列。假设压入栈的所有数字均不相等。
    例如序列1、2、3、4、5是某栈的压栈序列,序列4、5、3、2、1是该压栈序列对应的一个弹出序列。但4、3、5、1、2就不可能是该压栈序列的弹出序列
    借助图应该会更容易理解这个过程
    


   
//3.栈的压入和弹出序列
bool IsPoporder(const int* pushorder, const int* poporder, int length)
{
bool possible = false;
if (pushorder != NULL&&poporder != NULL&&length > 0)
{

c47f
const int* pushnext = pushorder;
const int* popnext = poporder;
stack data_stack;
while (popnext - poporder < length)
{
while (data_stack.empty() || data_stack.top() != *popnext)
{
if (pushnext - pushorder == length)
break;
data_stack.push(*pushnext);
pushnext++;
}
if (data_stack.top() != *popnext)
break;
data_stack.pop();
popnext++;
}
if (data_stack.empty() && popnext - poporder == length)
{
possible = true;
}
}
return possible;
}


    4.用两个栈实现队列
    题目:用两个栈实现一个队列。队列的声明如下,请实现它的两个函数appendTail和deleteHead,分别完成在队列尾部插入节点和在队列头部删除节点的功能
    template<typename T>
    class CQueue
    {
      public:
           CQueue(void);
           ~Queue(void);
                      void appendTail(const T& node);
           T deleteHead();
     private:
            stack<T> stack1;
            stack<T> stack2;
     }
    根据栈和队列的特性来实现,一个栈负责删除,一个栈负责插入
               


              
             
/4.用两个栈模拟实现一个队列
class SQueue
{
public:
void Push(int data)
{
pushstack.push(data);
}
void Pop()  //为检测删除是否正确
{
if (pushstack.empty() == true && popstack.empty() == true)
{
cout << "当前队列为空" << " ";
return ;
}
if (popstack.empty() == true)
{
while (pushstack.empty() == false)
{
popstack.push(pushstack.top());
pushstack.pop();
}
}
cout << "删除" << popstack.top() << endl;
popstack.pop();
}
private:
stack pushstack;
stack popstack;
};


    5.用两个队列实现栈
    题目:用两个队列实现一个栈,能够完成在栈顶插入节点,在栈顶删除节点的功能
    将一个队列作为辅助中转站,队列的插入、删除都在另一个栈中实现
              


               
   
#include
//5.两个队列实现一个栈
class QStack
{
public:
void Push(int data)
{
q1.push(data);
}
void Pop()
{
if (q1.empty() == true && q2.empty() == true)
{
cout << "当前栈为空" << endl;
return;
}
if (!q1.empty())
{
while (q1.size() > 1)
{
q2.push(q1.front());
q1.pop();
}
cout << "删除" << q1.front() << endl;
q1.pop();
while (q2.empty() == false)
{
q1.push(q2.front());
q2.pop();
}
}
}
private :
queue  q1;
queue q2;
};


     6.使用数组实现队列
    实现尾插和头删功能即可
    
   
/6.用数组实现队列(实现尾插头删)
template
class QueueArr
{
public:
QueueArr()
:_a(NULL)
, _size(0)
, _capacity(0)
{}
void Push(T data)
{
checkcapacity();
_a[_size] = data;
++_size;
}
void Pop()
{
if (_size==0)
{
cout << "当前队列为空" << endl;
return;
}
if (_size>0)
{
int i = 0;
for (int i = 0; i < _size; ++i)
{
_a[i] = _a[i - 1];
}
--_size;
}

}
void checkcapacity()
{
_capacity = _capacity * 2 + 3;
T* tmp = new T[_capacity];
if (_size>0)
{
for (int i = 0; i < _size; i++)
{
tmp[i] = _a[i];
}
delete[] _a;
}
_a = tmp;
}
private:
T* _a;
int _size;
int _capacity;
};


    7.一个数组实现两个栈
    把握栈的特性,即对于数组来说就是尾插功能和尾删功能,满足这两个功能主要即可
    对于这个题有三种组织形式,主要在扩容时有差别
   (1)第一种:从中间向两边压栈
    采用两个栈底分别放在数组中间,栈顶向两边移动,当两个栈顶任意一个到达数组的两边时,数组进行扩容
   (2)第二种:两边向中间压栈
    两个栈的栈底分别在数组的两边,压栈时栈顶向中间靠拢,当两个栈顶相遇时扩容
   (3)第三种:分奇偶方式压栈
    采用交叉索引的方式,两个栈分别拥有下标奇偶的空间,假设数组原本容量是偶数,当偶数栈的栈顶达到容量-1时或奇数栈的栈顶达到容量-2时扩容
    第一种和第三种在扩容时考虑的情况比较复杂,并且在一个栈数据多,一个栈数据少时,空间浪费比较大,我在这里只实现第二种方法
    


   
//7.一个数组实现两个栈

template
class ArrayStack
{
public:
ArrayStack()
:_arr1(new T[1])
, _size1(0)
, _size2(0)
, _capacity(1)
, _sz(_capacity-1)

{
assert(_arr1);
_arr2 = &_arr1[_capacity - 1];
}
~ArrayStack()
{
if (!_arr1)
{
delete[] _arr1;
_size1 = 0;
_capacity = 0;
_size2 = 0;
_sz = 0;
}
}
void arr1_Push(T data)
{
checkcapacity();
_arr1[_size1] = data;
_size1++;
}
void arr2_Push(T data)
{
checkcapacity();
_arr1[_capacity-_size2-1] = data;
_size2++;
}
void arr1_Pop()
{
if (_size1 > 0)
{
_size1--;
}
else
{
cout << "栈1为空" << endl;
}
}
void arr2_Pop()
{
if (_size2)
{
_size2--;
}
else
{
cout << "栈2为空" << endl;
}
}
void arr1_Display()
{
for (int i = 0; i < _size1; i++)
{
cout << _arr1[i] << " ";
}
cout << "NULL"<_capacity-_size2-1; i--)
{
cout << _arr1[i] << " ";
}
cout <<"NULL"<< endl;
}
void Display()
{
for (int i = 0; i < _capacity; i++)
{
cout << _arr1[i] << " ";
}
cout << "NULL" << endl;
}
void checkcapacity()
{
if (&_arr1[_size1]==&_arr1[_capacity-_size2-1])
{
int s = _size2;
int t_capacity = _capacity * 2 + 3;
int t =t_capacity;
T* tmp = new T[t_capacity];
for (int i = 0; i < _size1; i++)
{
tmp[i] = _arr1[i];
}
while (s--)
{
tmp[t - 1] = _arr1[_capacity - 1];
t--;
_capacity--;
}
delete[] _arr1;
_arr1 = tmp;
_capacity = t_capacity;
_arr2 = &_arr1[_capacity - 1];
_sz = _capacity - 1;
}
}
private:
T* _arr1;
T* _arr2;
int _size1;
int _size2;
int _capacity;   //两个栈共用的容量
int _sz;
};


  
    所以代码的地址:  
 https://github.com/zknn/VS2013Copy/blob/%E6%A0%88%E5%92%8C%E9%98%9F%E5%88%97%E7%9A%84%E9%9D%A2%E8%AF%95%E9%A2%98/StackQueue/%E6%BA%90.cpp
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: