数据结构-用顺序存储方式实现循环队列的 6 种情况 (C++)

用顺序存储方式实现循环队列的 6 种情况(可运行)

王道书提到的 线性队列 实现的 6 种情况,其对应代码实现如下。
为增加可读性使用 ANSI 代码设置输出文本颜色,Windows 系统建议使用 powershell 运行。

// test.cpp
// 编译运行命令 g++ test.cpp -otest ; ./test
#include <iostream>
using namespace std;
#define MaxSize 10
#define ElemType int
// 队尾指针Q.rear的位置:
//   (a)指向表尾的后一位   (b)指向表尾
// 判断队满队空的三种方法:
//   1. 牺牲存储单元  2.引入size变量   3.引入tag变量(true表示入队,false表示出队)

// 注意:C++取模运算所得结果的符号与被除数相同。
//a1
struct a1 { ElemType data[MaxSize]; int front, rear; };
void InitQueue(a1 &Q) { Q.front = Q.rear = 0; }
bool EnQueue(a1 &Q, ElemType x) { if ((Q.rear + 1) % MaxSize == Q.front) return false; Q.data[Q.rear] = x; Q.rear = (Q.rear + 1) % MaxSize; return true; }
bool DeQueue(a1 &Q, ElemType &x) { if (Q.front == Q.rear) return false; x = Q.data[Q.front]; Q.front = (Q.front + 1) % MaxSize; return true; }
//a2
struct a2 { ElemType data[MaxSize]; int front, rear, size; };
void InitQueue(a2 &Q) { Q.front = Q.rear = Q.size = 0; }
bool EnQueue(a2 &Q, ElemType x) { if (Q.size == MaxSize) return false; Q.data[Q.rear] = x; Q.rear = (Q.rear + 1) % MaxSize; Q.size++; return true; }
bool DeQueue(a2 &Q, ElemType &x) { if (Q.size == 0) return false; x = Q.data[Q.front]; Q.front = (Q.front + 1) % MaxSize; Q.size--; return true; }
//a3
struct a3 { ElemType data[MaxSize]; int front, rear; bool tag; };
void InitQueue(a3 &Q) { Q.front = Q.rear = 0; Q.tag = false; }
bool EnQueue(a3 &Q, ElemType x) { if (Q.front == Q.rear && Q.tag) return false; Q.data[Q.rear] = x; Q.rear = (Q.rear + 1) % MaxSize; Q.tag = true; return true; }
bool DeQueue(a3 &Q, ElemType &x) { if (Q.front == Q.rear && !Q.tag) return false; x = Q.data[Q.front]; Q.front = (Q.front + 1) % MaxSize; Q.tag = false; return true; }
//b1
struct b1 { ElemType data[MaxSize]; int front, rear; };
void InitQueue(b1 &Q) { Q.front = 0; Q.rear = MaxSize - 1; }
bool EnQueue(b1 &Q, ElemType x) { if ((Q.rear + 2) % MaxSize == Q.front) return false; Q.rear = (Q.rear + 1) % MaxSize; Q.data[Q.rear] = x; return true;}
bool DeQueue(b1 &Q, ElemType &x) { if ((Q.rear + 1) % MaxSize == Q.front) return false; x = Q.data[Q.front]; Q.front = (Q.front + 1) % MaxSize; return true;}
//b2
struct b2 { ElemType data[MaxSize]; int front, rear, size; };
void InitQueue(b2 &Q) { Q.front = Q.size = 0; Q.rear = MaxSize - 1; }
bool EnQueue(b2 &Q, ElemType x) { if (Q.size == MaxSize) return false; Q.rear = (Q.rear + 1) % MaxSize; Q.data[Q.rear] = x; Q.size++; return true; }
bool DeQueue(b2 &Q, ElemType &x) { if (Q.size == 0) return false; x = Q.data[Q.front]; Q.front = (Q.front + 1) % MaxSize; Q.size--; return true; }
//b3
struct b3 { ElemType data[MaxSize]; int front, rear; bool tag; };
void InitQueue(b3 &Q) { Q.front = 0; Q.rear = -1; Q.tag = false; }
bool EnQueue(b3 &Q, ElemType x) { if ((Q.rear + 1) % MaxSize == Q.front && Q.tag) return false; Q.rear = (Q.rear + 1) % MaxSize; Q.data[Q.rear] = x; Q.tag = true; return true; }
bool DeQueue(b3 &Q, ElemType &x) { if ((Q.rear + 1) % MaxSize == Q.front && !Q.tag) return false; x = Q.data[Q.front]; Q.front = (Q.front + 1) % MaxSize; Q.tag = false; return true; }

