C++学习笔记_19 适配器容器-stack queue 2021-05-19

 stack 容器(栈)
只支持在栈顶  存取  元素
后进先出

queue容器(队列)
从容器尾部插入元素,从容器头部取元素
先进先出

// C++学习笔记_19 适配器容器-stack queue
#include <iostream>
#include<string>
#include<vector>
#include<list>
#include<stack>  //STL 中栈的头文件
#include<queue>
using namespace std;

void TestStack()
{
    stack<int>  iStack1; 
        //事实上,就是把 deque 封装了一下,限制了一些函数的使用,而且不提供迭代器。
        //push 调用 deque.push_back(); pop 调用 deque.pop_back(); 等等
        //这里,deque 我们称之为 底层容器 (默认使用deque做底层容器)
        //能不能用 list, vector 做底层容器呢?
    stack<int>  iStack2(iStack1);
    stack<int>  iStack3({ 1, 2, 3, 4, 5 });

    stack<int, list<int>>    iStack4; //可以使用 list   做底层容器
    stack<int, vector<int>>  iStack5; //可以使用 vector 做底层容器
            //区别就是 list 和 deque 的区别,vector 和 deque 的区别  ---》 数据的存储方式不同

    //所用容器都有的函数
    //empty()
    //size()
    cout << "压栈:";
    for (int i = 0; i < 10; i++){
        cout << i << " ";
        iStack1.push(i);
        iStack4.push(i);
        iStack5.push(i);
    }
    cout << endl;

    cout << "弹栈:";
    while (!iStack1.empty()) {
        cout << iStack1.top() << " "; //取栈顶元素

        //注意一点 iStack1.top() 
        //返回值是引用:意味着可以通过复制来修改栈顶元素
        // iStack1.top() = xxx;

        iStack1.pop();//删除栈顶元素
    }
    cout << endl;

    cout << "弹栈:";
    while (!iStack4.empty()){
        cout << iStack4.top() << " "; //取栈顶元素
        iStack4.pop();//删除栈顶元素
    }
    cout << endl;

    cout << "弹栈:";
    while (!iStack5.empty()){
        cout << iStack5.top() << " "; //取栈顶元素
        iStack5.pop();//删除栈顶元素
    }
    cout << endl;
}
void TestQueue()
{
    queue<int> iQue1;
    queue<int> iQue2(iQue1);
    queue<int> iQue3({ 1, 2, 3, 4, 5 });

    //队列的底层容器也是 deque
    //能不能用 vector 和 list ?
    //queue<int, vector<int>> iQue4; 
        //queue.pop() 弹出元素,调用的是底层容器的 pop_front()
        //vector 容器没有这个方法,所以,queue 不能是用 vector做底层容器
    queue<int, list<int>>   iQue5;

    //empty(); size()

    cout << "入队列:";
    for (int i = 0; i < 10; i++){
        cout << i << " ";
        iQue1.push(i);
        //iQue4.push(i);
        iQue5.push(i);
    }
    cout << endl;

    //O(N^2) , O(2^N)
    //可以取队头和队尾元素
    cout << "队头元素:" << iQue1.front() << endl;
    cout << "队尾元素:" << iQue1.back()  << endl;
    //这里 front() 和 back() 都返回引用 ---》可以直接赋值,修改队头和队尾元素

    cout << "出队列:";
    while (!iQue1.empty()){
        cout << iQue1.front() << " ";
        iQue1.pop(); //删除队头元素
    }
    cout << endl;

    /*
    cout << "出队列:";
    while (!iQue4.empty()){        
        cout << iQue4.front() << " ";
        //error C2039: “pop_front”: 不是“std::vector<int,std::allocator<_Ty>>”的成员
        iQue4.pop(); //删除队头元素
    }
    cout << endl;
    */

    cout << "出队列:";
    while (!iQue5.empty()){
        cout << iQue5.front() << " ";
        iQue5.pop(); //删除队头元素
    }
    cout << endl;
}
int main()
{
    TestStack();
    TestQueue();
    system("pause");
	return 0;
}
//C 语言的 栈实现
#include <iostream>
using namespace std; 
//创建栈结构体 
typedef struct tagStack
{
    int *pBase;  //栈内存起始地址
    int *pTop;   //栈顶指针 (下一个元素存在这里)
    int size;    //栈的长度
} MyStack;
//申请栈 
int InitStack(MyStack *pStack, int sz)
{
    pStack->pBase = (int*)malloc(sz*sizeof(int));
    if (pStack->pBase == NULL) return -1;
    pStack->pTop = NULL; //表示空栈
    pStack->size = sz;
    return 0;
}
//进栈
int push(MyStack *pStack, int data)
{
    //1: 空间不够
    if (pStack->pTop == pStack->pBase + pStack->size - 1) return -1;
    //栈顶上移
    if (pStack->pTop == NULL) pStack->pTop = pStack->pBase;
    else (pStack->pTop)++;
    //存元素到栈顶
    *(pStack->pTop) = data;
    return 0;
}
//出栈, 直接删除栈顶,返回成功或者失败
int pop(MyStack *pStack)
{
    //空栈
    if (pStack->pTop == NULL) return -1;
    (pStack->pTop)--;
    //并没有做删除元素的操作 (指针下移,把元素位置置为不可用)
    return 0;
}
//取栈顶元素, 返回栈顶元素
int top(MyStack *pStack)
{
    //考虑一个问题:空栈?
    //if (pStack->pTop == NULL)
    //{
        //写断言,抛出异常,....
        //也可以不写,有使用者保证空栈的时候,不调用它
    //}
    return *(pStack->pTop);
}
bool empty(MyStack *pStack)
{
    return !(pStack->pTop == NULL);
}
//获取栈中元素个数 (不是栈的大小)
int size(MyStack *pStack)
{
    if (pStack->pTop == NULL) return  0;
    else
        return pStack->pTop - pStack->pBase + 1;
}
//释放栈内存
void DestroyStack(MyStack *pStack)
{
    if (pStack->pBase){
        free(pStack->pBase);
        pStack->pBase = NULL;
        pStack->pTop = NULL;
        pStack->size = 0;
    }
}
void Test_MyStack()
{
	MyStack *pStack;
	InitStack(pStack, 5);
	for(int i=0;i<5;i++)
	 	push(pStack, i+1);
	cout<<top(pStack)<<endl;
	cout<<pop(pStack)<<endl;
	cout<<top(pStack)<<endl;
	cout<<empty(pStack)<<endl;
	cout<<size(pStack)<<endl;
	DestroyStack(pStack);
	cout<<size(pStack)<<endl;	
} 
int main()
{
	Test_MyStack();
	return 0;
}
typedef struct tagQueue
{
    int *pBase; //指定内存起始位置
    int *pHead;
    int *pTail;
    int size;
}MyQueue;
//pBase 基址
//pTail 指向队尾元素
//为了不移动元素,我们再定义一个 pHead 指针,指向队头元素 (做成一个循环形式)
//1:一个元素出队 --》把 pHead 后移
//2:pTail 到了末尾位置? --》判断 pHead 是不是在 pBase
//       是的话,表示存满了,不是的话,存到 pBase 位置来 (跳转到起始位置)
//3:同样的 pHead 到了末尾,移动到 pBase 位置
//   这个时候 如果 pTail 也在这个位置,表示队列是空的了
//4:事实上:pHead == pTail 表示队列是空的
//   pTail 的后一个位置(末尾的后一个位置就跳到了队头),是 pHead 表示队列满了
//5:所以我们要注意一点:N 个长度的队列,只能插入 N-1 个元素
//   有个位置留白,用于区分到底是空队列还是满队列

//作业:自己实现队列  InitQueue   push   pop  front  back  empty  size  destroy

猜你喜欢

转载自blog.csdn.net/lybc2019/article/details/117018269
今日推荐