码迷,mamicode.com
首页 > 编程语言 > 详细

用两个栈实现一个队列,并实现在多线程环境下

时间:2015-08-21 13:09:55      阅读:250      评论:0      收藏:0      [点我收藏+]

标签:

在知乎上看到这道题目,就实现了下看看。如有错误,麻烦各位看官留言指导下。

首先两个栈实现一个队列的思路是这样的:

      (1)用栈A作为队列的入口,只提供入队操作, 用栈B作为队列的出口,只提供出口。

      (2)由于栈的特性是后进先出, 队列是先进先出, 若要出队(即把栈A最底层的元素pop出来), 需要把栈A整个转移到栈B(转移后就变为了倒序),此时只要pop栈B就能成功出队一个元素

      (3)同理若要入队, 则要先把栈B整个转移到栈A,再push一个元素到栈A  ( 具体的操作只要简单画个图就能明白 )

具体见代码:

技术分享
 1 #pragma once
 2 class Stack
 3 {
 4 public:
 5     Stack();
 6     ~Stack();
 7 
 8     bool isEmpty();
 9     void push(int value);
10     int pop();
11     int count();
12 
13 private:
14     int m_nTop;
15     int m_nArray[400];
16 
17 };
Stack.h
技术分享
 1 #include "Stack.h"
 2 #include <string.h>
 3 
 4 Stack::Stack()
 5 {
 6     memset(m_nArray, sizeof(m_nArray), 0);
 7     m_nTop = -1;
 8 }
 9 
10 Stack::~Stack()
11 {
12 
13 }
14 
15 bool Stack::isEmpty()
16 {
17     return -1 == m_nTop;
18 }
19 
20 void Stack::push(int value)
21 {
22     m_nArray[++m_nTop] = value;
23 }
24 
25 int Stack::pop()
26 {
27     return m_nArray[m_nTop--];
28 }
29 
30 int Stack::count()
31 {
32     return m_nTop + 1;
33 }
Stack.cpp
技术分享
 1 #pragma once
 2 #include "Stack.h"
 3 
 4 //make a queue by using two stacks
 5 class StackQueue 
 6 {
 7 public:
 8     StackQueue();
 9     ~StackQueue();
10 
11 public:
12     void push(int value);
13     int pop(int thread_id);
14     bool isEmpty();
15     int count();
16 
17 private:
18     Stack m_InStack; //负责入队
19     Stack m_OutStack; //负责出队
20 };
StackQueue.h
技术分享
 1 #include "StackQueue.h"
 2 #include <iostream>
 3 
 4 StackQueue::StackQueue()
 5 {
 6 }
 7 
 8 StackQueue::~StackQueue()
 9 {
10 }
11 
12 bool StackQueue::isEmpty()
13 {
14     return m_InStack.isEmpty() && m_OutStack.isEmpty();
15 }
16 
17 int StackQueue::count()
18 {
19     return m_InStack.count() + m_OutStack.count();
20 }
21 
22 void StackQueue::push(int value)
23 {    
24     if (!m_OutStack.isEmpty())
25     {
26         while(!m_OutStack.isEmpty())
27         {
28             int tmp = m_OutStack.pop();
29             m_InStack.push(tmp);
30         }
31     }        
32     m_InStack.push(value);
33 }
34 
35 int StackQueue::pop(int thread_id)
36 {
37     while(!m_InStack.isEmpty())
38     {    
39         int tmp = m_InStack.pop();
40         m_OutStack.push(tmp);
41     }
42     if (!m_OutStack.isEmpty())
43     {
44         int tmp = m_OutStack.pop();
45         std::cout << "pop queue! value=" << tmp << "  thread_id=" << thread_id << std::endl;
46         return tmp;
47     }
48     else
49     {
50         std::cerr << " empty queue! pop failed! " << std::endl;
51         return -1;
52     }
53 }
StackQueue.cpp

 

相信各位看官看懂小弟的代码不成问题,然后就讲解下加入多线程环境要如何分析

      (1)由于栈A只作为入队,那么栈A入栈的时候需要锁住栈A

      (2)同理栈B只作为出队,那么栈B出栈的时候需要锁住栈B

      (3)当入队或出队时,可能会需要整个栈A转移到栈B(或栈B转移到栈A), 做转移时,需要同时锁住栈A和栈B。 注意:这里的转移操作的范围是整个栈的,直到其转移完成为止,都必须锁住栈A和栈B。

所以修改后的代码是这样的:

技术分享
 1 //头文件中定义栈A和栈B的互斥量
 2 boost::recursive_mutex in_mtx;
 3 boost::recursive_mutex out_mtx;
 4 
 5 void StackQueue::push(int value)
 6 {
 7     {    
 8         boost::recursive_mutex::scoped_lock out_lock(out_mtx); //对栈B的互斥量加锁
 9         if (!m_OutStack.isEmpty())
10         {
11             while(!m_OutStack.isEmpty())
12             {
13                 int tmp = m_OutStack.pop();
14                 boost::recursive_mutex::scoped_lock in_lock(in_mtx);  //对栈A的互斥量加锁
15                 m_InStack.push(tmp);
16             }
17         }    
18     }
19     
20     {
21                 //对栈A的互斥量加锁
22         boost::recursive_mutex::scoped_lock in_lock(in_mtx); 
23         m_InStack.push(value);
24     }    
25 }
26 
27 int StackQueue::pop(int thread_id)
28 {
29     {
30                 //对栈A的互斥量加锁
31         boost::recursive_mutex::scoped_lock in_lock(in_mtx);
32         while(!m_InStack.isEmpty())
33         {
34             
35             int tmp = m_InStack.pop();
36             boost::recursive_mutex::scoped_lock out_lock(out_mtx); //对栈B的互斥量加锁
37             m_OutStack.push(tmp);
38         }
39     }
40     
41     {
42         boost::recursive_mutex::scoped_lock out_lock(out_mtx); //对栈B的互斥量加锁
43         if (!m_OutStack.isEmpty())
44         {
45             int tmp = m_OutStack.pop();
46             std::cout << "pop queue! value=" << tmp << "  thread_id=" << thread_id << std::endl;
47             return tmp;
48         }
49         else
50         {
51             std::cerr << " empty queue! pop failed! " << std::endl;
52             return -1;
53         }
54     }
55 }
加入多线程后的入队出队操作

       懒得去查资料就用了boost的互斥量和锁,其实也就是一样的东西。 

      

用两个栈实现一个队列,并实现在多线程环境下

标签:

原文地址:http://www.cnblogs.com/elenno/p/stack_queue_multi_thread.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!