第3章课后习题算法设计题(严蔚敏数据结构c语言版第2版)

3-1 将编号0和1的两个栈存放于一个数组空间V[m]中,栈顶分别处于数组两端。两栈均从两端向中间增长,试编写双栈初始化,判断栈空、栈满、进栈和出栈等算法的函数。双栈数据结构的定义如下:
typedef struct
{
int top[2],bot[2];//栈顶和栈底指针
SElemType *V;//栈数组
int m; //栈最大可容纳元素个数
}DblStack;

#include<iostream>
using namespace std;
#define MAXSIZE 100
typedef struct{
    int top[2],bot[2];
    int *V;
    int m;
}DblStack;
void InitStack(DblStack &s);
void CheckNull(DblStack s);
void CheckFull(DblStack s);
void Push(DblStack &s,int n);
void Pop(DblStack &s,int n);

int main(){
    DblStack s;
    int n,choice;
    InitStack(s);
    CheckNull(s);
    cout<<"请输入进栈个数:";
    cin>>n;
    Push(s,n);
    cout<<"请输入出栈个数:";
    cin>>n;
    Pop(s,n);
    CheckFull(s);

    return 0;
}
//双栈初始化
void InitStack(DblStack &s){
    cout<<"请输入栈长:";
    cin>>s.m;
    s.bot[0]=0;
    s.bot[1]=s.m-1;
    s.top[0]=s.bot[0];
    s.top[1]=s.bot[1];
    cout<<"双栈长度为:"<<s.m<<endl;
}
//判断栈空
void CheckNull(DblStack s){
    if(s.top[0]==s.bot[0]&&s.top[1]==s.bot[1]){
        cout<<"两个栈都为空"<<endl;
    }else if(s.top[0]==s.bot[0]&&s.top[1]!=s.bot[1]){
        cout<<"只有第一个栈为空"<<endl;
    }else if(s.top[0]!=s.bot[0]&&s.top[1]==s.bot[1]){
        cout<<"只有第二个栈为空"<<endl;
    }else{
        cout<<"两个栈都不为空"<<endl;
    }
}
//栈满:两个栈顶相邻
void CheckFull(DblStack s){
    if(s.top[1]-s.top[0]==1){
        cout<<"栈满了"<<endl;
    }else{
        cout<<"栈未满"<<endl;
    }
}
/*入栈:n为入栈总个数,选择入哪个栈,
        如果为1号栈,先输入索引为top[0]值的位置的值,再让top[0]值+1,
        如果为2号栈,先输入索引为top[1]值的位置的值,再让top[1]值-1,
        接着又判断入哪个栈,重复操作直至入栈总个数达到预定值*/
void Push(DblStack &s,int n){
    int e,choice;
    for(int i=0;i<n;i++){
        cout<<"进哪个栈(1为1号栈,2为2号栈):";
        cin>>choice;
        if(choice==1){
            if(s.top[1]-s.top[0]==1){
                cout<<"栈满无法进栈"<<endl;
                break;
            }else{
                cout<<"进1号栈值为:";
                cin>>e;
                s.V[s.top[0]++]=e;
            }
        }else{
            if(s.top[1]-s.top[0]==1){
                cout<<"栈满无法进栈"<<endl;
                break;
            }else{
                cout<<"进2号栈值为:";
                cin>>e;
                s.V[s.top[1]--]=e;
            }
        }
    }
}
/*出栈:n为出栈总个数,选择出哪个栈,
如果为1号栈,top[0]值先-1,再输出索引为top[0]值的位置的值,
如果为2号栈,top[1]值先+1,再输出索引为top[1]值的位置的值,
接着又判断出哪个栈,重复操作直至出栈总个数达到预定值*/
void Pop(DblStack &s,int n){
    int e,choice;
    for(int i=0;i<n;i++){
        cout<<"出哪个栈(1为1号栈,2为2号栈):";
        cin>>choice;
        if(choice==1){
            if(s.bot[0]==s.top[0]){
                cout<<"栈空无法出栈"<<endl;
                break;
            }else{
                e=s.V[--s.top[0]];
                cout<<"1号栈出栈为:"<<e<<endl;
        }
        }else{
            if(s.bot[1]==s.top[1]){
                cout<<"栈空无法出栈"<<endl;
                break;
            }else{
                e=s.V[++s.top[1]];
                cout<<"2号栈出栈为:"<<e<<endl;
            }
        }
    }
}

3-6 假设以带头结点的循环链表表示队列,并且只设一个指针指向队尾元素结点(注意:不设头指针),试编写相应的置空队列、判断队列是否为空、入队和出队等算法

#include<iostream>
using namespace std;
#define MAXSIZE 100
typedef struct LNode{
    int data;
    struct LNode *next;
}LNode,*LinkList;
typedef struct{
    LinkList rear;
}LinkQueue;
void InitQueue(LinkQueue &q);
void SetNull(LinkQueue &q);
bool CheckNull(LinkQueue q);
void EnQueue(LinkQueue &q,int e);
void DeQueue(LinkQueue &q);

