双栈(Dual Stack)

双栈(Dual Stack)
1. 双栈的概念
1.1 双栈的定义
双栈是指两个顺序栈,是一种特殊的顺序栈。
1.2 双栈中各元素的逻辑及存储关系
双栈共享一个地址连续的存储单元。即程序同时需要两个栈时,可以定义一个足够大的栈空间,该空间的两端分别设为两个栈的栈底,用bottom[0]=-1和bottom[1]=maxSize指示。
压入数据时,让两个栈的栈顶top[0]和top[1]都向中间伸展,如果指示栈顶的指针top[0]+1等于另一个栈顶的指针top[1]时两栈已满。
每次进栈时top[0]加1或top[1]减1,而退栈时top[0]减1或top[1]加1。
如果top[0] == -1且top[1] == maxSize两栈为空。
双栈的模型: 

在双栈的情形下: 
(1)栈的初始化语句:bottom[0]=top[0]=-1,bottom[1]=top[1]=maxSize。 
(2)栈满的条件:top[0]+1 == top[1]。 
(3)栈空的条件:bottom[0]==top[0]==-1且bottom[1]==top[1]==maxSize。
2. 双栈的实现
2.1 双栈的类定义及其操作的实现
文件:DualStack.h


#ifndef DUAL_STACK_H_


#define DUAL_STACK_H_

#include <iostream>


#include <string>


#include <strstream>


using namespace std;

const int defaultSize = 50;         //默认栈空间大小
const int stackIncreament = 20;     //栈溢出时扩展空间的增量
const int n = 2;                    //设置n=2个栈共有一个栈空间

template <class T>
class DualStack
{
public:
    DualStack(int sz = defaultSize);        //构造函数
    ~DualStack();                           //析构函数
public:
    bool Push(const T& x, int d) ;      //新元素x进栈
    bool Pop(T& x, int d);              //栈顶元素出栈,并将该元素的值保存至x
    bool getTop(T& x, int d) const;     //读取栈顶元素,并将该元素的值保存至x
    bool IsEmpty() const;               //判断栈是否为空
    bool IsFull() const;                //判断栈是否为满
    int getSize() const;                //计算栈中元素个数
    void MakeEmpty();                   //清空栈的内容
    void overflowProcess();             //栈的溢出处理
public:
    template <class T>
    friend ostream& operator<<(ostream& os, const DualStack<T>& s); //输出栈中元素的重载操作<<
private:
    T *Vector;      //存放栈中元素的栈数组
    int top[n];     //栈顶指针
    int maxSize;    //栈最大可容纳元素个数
};

//构造函数
template <class T>
DualStack<T>::DualStack(int sz)
{
    cout << "$ 执行构造函数" << endl;
    if (sz >= 0)
    {
        maxSize = sz;           
        top[0] = -1;
        top[1] = maxSize;
        Vector = new T[maxSize];
    }
}                       

//析构函数
template <class T>
DualStack<T>::~DualStack()
{
    cout << "$ 执行析构函数" << endl;
    delete[] Vector;
    Vector = NULL;
}   

//新元素x进栈
template <class T>
bool DualStack<T>::Push(const T& x, int d)
{
    if (true == IsFull())
    {
        return false;
    }
    if (0 == d)
    {
        top[0]++;
    }
    else
    {
        top[1]--;
    }
    Vector[top[d]] = x;
    return true;
}

//栈顶元素出栈,并将该元素的值保存至x
template <class T>
bool DualStack<T>::Pop(T& x, int d)
{
    if (true == IsEmpty())
    {
        return false;
    }
    x = Vector[top[d]];
    if (0 == d)
    {
        top[0]--;
    }
    else
    {
        top[1]++;
    }
    return true;
}

//读取栈顶元素,并将该元素的值保存至x
template <class T>
bool DualStack<T>::getTop(T& x, int d) const
{
    if (true == IsEmpty())
    {
        return false;
    }
    x = Vector[top[d]];
    return true;
}

//判断栈是否为空
template <class T>
bool DualStack<T>::IsEmpty() const
{
    return ((-1 == top[0]) && (maxSize == top[1])) ? true : false;
}

//判断栈是否为满
template <class T>
bool DualStack<T>::IsFull() const
{
    return (top[0] + 1 == top[1]) ? true : false;
}

//计算栈中元素个数
template <class T>
int DualStack<T>::getSize() const
{
    return (top[0] + 1) + (maxSize - top[1]);
}

