栈和队列(C语言版)

间隔了好久,开始继续复习。
栈和队列是在程序中最常被用到的数据结构,其重要性不言而喻。

栈:

定义:限定仅在表尾进行插入和删除操作的线性表,因此表尾称之为栈顶,表头为栈底,重要特点是后进先出(LIFO)

这里写图片描述

操作:

  • InitStack(&S) 初始化一个栈
  • DestoryStack(&S)销毁一个已经存在的栈
  • ClearStack(&S)清空一个栈
  • StackEmpty(S)判断已存在的栈是否为空
  • StackLength(S)求栈长度
  • GetTop(S,&e)获取栈顶部元素
  • Push(&S,e)将一个元素e压入栈(核心)
  • Pop(&S,&e) 将栈顶元素出栈,并用e返回其值(核心)

实现(C语言):
和线性表的实现类似,栈也有两种实现方式,分别为顺序栈链栈

顺序栈的实现:

/*栈和队列的实现(C语言版)-------顺序栈*/

#include<stdio.h>
#include<malloc.h>
#include"string.h"

#define STACK_INIT_SIZE 100//栈的基础容量
#define STACK_INCREMENT 100//栈增长量

#define overflow_error 0
#define OK 1
#define operate_error 2
#define stack_null_error 3

typedef struct{
    int *top;
    int *base;
    int stackSize;
}SqStack;

/*
    初始化顺序栈
*/
int InitStack(SqStack *S){

    (*S).base = (int *)malloc(STACK_INIT_SIZE * sizeof(int));

    if( (!(*S).base) ){
        exit(overflow_error);
    }
    (*S).top = (*S).base;
    (*S).stackSize = STACK_INIT_SIZE;
    return OK;
}

/*
    入栈操作,elem为要入栈的元素
*/

int PushStack(SqStack *S,int elem){
    //如果内存不够用,则重新申请空间
    if((*S).top-(*S).base>(*S).stackSize){

        (*S).base = (int *)realloc((*S).base,((*S).stackSize+STACK_INCREMENT)*sizeof(int));
        //未申请上空间
        if(!(*S).base){
            exit(overflow_error);
        }
        (*S).top = (*S).base+(*S).stackSize;
        (*S).stackSize += STACK_INCREMENT;

    }

    *((*S).top)++ = elem;
    return OK;

}

/*出栈操作,将栈顶元素出栈,并用elem将该元素返回*/
int PopStack(SqStack *S,int *elem){
    //判断是否栈空
    if((*S).top == (*S).base){
        return stack_null_error;
    }
    *elem = *--((*S).top);//将元素弹出栈,并将指针下移
    return OK;
}



/*获取栈顶元素,但是并不是将元素出栈,并用elem返回元素值*/
int GetTop(SqStack S,int *elem){
    if(S.top == S.base){
        return stack_null_error;
    }
    *elem = *(S.top-1);
    return OK;
}


/*判断是否栈空*/
int StackEmpty(SqStack s){
    int flag = 0;
    if(s.base == s.top){
        flag = 0;
    }else{
        flag = 1;
    }

return flag;
}

/*根据操作返回的结果进行成功与否的显示*/
void Utils_Print_Msg(int flag){
    if(flag == OK){
        printf("成功\n");
    }else{
        printf("不成功\n");
    }
}




/*主函数*/
int main(){
    SqStack stack;
    //栈初始化
    int flag = InitStack(&stack);
    Utils_Print_Msg(flag);

    //入栈
    flag = operate_error;
    flag = PushStack(&stack,60);
    flag = PushStack(&stack,50);
    flag = PushStack(&stack,40);
    flag = PushStack(&stack,30);
    flag = PushStack(&stack,20);
    Utils_Print_Msg(flag);

    int getElem = 0;
    GetTop(stack,&getElem);
    printf("获取到的栈顶元素是%d\n",getElem);

    //出栈
    int elem = 0;
    flag = operate_error;
    flag = PopStack(&stack,&elem);
    if(flag == OK){
        printf("%d出栈成功\n",elem);
    }else{
        printf("%d出栈失败\n",elem);
    }

    //获取栈顶元素
    GetTop(stack,&getElem);
    printf("获取到的栈顶元素是%d\n",getElem);

return 0;
}

应用:
栈的应用十分广泛,所以也产生了许多使用栈的经典应用算法,几个简单的用用的简单实现。
数制转换:

/*
    进制转换---除K取余法
    int Num_10 十进制下的数
    int Num_convered 要转换的的进制
*/
int Conversion(int Num_10,int Num_convered){
    SqStack s;
    InitStack(&s);
    printf("数制转换前%d\n",Num_10);
    while(Num_10){
        PushStack( &s,(Num_10%Num_convered) );
        Num_10 = Num_10/Num_convered;
    }
    printf("转换数制后");
    while(StackEmpty(s)){
        int e;
        PopStack(&s,&e);
        printf("%d",e);
    }
    printf("\n");

}

