数据结构--栈及其及其应用(进制转换和停车场问题)

利用栈,将十进制数字N转换为D进制(D=2,8,16),其中16进制对应的符号是09,AF。

要求:十进制数字和N进制的值从键盘输入获得;从屏幕显示进制转换后的数字。

运行结果参考如下:

顺序栈测试:
(15)10 转换可以得到(F)16
(9)10 转换可以得到(11)8

链栈测试:
(65535)10 转换可以得到(FFFF)16
(38)10 转换可以得到(100110)2

#include<iostream>

#define StackSize 100

typedef struct
{
    int data[StackSize];
    int top = -1;
}SeqStack;

typedef struct Node
{
    int data;
    struct Node *next;
}Node,*LinkList;
/*
    等价于
    struct Node1
    {
        int data;
        struct node *next;
    };
    typedef struct Node1 Node2;

    struct Node1 Node;//定义一个Node1类型的结构体,命名为Node
    简写为
    Node2 Node;//与上一句作用相同。

    同理,在定义链表时
    typedef struct Node1* LinkList;

    把struct Node1* 重命名为LinkList,以后就可以使用LinkList来简化定义Node*类型的变量了(而且还是个指向struct变量的指针)。
    应该把定义中的那个*与前面的结构体连接在一起考虑,而不是与后面的LinkList连接在一起考虑,这就是容易引起疑惑的地方。
 */

//顺序表:
int StackEmpty(SeqStack S) /*判栈S为空栈时返回值为真,反之为假*/
{
    return S.top == -1;
}

int push(SeqStack &S, int x) /*将x置入S栈新栈顶*/
{
    if(S.top == StackSize -1)  /*栈已满*/
        return false;
    else{
        S.top++;
        S.data[S.top]=x;
        return true;
    }
}

int pop(SeqStack &S, int &x)  /*将栈S的栈顶元素弹出,放到x中*/
{
    using namespace std;
    if(S.top==-1)    /*栈为空*/
        return false;
    else{
        x = S.data[S.top];
        S.top--;           /*修改栈顶指针*/
        return true;
    }
}

void Transform(int num1, int num2)
{
    using namespace std;    //在main函数中输入 using namespace std; 意思是表示我们要告诉编译器,我们将在接下来一直使用std命名的空间,这样一来我们就不用一直输入std了;
    SeqStack s;
    while(num1!=0)
    {
        int r = num1 % num2;
        push(s,r);  //入栈
        num1 = num1 / num2;
    }

    cout<<"转化过来的数字是:\n";

    while(!StackEmpty(s))   //不为空
    {
        int e; //e拿出栈顶元素
        pop(s,e);    //出栈
        if (e>9)
        {
            switch (e)
            {
                case 10:
                    cout<<"A";
                    break;
                case 11:
                    cout<<"B";
                    break;
                case 12:
                    cout<<"C";
                    break;
                case 13:
                    cout<<"D";
                    break;
                case 14:
                    cout<<"E";
                    break;
                case 15:
                    cout<<"F";
                    break;
            }
        } else  cout<<e;    // cout<<e<<endl 可以换行
    }
    cout<<"\n";
}

void list()
{
    using namespace std;
    int num1,num2;
    cout<<"请输入要转换的十进制整数\n";
    cin>>num1;
    cout<<"请输入要转换的进制,仅限2-9以及16\n";
    cin>>num2;
    Transform(num1,num2);
}

//链表:
int LinkListEmpty(LinkList top)//判断栈是否为空
{
    return top == nullptr;
}

int LinkListPush(LinkList &top, int x) /*将x置入S栈新栈顶*/        //也可将&top换为*top,则下面的top全部换成(*top),LinkListPush(&top,r)换成LinkListPush(top,r);
{
    LinkList linkList = (LinkList)malloc(sizeof(Node)); //定义一个大小为Node的linkList指针指向结构体Node
    if(linkList == nullptr) return false;   //判断是否申请空间成功
    //C++中NULL定义为0, 在C++中void*不能隐式转换为其他类型,所以使用0(即NULL)代替控制指针。C++11引入nullptr表示空指针,即nullptr就是void*。这样就可以保证在任何情况下,nullptr都可以表示空指针。
    linkList->data = x;
    linkList->next = top;
    top = linkList;
    return true;
    /*
        或者:
        linkList->data=x;
        linkList->next=top->next;
        top->next=linkList; //修改当前栈顶指针
    */
}

int LinkListPop(LinkList *top, int *x)  //Transform2中LinkList传的是地址,所以用指针接收
{
    if(top!=nullptr)
    {
        LinkList p=(*top);
        (*x)=(*top)->data;
        (*top)=(*top)->next;
        free(p);
        return 1;
    }
    return 0;
}