//清空栈的内容
template <class T>
void DualStack<T>::MakeEmpty()
{
    delete[] Vector;
    top[0] = -1;
    top[1] = maxSize;
    Vector = new T[maxSize];
}

//栈的溢出处理
template <class T>
void DualStack<T>::overflowProcess()
{
    int newSize = maxSize + stackIncreament;
    T *neweVector = new T[newSize];
    for (int i = 0; i <= top[0]; i++)
    {
        neweVector[i] = Vector[i];
    }
    for (int i = maxSize - 1; i >= top[1]; i--)
    {
        neweVector[i + stackIncreament] = Vector[i];
    }
    delete[] Vector;
    Vector = neweVector;
    maxSize = newSize;
    top[1] += stackIncreament;
}

//输出栈中元素的重载操作<<
template <class T>
ostream& operator<<(ostream& os, const DualStack<T>& s)
{
    os << "top[0]=" << s.top[0] << endl;    //输出栈1顶位置
    for (int i = 0; i <= s.top[0]; i++)
    {
        os << "[" << i << "]" << " : " << s.Vector[i] << endl;
    }
    os << "top[1]=" << s.top[1] << endl;    //输出栈2顶位置
    for (int i = s.maxSize - 1; i >= s.top[1]; i--)
    {
        os << "[" << i << "]" << " : " << s.Vector[i] << endl;
    }
    return os;
}


#endif /* DUAL_STACK_H_ */
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
2.2 主函数(main函数)的实现
文件:main.cpp


#include "DualStack.h"

#define EXIT 0              //退出


#define PUSH 1              //新元素x进栈


#define POP  2              //栈顶元素出栈,并将该元素的值保存至x


#define GETTOP 3            //读取栈顶元素,并将该元素的值保存至x


#define ISEMPTY  4          //判断栈是否为空


#define ISFULL 5            //判断栈是否为满


#define GETSIZE 6           //计算栈中元素个数


#define MAKEEMPTY 7         //清空栈的内容


#define OPERATOR_OSTREAM 8  //输出栈中元素的重载操作<<


#define OVERFLOWPROCESS 9   //栈的溢出处理


void print_description()
{
    cout << "------------------------------>双栈<------------------------------" << endl;
    cout << "功能选项说明:" << endl;
    cout << "#0: 退出" << endl;
    cout << "#1: 新元素x进栈" << endl;
    cout << "#2: 栈顶元素出栈,并将该元素的值保存至x" << endl;
    cout << "#3: 读取栈顶元素,并将该元素的值保存至x" << endl;
    cout << "#4: 判断栈是否为空" << endl;
    cout << "#5: 判断栈是否为满" << endl;
    cout << "#6: 计算栈中元素个数" << endl;
    cout << "#7: 清空栈的内容" << endl;
    cout << "#8: 输出栈中元素的重载操作<<" << endl;
    cout << "#9: 栈的溢出处理" << endl;
    cout << "--------------------------------------------------------------------" << endl;
}

//判断输入的字符串每个字符是否都是数值0~9
bool IsStackNumber(const string& s_num)
{
    if (s_num.size() > 1)
    {
        return false;
    }

    if ((s_num[0] != '0') && (s_num[0] != '1'))
    {
        return false;
    }

    return true;
}

//判断输入的字符串每个字符是否都是数值0~9
bool IsNumber(const string& s_num)
{
    for (size_t i = 0; i < s_num.size(); i++)
    {
        if ((s_num[i] < '0') || (s_num[i] > '9'))
        {
            return false;
        }
    }
    return true;
}

//类型转换——将string型转为模板类型T
template <class T>
T StrToTtype(const string& s_num)
{
    T n_num;
    strstream ss_num;
    ss_num << s_num;
    ss_num >> n_num;
    return n_num;
}

//输入栈编号
template <class T>
int get_item()
{
    cout << "> 请输入栈编号,item = ";
    string s_item;
    cin >> s_item;
    while (false == IsStackNumber(s_item))
    {
        cout << "* 输入有误,请重新输入:";
        cin >> s_item;
    }
    return atoi(s_item.c_str());
}

//输入数据值
template <class T>
T get_data()
{
    cout << "> 请输入数据值,data = ";
    string s_data;
    cin >> s_data;
    return StrToTtype<T>(s_data);
}