int main(){
    LinkQueue q;
    InitQueue(q);
    EnQueue(q,100);
    DeQueue(q);
    EnQueue(q,200);
    DeQueue(q);
    CheckNull(q);
    SetNull(q);
    CheckNull(q);
    return 0;
}
//初始化循环链式队列
void InitQueue(LinkQueue &q){
    q.rear=new LNode;
    q.rear->next=q.rear;
    cout<<"初始化成功"<<endl;
}
//置空队列
void SetNull(LinkQueue &q){
    LinkList s;
    q.rear=q.rear->next;
    while(q.rear!=q.rear->next){
        s=q.rear->next;
        q.rear->next=s->next;
        delete s;
    }
    cout<<"置空成功"<<endl;
}
//判断空队列:尾指针下一个位置指向尾指针本身
bool CheckNull(LinkQueue q){
    if(q.rear->next==q.rear){
        cout<<"队列为空"<<endl;
        return true;
    }else{
        cout<<"队列不为空"<<endl;
        return false;
    }
}
/*入队:在队尾插入新结点,使新结点的指针指向首节点,尾指针指向新结点*/
void EnQueue(LinkQueue &q,int e){
    LinkList p;
    p->data=e;
    p->next=q.rear->next;
    q.rear->next=p;
    q.rear=p;
    cout<<"入队的值为:"<<e<<endl;
}
/*出队:在队头删除结点,判断是否是空队列,若为空就返回信息;
若不是且只有一个结点,就让尾指针指向头指针位置,头指针位置的指针指向尾指针;
若不止一个结点,就让头指针位置的指针指向要出队结点的下一个指针位置;
最后释放出队结点的空间*/
void DeQueue(LinkQueue &q){
    LinkList p;
    int e;
    if(CheckNull(q)){
        cout<<"队列为空,不能出队"<<endl;
    }else{
        p=q.rear->next->next;
        e=p->data;
        if(p==q.rear){
            q.rear=q.rear->next;
            q.rear->next=p->next;
        }else{
            q.rear->next->next=p->next;
        }
        delete p;
        cout<<"出去的值为:"<<e<<endl;
    }
}

3-7 假设以数组Q[m]存放循环队列中的元素,同时设置一个标志tag,以tag=0和tag=1来区别在队头指针(front)和队尾指针(rear)相等时,队列状态为“空”还是“满”。试编写与此结构相应的插入(enqueue)和删除(dequeue)算法

#include<iostream>
using namespace std;
#define m 10
typedef struct{
    int *base;
    int front;
    int rear;
    int tag;
}SqQueue;
void InitQueue(SqQueue &s);
void EnQueue(SqQueue &s);
void DeQueue(SqQueue &s);
void CheckFullOrNull(SqQueue s);

int main(){
    SqQueue s;
    InitQueue(s);
    EnQueue(s);
    DeQueue(s);
    return 0;
}
//初始化循环队列
void InitQueue(SqQueue &s){
    s.base=new int[m];
    s.front=s.rear=0;
    s.tag=0;
}
//入队:队尾插入且队尾下标+1,tag=1队列不为空
void EnQueue(SqQueue &s){
    int e;
    if(s.tag==1&&s.front==s.rear){
        cout<<"队列满了无法入队"<<endl;
    }else{
        cout<<"输入入队的值:";
        cin>>e;
        s.base[s.rear]=e;
        s.rear=(s.rear+1)%m;
        s.tag=1;
    }
    CheckFullOrNull(s);
}
//出队:队头删除,且队头下标+1,当队尾等于队头下标tag=0队列为空
void DeQueue(SqQueue &s){
    int e;
    if(s.tag==0&&s.front==s.rear){
        cout<<"队列空了无法出队"<<endl;
    }else{
        e=s.base[s.front];
        s.front=(s.front+1)%m;
        cout<<"出队的值为:"<<e<<endl;
        if(s.rear==s.front){
            s.tag=0;
        }
    }
    CheckFullOrNull(s);
}
void CheckFullOrNull(SqQueue s){
    if(s.tag==0){
        cout<<"队列为空"<<endl;
    }else{
        cout<<"队列不空"<<endl;
    }
}

3-8 如果允许在循环队列的两端都可以进行插入和删除操作。要求:(1)写出循环队列类型定义(2)写出“从队尾删除”和“从队头插入”的算法

#include<iostream>
using namespace std;
#define m 10
typedef struct{
    int *base;
    int front;
    int rear;
}SqQueue;
//从队头入队
void EnQueue(SqQueue &s){
    int e;
    if(s.front==(s.rear+1)%m){
        cout<<"队列满了无法入队"<<endl;
    }else{
        cout<<"从队头插入的值:";
        cin>>e;
        s.base[s.front]=e;
        s.front=(s.front-1+m)%m;
    }
}
//从队尾出队
void DeQueue(SqQueue &s){
    int e;
    if(s.front==s.rear){
        cout<<"队列空了无法出队"<<endl;
    }else{
        e=s.base[s.rear];
        s.rear=(s.rear-1+m)%m;
        cout<<"从队尾删除的值为:"<<e<<endl;
    }
}
//初始化循环队列
void InitQueue(SqQueue &s){
    s.base=new int[m];
    s.front=s.rear=0;
}
void InitQueue(SqQueue &s);
void EnQueue(SqQueue &s);
void DeQueue(SqQueue &s);

int main(){
    SqQueue s;
    InitQueue(s);
    EnQueue(s);
    DeQueue(s);
    return 0;
}
  • 3
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值