--------------------------------------
//在主函数中添加代码测试一下:
    int num_10,num_convered;
    printf("输入十进制数");
    scanf("%d",&num_10);

    printf("输入要转换的进制");
    scanf("%d",&num_convered);
    Conversion(num_10,num_convered);

队列:
定义:
队列是一种先进先出的数据结构,只允许在表的一端进行插入,在表的另一端进行删除元素。允许插入的一端叫队尾,允许删除的一端叫队头
这里写图片描述

操作:

  • InitQueue(&Q)初始化队列
  • DestoryQueue(&Q)销毁队列
  • ClearQueue(&Q)清空队列
  • QueueEmpty(Q)队列为空
  • GetHead(Q,&e)获得队首元素,并用e返回其值,但是并不出队
  • EnterQueue(&Q,e)将元素e入队
  • DeleteQueue(&Q,&e)将元素出队,并用e返回其值

实现(C语言版):
和之前的数据结构类似,队列也有两种实现方式,为顺序队列链队列

单链队列的实现(C语言版):

/*栈和队列的实现(C语言版)-------单链队列*/

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

#define overflow_error 0
#define OK 1
#define operate_error 2
#define queue_null_error 3

/*队列的数据节点*/
typedef struct QNode{
    int data;
    struct QNode *next;
}QNode,*QueuePtr;

/*对头队尾指针*/
typedef struct {
    QueuePtr front;
    QueuePtr rear;
}LinkQueue;

/*初始化一个单链表队列*/
int InitQueue(LinkQueue *Q){
    (*Q).front = (*Q).rear = (QueuePtr)malloc(sizeof(QNode));

    if(!(*Q).front){
        exit(overflow_error);
    }
    (*Q).front->next = NULL;
    return OK;
}

/*将元素elem入队*/
int EnterQueue(LinkQueue *Q,int elem){
    QueuePtr newNode = (QueuePtr)malloc(sizeof(QNode));
    if(!newNode){
        exit(overflow_error);
    }
    newNode->data = elem;
    newNode->next = NULL;
    (*Q).rear->next = newNode;
    (*Q).rear = newNode;

    return OK;

}

/*将队尾的元素出队,并用elem将其值返回*/
int DeleteQueue(LinkQueue *Q,int *elem){
    if((*Q).front == (*Q).rear){
        return queue_null_error;
    }

    QueuePtr deleteNode = (*Q).front->next;
    *elem = deleteNode->data;
    (*Q).front->next = deleteNode->next;

    if((*Q).rear == deleteNode){
        (*Q).rear = (*Q).front;
    }
    free(deleteNode);

    return OK;

}

/*根据操作返回的结果进行成功与否的显示*/
void Utils_Print_Msg(int flag){
    if(flag == OK){
        printf("成功\n");
    }else{
        printf("不成功\n");
    }
}




/*主函数*/
int main(){
    LinkQueue queue;
    //初始化队列
    int flag = operate_error;
    flag = InitQueue(&queue);
    Utils_Print_Msg(flag);
    //将元素elem插入队尾
    flag = operate_error;
    flag = EnterQueue(&queue,78);
    flag = EnterQueue(&queue,567);
    flag = EnterQueue(&queue,21);
    flag = EnterQueue(&queue,26);
    flag = EnterQueue(&queue,54);
    flag = EnterQueue(&queue,34);
    flag = EnterQueue(&queue,8);
    flag = EnterQueue(&queue,37);
    Utils_Print_Msg(flag);
    //将队头元素出队,并用elem将其值返回
     flag = operate_error;
     int deleteNum;
    flag = DeleteQueue(&queue,&deleteNum);
    if(flag){
        printf("%d\n",deleteNum);
    }else{
        printf("失败");
    }

    flag = DeleteQueue(&queue,&deleteNum);
    if(flag){
        printf("%d\n",deleteNum);
    }else{
        printf("失败");
    }


    flag = DeleteQueue(&queue,&deleteNum);
    if(flag){
        printf("%d\n",deleteNum);
    }else{
        printf("失败");
    }


    flag = DeleteQueue(&queue,&deleteNum);
    if(flag){
        printf("%d\n",deleteNum);
    }else{
        printf("失败");
    }

    flag = DeleteQueue(&queue,&deleteNum);
    if(flag){
        printf("%d\n",deleteNum);
    }else{
        printf("失败");
    }


return 0;
}



  • 6
    点赞
  • 34
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值