栈与队列模拟

1.两个栈模拟一个队列

定义两个栈S1和S2,数据入栈时只给S1入,出栈时首先判断S2空不空,不空则直接从S2出栈,空则将S1中的数据放进S2,然后从S2出。

对于栈的操作直接调用之前写的函数即可

typedef stuct TSTQueue
{
    LinkStack S1;
    LinkStack S2;
}TSTQueue;


1.初始化

将两个栈都初始化,S1用来入栈,S2用来出栈

void Init_Two_Stack_To_Queue(TSTQueue* head)
{
    Init_LinkStack(&head->S1);
    Init_LinkStack(&head->S2);
    
}

2.入队

数据全都给S1入

bool Push_TSTQ(TSTQueue* head,ELEM_TYPE val)
{
    assert(tstq != NULL);
    return Push(&head->S1,val);
}

3.出队

从S2出,如果S2非空直接出即可,如果为空,则将S1中的数据全部倒入S2,再从S2出栈

bool Pop_TSTQ(TSTQueue* head)
{
    assert(head != NULL);
    //保证有数据可以出栈
    if(IsEmpty(&head->S1) && IsEmpty(&head->S2))
        return false;
    
    //如果S2空,说明剩余数据在S1中
    if(IsEmpty(&head->S2))
    {
        while(!IsEmpty(&head->S1))//将S1中的数据全部倒入S2中
        {
            ELEM_TYPE tmp = Top(&head->S1);//将S1的栈顶元素取出
            Pop(&head->S1);//删掉
            Push(&head->S2,tmp);//放入S2中
        }
    }
    return Pop(&head->S2);
}

4.获取队头元素

跟出队代码几乎一样,只需要将return Pop改成return Top

ELEM_TYPE TSTQ_Front(TSTQueue* head)
{
    assert(head != NULL);
    if(IsEmpty(&head->S1) && IsEmpty(&head->S2))
        return false;
    //如果S2空,说明剩余数据在S1中
    if(IsEmpty(&head->S2))
    {
        while(!IsEmpty(&head->S1))//将S1中的数据全部倒入S2中
        {
            ELEM_TYPE tmp = Top(&head->S1);//将S1的栈顶元素取出
            Pop(&head->S1);//删掉
            Push(&head->S2,tmp);//放入S2中
        }
    }
    return Top(&head->S2);
}

2.两个队列模拟一个栈

入栈和出栈操作步骤:

​ 入栈:只往Q2入

​ 出栈:首先判断Q2空不空,若不空,则除最后一个元素外,剩余元素全部转移到Q1中,此时Q2仅剩下一个要操作的元素;若空,则数据都在Q1里,则将Q1里除最后一个元素外,剩余元素全部转移到Q2中,此时Q1仅剩下一个要操作的元素

typedef struct TQTStack
{
    queue<char> Q1;
    queue<char> Q2;
}TQTStack;

1.入栈

只给Q2入

bool Push_TQTS(TQTStack* head,char ch)
{
    assert(head != NULL);
    head->Q2.push(ch);
    return true;
}

2.出栈

bool Pop_TQTS(TQTStack* head)
{
    assert(head != NULL);
    if(head->Q1.empty() && head->Q2.empty())
        return false;
    if(!head->Q2.empty())
    {
        //Q2不为空,则将除最后一个元素外的元素全都放到Q1里
        while(head->Q2.front() != head->Q2.back())
        {
            char tmp = head->Q2.front();
            head->Q2.pop();
            head->Q1.push(tmp);
        }
        head->Q2.pop();
        return true;
    }
    else
    {
        //Q2为空,那就将Q1中除最后一个元素外全都放在Q2中
        while(head->Q1.front() != head->Q1.back())
        {
            char tmp = head->Q1.front();
            head->Q1.pop();
            head->Q2.push(tmp);
        }
        head->Q1.pop();
	}
}

3.获取栈顶元素

与出栈并不相似,不能改变队列顺序,所以再获取完元素还应该还原,否则后续出栈会乱

char Top_TQTStack(TQTStack* head)
{
    assert(head != NULL);
    if(head->Q1.empty() && head->Q2.empty())
        return false;
    if(!Q2.empty())
    {
        //如果Q2不为空,则先将Q2中除最后一个元素外的元素倒入Q1中,然后取Q2最后一个元素返回,返回后需将这个元素再倒入Q1中,还原队列,否则后续操作会打乱队列原本顺序
        while(head->Q2.front() != head->Q2.back())
        {
            char tmp = head->Q2.front();
            head->Q1.push(tmp);
        }
        char tmp = head->Q2.front();
        head->Q2.pop();
        head->Q1.push(tmp);
        return tmp;
    }
    else
    {
        //t
        while(head->Q1.front() != head->Q1.back())
        {
            char tmp = head->Q1.front();
            head->Q1.pop();
            head->Q2.push(tmp);
        }
        char tmp = head->Q1.front();
        head->Q1.pop();
        head->Q2.push(tmp);
        return tmp;
	}
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值