void PrintQueue(a1 &Q) { cout << "- a1 "; for (int i = 0; i < (Q.rear - Q.front + MaxSize) % MaxSize; i++) printf("\e[33m%d\e[0m|", Q.data[(Q.front + i) % MaxSize]); cout << endl; }
void PrintQueue(a2 &Q) { cout << "- a2 "; for (int i = 0; i < Q.size; i++) printf("\e[33m%d\e[0m|", Q.data[(Q.front + i) % MaxSize]); cout << endl; }
void PrintQueue(a3 &Q) { cout << "- a3 "; int size = ((Q.rear == Q.front) && Q.tag) ? MaxSize : (Q.rear - Q.front + MaxSize) % MaxSize; for (int i = 0; i < size; i++) printf("\e[33m%d\e[0m|", Q.data[(Q.front + i) % MaxSize]); cout << endl; } 
void PrintQueue(b1 &Q) { cout << "- b1 "; for (int i = 0; i < (Q.rear - Q.front + 1 + MaxSize) % MaxSize; i++) printf("\e[33m%d\e[0m|", Q.data[(Q.front + i) % MaxSize]); cout << endl; }
void PrintQueue(b2 &Q) { cout << "- b2 "; for (int i = 0; i < Q.size; i++) printf("\e[33m%d\e[0m|", Q.data[(Q.front + i) % MaxSize]); cout << endl; }
void PrintQueue(b3 &Q) { cout << "- b3 "; int size = ((Q.rear - Q.front + 1) % MaxSize == 0 && Q.tag) ? MaxSize : (Q.rear - Q.front + 1 + MaxSize) % MaxSize; for (int i = 0; i < size; i++) printf("\e[33m%d\e[0m|", Q.data[(Q.front + i) % MaxSize]); cout << endl; }
void Do (bool fun, const char* msg) { if (!fun) printf("\e[1;3;31m[%s]失败\e[0m   "); }

void testQueue() {
    printf("执行\e[32m线性队列\e[0m测试\n");
    a1 a1; a2 a2; a3 a3; b1 b1; b2 b2; b3 b3;
    InitQueue(a1); InitQueue(a2); InitQueue(a3); InitQueue(b1); InitQueue(b2); InitQueue(b3);
    ///
    // 此处修改测试代码

    // 把队列一次性填满
    for (int i = 0; i < MaxSize; i++) { Do(EnQueue(a1, i + 1), "a1入队"); Do(EnQueue(a2, i + 1), "a2入队"); Do(EnQueue(a3, i + 1), "a3入队"); Do(EnQueue(b1, i + 1), "b1入队"); Do(EnQueue(b2, i + 1), "b2入队"); Do(EnQueue(b3, i + 1), "b3入队"); } cout << endl;
    PrintQueue(a1); PrintQueue(a2); PrintQueue(a3); PrintQueue(b1); PrintQueue(b2); PrintQueue(b3);
    printf("a1和b1各少了一个元素,恰好是通过\e[33m牺牲一个元素位置\e[0m来判断队空队满的体现。\n");

    printf("\n\e[32m各出队 5 次\e[0m");
    ElemType res = 0;
    for (int i = 0; i < 5; i++) { Do(DeQueue(a1, res), "a1出队"); Do(DeQueue(a2, res), "a2出队"); Do(DeQueue(a3, res), "a3出队"); Do(DeQueue(b1, res), "b1出队"); Do(DeQueue(b2, res), "b2出队"); Do(DeQueue(b3, res), "b3出队"); } cout << endl;
    PrintQueue(a1); PrintQueue(a2); PrintQueue(a3); PrintQueue(b1); PrintQueue(b2); PrintQueue(b3);

    printf("\n\e[32m各入队 3 次\e[0m");
    for (int i = 0; i < 3; i++) { Do(EnQueue(a1, i + 1), "a1入队"); Do(EnQueue(a2, i + 1), "a2入队"); Do(EnQueue(a3, i + 1), "a3入队"); Do(EnQueue(b1, i + 1), "b1入队"); Do(EnQueue(b2, i + 1), "b2入队"); Do(EnQueue(b3, i + 1), "b3入队"); } cout << endl;
    PrintQueue(a1); PrintQueue(a2); PrintQueue(a3); PrintQueue(b1); PrintQueue(b2); PrintQueue(b3);

    ///
    
}

int main(int argc, char const *argv[])
{
    testQueue();
    cout << endl;
    return 0;
}

@echo off
chcp 65001 > nul
@REM 文件名run.bat,运行程序的简易批处理脚本
(g++ test.cpp -otest ) && (
    echo 编译完成 正在执行
    echo +++++++++++++++++++++
    (test) && (
        echo.
        echo +++++++++++++++++++++
        echo 执行完成
    ) ||(
        echo.
        echo ---------------------
        echo 程序执行出错)
) || (echo 编译出错)
@REM pause
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值