//输入数组的最大长度
template <class T>
int get_maxsize()
{
    cout << "> 请输入数组的最大长度,maxsize = ";
    string s_maxsize;
    cin >> s_maxsize;
    while (false == IsNumber(s_maxsize))
    {
        cout << "* 输入有误,请重新输入:";
        cin >> s_maxsize;
    }
    return atoi(s_maxsize.c_str());
}

//构造双栈
template <class T>
DualStack<T>* construct_dualstack()
{
    cout << "\n==> 创建双栈" << endl;
    int n_maxsize = get_maxsize<T>();
    DualStack<T> *dualStack = new DualStack<T>(n_maxsize);
    return dualStack;
}

//析构双栈
template <class T>
void destory_seqstack(DualStack<T>* dualStack)
{
    cout << "\n==> 释放双栈在堆中申请的空间,并将指向该空间的指针变量置为空" << endl;
    delete dualStack;
    dualStack = NULL;
}

//新元素x进栈
template <class T>              
void push(DualStack<T>* dualStack)
{
    cout << "$ 执行新元素x进栈函数" << endl;
    T data = get_data<T>();
    int d = get_item<T>();
    if (false == dualStack->Push(data, d))
    {
        cout << "* 进栈失败" << endl;
        return;
    }
    cout << "* 进栈成功,data = " << data << endl;
}

//栈顶元素出栈,并将该元素的值保存至x
template <class T>  
void pop(DualStack<T>* dualStack)
{
    cout << "$ 执行栈顶元素出栈并将该元素的值保存至x函数" << endl;
    T data;
    int d = get_item<T>();
    if (false == dualStack->Pop(data, d))
    {
        cout << "* 出栈失败" << endl;
        return;
    }
    cout << "* 出栈成功,data = " << data << endl;
}

//读取栈顶元素,并将该元素的值保存至x
template <class T>  
void gettop(DualStack<T>* dualStack)
{
    cout << "$ 执行读取栈顶元素并将该元素的值保存至x函数" << endl;
    T data;
    int d = get_item<T>();
    if (false == dualStack->getTop(data, d))
    {
        cout << "* 读取栈顶元素失败" << endl;
        return;
    }
    cout << "* 读取栈顶元素成功,data = " << data << endl;
}

//判断栈是否为空
template <class T>  
void isempty(DualStack<T>* dualStack)
{
    cout << "$ 执行判断栈是否为空函数,IsEmpty = " << dualStack->IsEmpty() << endl;
}

//判断栈是否为满
template <class T>  
void isfull(DualStack<T>* dualStack)
{
    cout << "$ 执行判断栈是否为满函数,IsFull = " << dualStack->IsFull() << endl;
}

//计算栈中元素个数
template <class T>  
void getsize(DualStack<T>* dualStack)
{
    cout << "$ 执行计算栈中元素个数函数,Size = " << dualStack->getSize() << endl;
}

//清空栈的内容
template <class T>  
void makeempty(DualStack<T>* dualStack)
{
    cout << "$ 执行清空栈的内容函数" << endl;
    dualStack->MakeEmpty();
}

//输出栈中元素的重载操作<<
template <class T>  
void operator_ostream(DualStack<T>* dualStack)
{
    cout << "$ 执行输出栈中元素的重载操作<<函数" << endl;
    cout << *dualStack;//或operator<<(cout, *dualStack);
}

//栈的溢出处理
template <class T>
void overflowprocess(DualStack<T>* dualStack)
{
    cout << "$ 执行栈的溢出处理函数" << endl;
    dualStack->overflowProcess();
}

