#include<stdio.h>
#include<malloc.h>
#include<windows.h>
#include<stdbool.h>

#define SIZE 5                                     //定义默认数组长度
#define len sizeof(struct stacknode)             //结构体stacknode的长度,即要申请空间的长度

int sourceData[SIZE] = { 11,22,33,44,55 };         //内部数据数组,节省每次建立时输入时间
enum returninfo { success, fail, underflow, range_error };  //定义返回信息清单
int stackLength;                                 //链栈中数据个数
bool flag = false;
typedef struct stacknode {                         //用结构体定义链表的节点
    int data;
    struct stacknode* next;
}NODE,*PNODE;

typedef struct pointer {
    struct stacknode* linkStackTop;
    struct stacknode* newnodep;
    struct satcknode* usedNodep;
};

struct pointer* sp;
//函数声明
bool isempty();                                    //判断栈是否为空
enum returninfo display();                        //显示栈中所有元素
int getLength();                                //获取栈的长度
void processmenu();                                //判断选择
enum returninfo pop(int* item);                    //出栈,把数据返回
void showmenu();                                //显示菜单
enum returninfo initStack();                    //初始化链栈
enum returninfo create();                        //根据内部默认数组创建一个栈
enum returninfo destroy();                        //销毁一个栈
enum returninfo push(int item);                 //将数据进栈
enum returninfo poponly();                        //出栈,不返回数值,并且释放房前元素的空间
enum returninfo gettop(int* item);                //得到栈顶元素
void clearscreen();                                //清屏

/*------------------------------------
函数名:clearscreen()
描  述:清屏
入口参数:无
出口参数:无
--------------------------------------*/
void clearscreen() {
    system("cls");
}

/*------------------------------------
函数名:showmenu()
描  述:显示菜单
入口参数:无
出口参数:无
--------------------------------------*/
void showmenu() {
    puts("=============================================    ");
    puts("栈的简单操作 ");
    puts("=============================================    ");
    puts("                   功能菜单                    ");
    puts("=============================================    ");
    puts("1.初始化一个栈                                    ");
    puts("2.按照内部数组创建默认链栈                        ");
    puts("3.销毁一个栈                                    ");
    puts("4.出栈并且返回原栈顶的值                        ");
    puts("5.取出当前栈顶元素                                ");
    puts("6.遍历栈中所有数据                                ");
    puts("7.数据进栈                                        ");
    puts("8.获取栈的长度                                    ");
    puts("0.结束程序                                        ");
    puts("=============================================    ");
    printf("请输入您的选择:");
}

/*------------------------------------
函数名:initStack()
描  述:初始化一个栈
入口参数:无
出口参数:enum returninfo类型判断是否成功
--------------------------------------*/
enum returninfo initStack() {
    sp = (struct pointer*)malloc(sizeof(struct pointer));
    sp->linkStackTop = (PNODE)malloc(len);
    if (sp->linkStackTop == NULL) {
        return fail;
    }
    sp->linkStackTop->next = NULL;
    stackLength = 0;
    return success;
}

/*------------------------------------
函数名:create()
描  述:创建一个链栈
入口参数:无
出口参数:enum returninfo类型判断是否成功
--------------------------------------*/
enum returninfo create() {
    int i;
    for (i = 0; i < SIZE; i++) {
        sp->newnodep = (PNODE)malloc(len);
        if (sp->newnodep == NULL) {
            return fail;
        }
        sp->newnodep->data = sourceData[i];
        sp->newnodep->next = sp->linkStackTop->next;
        sp->linkStackTop->next = sp->newnodep;
        stackLength++;
    }
    return success;
}

/*------------------------------------
函数名:destroy()
描  述:销毁一个链栈
入口参数:无
出口参数:enum returninfo类型判断是否成功
--------------------------------------*/
enum returninfo destroy() {
    if (poponly() == underflow) {
        return underflow;
    }
    while (poponly() == success);
    return success;
}

/*------------------------------------
函数名:poponly()
描  述:出栈但不返回数据
入口参数:无
出口参数:enum returninfo类型判断是否成功
--------------------------------------*/
enum returninfo poponly(){
    if (isempty() == false) {
        sp->usedNodep = sp->linkStackTop->next;
        sp->linkStackTop->next = sp->linkStackTop->next->next;
        free(sp->usedNodep);
        stackLength--;
        return success;
    }
    return underflow;
}

/*------------------------------------
函数名:isempty()
描  述:判断栈是否为空
入口参数:无
出口参数:返回栈是否为空的信息
--------------------------------------*/
bool isempty() {
    if (stackLength == 0) {
        return true;
    }
    else {
        return false;
    }
}