void Transform2(int num1, int num2)
{
    using namespace std;

    LinkList top = nullptr;

    while(num1!=0)
    {
        int r = num1 % num2;
        LinkListPush(top,r);  //入栈
        num1 = num1 / num2;
    }

    cout<<"转化过来的数字是:\n";

    while(!LinkListEmpty(top))   //不为空
    {
        int e; //e拿出栈顶元素
        LinkListPop(&top,&e);   //出栈
        if (e>9)
        {
            switch (e)
            {
                case 10:
                    cout<<"A";
                    break;
                case 11:
                    cout<<"B";
                    break;
                case 12:
                    cout<<"C";
                    break;
                case 13:
                    cout<<"D";
                    break;
                case 14:
                    cout<<"E";
                    break;
                case 15:
                    cout<<"F";
                    break;
            }
        } else  cout<<e;    // cout<<e<<endl 可以换行
    }
    cout<<"\n";
}

void linklist()
{
    using namespace std;
    int num1,num2;
    cout<<"请输入要转换的十进制整数\n";
    cin>>num1;
    cout<<"请输入要转换的进制,仅限2-9以及16\n";
    cin>>num2;
    Transform2(num1,num2);
}


int main()
{
    using namespace std;

    int D = 0;

    bool loop = true;
    while (loop){
        cout<<"请选择你想使用的功能\n";
        cout<<"1. 使用顺序栈转换\n";
        cout<<"2. 使用链栈转换\n";
        cout<<"3. 退出程序\n";

        cin>>D; //读入十进制变量

        switch (D)
        {
            case 1:
                list();
                break;
            case 2:
                linklist();
                break;
            case 3:
                cout<<"程序已退出\n";
                loop = false;
                break;
            default:
                break;
        }
    }

    system("pause");
    return 0;
}

停车场问题:在这里插入图片描述

#include <iostream>

typedef struct
{
    char CarStatus;
    int CarNum;
    int time;
}Car;

typedef struct
{
    int p[100];     //用于存放车牌号
    int t[100];     //用于存放进入停车场的时间
    int StackSize;  //停车场最大容量
    int Cost;   //收费标准
    int top;
}SeqStack;

typedef struct Node
{
    Car car;
    struct Node *next;
}Node,*LinkList;

void InitStack(SeqStack &stack)
{
    stack.top = -1;
}

//便道
int Road(LinkList *temp, Car car, int &num)
{
    auto linkList = (LinkList)malloc(sizeof(Node));
    if(linkList==nullptr)   return false;
    linkList->car = car;
    linkList->next=(*temp);
    (*temp)=linkList;
    num++;
    return true;
}

//离开便道
int leaveR(LinkList *top, Car *car)
{
    if(top!=nullptr)
    {
        LinkList p=(*top);
        (*car)=(*top)->car;
        (*top)=(*top)->next;
        free(p);
        return true;
    }
    return false;
}

int RoadEmpty(LinkList top){
    return top == nullptr;
}

//停车场
void ParkingLotA(SeqStack &stack, Car car)
{
    stack.top++;
    stack.p[stack.top] = car.CarNum;
    stack.t[stack.top] = car.time;
    printf("车牌号为%d的车在停车场的位置是%d",car.CarNum,stack.top+1);
}

void ParkingLotD(SeqStack &stack, Car car)
{
    for (int i = 0; i < stack.StackSize; i++) {
        if (stack.p[i] == car.CarNum)
        {
            int time = car.time - stack.t[i];
            if (i != 0){
                for (int j = i; j < stack.StackSize - 1; j++) {
                    stack.p[j] = stack.p[j+1];
                    stack.t[j] = stack.t[j+1];
                }
            }
            stack.top--;
            int cost = stack.Cost * time;
            printf("车牌号为%d的车停留时长为%d, 所需缴纳的停车费为:%d\n",car.CarNum,time,cost);
        }
    }
}


int main() {
    using namespace std;

    SeqStack stack;
    LinkList top = nullptr;

    cout << "请输入停车场的最大容量(/辆)以及车在停车场每小时的费用(/元)" << endl;
    cin >> stack.StackSize >> stack.Cost;

    InitStack(stack);

    bool loop = true;
    char CarStatus;
    int num;
    int time;
    int RNum = 0;

    cout << "请输入车的状态(A进站,D出站),车牌号和时间(进站时间/出站时间)" << endl;
    cout << "输入E退出程序" << endl;

    while (loop) {
        cin >> CarStatus >> num >> time;

        Car car = {CarStatus, num, time};

        if (CarStatus == 'E')
            loop = false;
        else if (CarStatus == 'A') {

            if (stack.top < stack.StackSize - 1) //停车场内没停满
            {
                ParkingLotA(stack, car);
            } else {
                cout<<"停车场内没有停车位了,这辆车停到便道上"<<endl;
                Road(&top, car, RNum); //停车场停满了,停到便道上
                cout<<"车在便道的位置是"<<RNum<<endl;
            }

        } else if (CarStatus == 'D') {
            ParkingLotD(stack, car);
            if (!RoadEmpty(top))
            {
                Car car1;
                leaveR(&top,&car1);
                car1.time = car.time; //进入的时间就是前一辆车离开停车场的时间
                ParkingLotA(stack, car1);
            } else cout<<"此时便道上没有车"<<endl;

        }

    }

    printf("程序已退出\n");

    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值