//双栈操作选择
template <class T>
void select_operation(DualStack<T>* dualStack)
{
    if (NULL == dualStack)
    {
        cout << "* 没有构造双栈,请先构造双栈。" << endl;
        return;
    }

    string s_operation;
    while (s_operation != "0")
    {
        cout << "\n==> 请输入功能选项编号(按\"0\"退出程序):";
        cin >> s_operation;
        while (false == IsNumber(s_operation))
        {
            cout << "* 输入有误,请重新输入:";
            cin >> s_operation;
        }
        int n_operation = atoi(s_operation.c_str());
        switch (n_operation)
        {
            case EXIT://退出
            {
                cout << "$ 退出程序" << endl;
                break;
            }
            case PUSH://新元素x进栈
            {
                push(dualStack);
                break;
            }
            case POP://栈顶元素出栈,并将该元素的值保存至x
            {
                pop(dualStack);
                break;
            }
            case GETTOP://读取栈顶元素,并将该元素的值保存至x
            {
                gettop(dualStack);
                break;
            }
            case ISEMPTY://判断栈是否为空
            {
                isempty(dualStack);
                break;
            }
            case ISFULL://判断栈是否为满
            {
                isfull(dualStack);
                break;
            }
            case GETSIZE://计算栈中元素个数
            {
                getsize(dualStack);
                break;
            }
            case MAKEEMPTY://清空栈的内容
            {
                makeempty(dualStack);
                break;
            }
            case OPERATOR_OSTREAM://输出栈中元素的重载操作<<
            {
                operator_ostream(dualStack);
                break;
            }
            case OVERFLOWPROCESS://栈的溢出处理
            {
                overflowprocess(dualStack);
                break;
            }
            default:
            {
                cout << "* 请输入正确的功能选项编号" << endl;
                break;
            }
        }
    }
}

int main(int argc, char* argv[])
{
    print_description();
    DualStack<int> *dualStack = construct_dualstack<int>();
    select_operation(dualStack);
    destory_seqstack(dualStack);
    system("pause");
    return 0;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
3. 双栈的优缺点
3.1 优点
两栈的大小不是固定不变的,在实际运算过程中,一个栈有可能进栈元素多而体积大些,另一个则可能小些。
两个栈共用一个栈空间,相互调剂,灵活性强。
3.2 缺点
运算较为复杂。
长度为定值,中途不易扩充。
注:n(n>2)个栈的情况更有所不同,采用多个栈共享栈空间的顺序存储表示方式,处理十分复杂,在插入时元素的移动量很大,因而时间代价较高。特别是当整个存储空间即将充满时,这个问题更加严重。
解决上述问题的办法就是采用链接方式作为栈的存储表示方式。
3.3 双栈的适用情况
当栈满时要发生溢出,为了避免这种情况,需要为栈设立一个足够大的空间。但如果空间设置得过大,而栈中实际只有几个元素,也是一种空间浪费。此外,程序中往往同时存在几个栈,因为各个栈所需的空间在运行中是动态变化着的。如果给几个栈分配同样大小的空间,可能实际运行时,有的栈膨胀得快,很快就产生了溢出,而其他的栈可能此时还有许多空闲空间。这时就可以利用双栈,两个栈共用一个栈空间,相互调剂,灵活性强。
参考文献: 
[1]《数据结构(用面向对象方法与C++语言描述)(第2版)》殷人昆——第三章 
[2]《C/C++常用算法手册》秦姣华、向旭宇——第二章 
[3] 百度搜索关键字:双栈
————————————————
版权声明:本文为CSDN博主「Cainv89」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/cainv89/article/details/51398148

  • 2
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: Fortigate是一种网络安全设备,用于保护网络免受网络攻击和安全威胁。然而,Fortigate不支持双栈协议,这意味着它不能同时支持IPv4和IPv6协议。 IPv4是目前广泛使用的Internet协议,但它已经达到了可用地址的极限。因此,IPv6作为IPv4的后继者正在逐渐流行。由于IPv6的地址空间更大,因此它可以提供更多的地址和更好的网络性能。 然而,由于Fortigate不支持双栈协议,它无法同时使用IPv4和IPv6地址。因此,它在网络过渡期间的使用受到了一定的限制,需要适当的网络规划和升级才能实现更好的网络性能和安全性。 综上所述,Fortigate不支持双栈协议,因此需要对网络进行适当的规划和升级,以便在IPv4和IPv6之间实现平稳的过渡。同时,我们也需要考虑未来的网络安全和性能需求,以确保我们的网络能够满足不断变化的需求。 ### 回答2: Fortigate不支持双栈功能。双栈是IPv4与IPv6协议的混合使用,可以使网络具备向IPv6协议的过渡能力。但目前Fortigate不能同时支持IPv4和IPv6协议的双栈,仅支持其中一种协议。因此在使用Fortigate时需要根据实际情况选择哪种协议来支持。如果需要支持IPv6协议,就可能需要使用其他的网络设备来进行转换或兼容。如果需要支持IPv4协议,则可以继续使用Fortigate进行网络防护和管理。总之,需要注意Fortigate的协议支持范围,以确保网络安全和正常运行。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值