/*------------------------------------
函数名:pop()
描  述:出栈返回数据
入口参数:通过引用的到栈顶的值
出口参数:enum returninfo类型判断是否成功
--------------------------------------*/
enum returninfo pop(int* item) {
    if (isempty()) {
        return underflow;
    }
    *item = sp->linkStackTop->next->data;
    sp->usedNodep = sp->linkStackTop->next;
    sp->linkStackTop->next = sp->linkStackTop->next->next;
    free(sp->usedNodep);
    stackLength--;
    return success;
    
}

/*------------------------------------
函数名:gettop()
描  述:返回数据
入口参数:通过引用的到栈顶的值
出口参数:enum returninfo类型判断是否成功
--------------------------------------*/
enum returninfo gettop(int* item) {
    if (isempty()) {
        return underflow;
    }
    *item = sp->linkStackTop->next->data;
    return success;
}

/*------------------------------------
函数名:getdisplay()
描  述:遍历栈中元素
入口参数:通过引用的到栈的所有数据
出口参数:enum returninfo类型判断是否成功
--------------------------------------*/
enum returninfo display() {
    PNODE searchp = sp->linkStackTop->next;
    if (isempty()) {
        return underflow;
    }
    printf("目前栈中的内容是:栈顶-->");
    while (searchp) {
        printf("%d ",searchp->data);
        searchp = searchp->next;
    }
    printf("栈底\n");
    return success;
}

/*------------------------------------
函数名:push()
描  述:数据进栈
入口参数:要进栈的元素数值
出口参数:enum returninfo类型判断是否成功
--------------------------------------*/
enum returninfo push(int item) {
    sp->newnodep = (PNODE)malloc(len);
    if (sp->newnodep == NULL) {
        return fail;
    }
    sp->newnodep->data = item;
    sp->newnodep->next = sp->linkStackTop->next;
    sp->linkStackTop->next = sp->newnodep;
    stackLength++;
    return success;

}

/*------------------------------------
函数名:getLength()
描  述:得到栈的长度
入口参数:无
出口参数:int型表示栈的长度
--------------------------------------*/
int getLength() {
    return stackLength;
}

/*------------------------------------
函数名:processmenu()
描  述:判断选择,完成功能
入口参数:struct pointer* 类型
出口参数:无
--------------------------------------*/
void processmenu() {
    int menuchoice;
    int num1;
    int returnvalue;
    scanf("%d", &menuchoice);
    switch (menuchoice) {
    case 1:
        returnvalue = initStack();
        if (returnvalue == fail) {
            printf("链栈初始化失败!\n");
        }
        else {
            printf("链栈初始化成功!\n");
        }
        break;
    case 2:
        returnvalue = create();
        if (returnvalue == fail) {
            printf("内存分配失败,创建失败!\n");
        }
        else {
            printf("链栈创建成功!\n");
        }
        break;
    case 3:
        returnvalue = destroy();
        if (returnvalue == underflow) {
            printf("栈为空!\n");
        }
        else {
            printf("栈销毁成功!\n");
        }
        break;
    case 4:
        returnvalue = pop(&num1);
        if (returnvalue == underflow) {
            printf("链栈为空!\n");
        }
        else {
            printf("出栈成功,栈顶值为%d\n",num1);
        }
        break;
    case 5:
        returnvalue = gettop(&num1);
        if (returnvalue == underflow) {
            printf("栈链为空!\n");
        }
        else {
            printf("取出栈顶元素为%d\n",num1);
        }
        break;
    case 6:
        returnvalue = display();
        if (returnvalue == underflow) {
            printf("链表为空!\n");
        }
        break;
    case 7:
        printf("请输入您要入栈的元素值: ");
        scanf("%d",&num1);
        returnvalue = push(num1);
        if (returnvalue == fail) {
            printf("分配内存失败!\n");
        }
        else {
            printf("数据入栈成功!");
        }
        break;
    case 8:
        num1 = getLength();
        printf("栈的长度为%d\n",num1);
        break;
    case 0:
        exit(0);
    default :
        puts("对不起,您输入的功能编号有错!请重新输入!!!");
        break;
    }
}


//主函数
int main()
{
    SetConsoleTitle("栈元素的简单操作");
    system("color f0");                  //设置背景为白色,字体为黑色
    clearscreen();
    
    while (true) {
        showmenu();                        //显示菜单
        processmenu();                    //处理菜单窗口,出口就在其中
        system("pause");                //暂停一下,等用户给一个回车
        clearscreen();
    }
    return 0;
}

 

扫码关注我们
微信号:SRE实战
拒绝背锅 运筹帷幄

SRE实战 互联网时代守护先锋,助力企业售后服务体系运筹帷幄!一键直达领取阿里云限量特价优惠。