【C语言督学训练营 第十三天】栈与循环队列的顺序实现与链式实现

前言

栈与队列是数据结构中最常见的数据结构之一,因其特性往往可以将问题简单化,在使用栈与队列时要牢记:栈:先进后出,队列:先进先出!,写代码时必要时刻可以增加头结点,或者末尾留空,以简化操作。本篇博客主要为了回顾一下,顺序栈,链式栈,顺序循环队列,链式循环队列。以便于后期的复习!在这里插入图片描述

可以先看一下栈与队列通常考什么:
在这里插入图片描述

栈–思想

stack: a pile of objects
翻译:一垛物品
维基百科:堆栈(英语: stack)又称为栈或堆叠
特性:先进后出 (First In Last Out)FILO
考点:主要靠顺序栈,链式栈基本不考!

在这里插入图片描述
在这里插入图片描述

栈–代码实战

顺序栈(***)重点:
顺序栈通常会设置一个栈顶数值指针top用于记录当前栈顶的位置,可以将栈顶初始位置设置到-1,当有元素入栈时使用条件++top,这样top所指的位置就是栈顶元素。出栈时使用条件top–;实现代码如下:

//
// Created by Zhu Shichong on 2023/1/9.
//
#include <stdio.h>
#include<stdlib.h>
#define MaxSize 50
#define bool int
#define true 1
#define false 0
typedef int ElemType;
//数组类型
struct myList{
    
    
    ElemType data[MaxSize];
    int top;
};
typedef struct myList myList;

bool insert_stack(myList *stack,ElemType e){
    
    
    if (stack->top==MaxSize-1){
    
    
        return false;
    }
    stack->data[++stack->top]=e;
    return true;

}
ElemType pop_stack(myList *stack){
    
    
    if(stack->top==-1){
    
    
        return false;
    }
    return stack->data[stack->top--];
}
int main() {
    
    
    myList *stack=(myList*)malloc(sizeof (myList));
    stack->top=-1;
    int a;
    for(int i;i<5;i++){
    
    
        scanf("%d",&a);
        insert_stack(stack,a);
    }
    while(stack->top!=-1){
    
    
        printf("%d ", pop_stack(stack));
    }
    printf("\n");
    return 0;
}

在这里插入图片描述

链表栈(虽不常考,但也实现了一番):

//
// Created by Zhu Shichong on 2023/1/9.
//
#include <stdio.h>
#include<stdlib.h>
#define bool int
#define true 1
#define false 0
typedef int ElemType;
//数组类型
struct myList{
    
    
    ElemType data;
    struct myList *next;
};
typedef struct myList myList;

bool insert_stack(myList *stack,ElemType e){
    
    
    myList *tail=(myList*) malloc(sizeof (myList));
    tail->data=e;
    tail->next=stack->next;
    stack->next=tail;
    return true;

}
ElemType pop_stack(myList *stack){
    
    
    if(stack->next==NULL){
    
    
        return false;
    }
    myList *p;
    ElemType e;
    p=stack->next;
    e=p->data;
    stack->next=stack->next->next;
    free(p);
    return e;
}
int main() {
    
    
    myList *stack=(myList*)malloc(sizeof (myList));
    stack->next=NULL;
    int a;
    for(int i;i<5;i++){
    
    
        scanf("%d",&a);
        insert_stack(stack,a);
    }
    while(stack->next!=NULL){
    
    
        printf("%d ", pop_stack(stack));
    }
    printf("\n");
    return 0;
}

在这里插入图片描述

队列–思想

队列(Queue)简称队,也是一种操作受限的线性表,只允许在表的一端进行插入,而在表的另一端进行删除。向队列中插入元素称为入队或进队;删除元素称为出队或离队。FIFO

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
循环队列是队列的常考点,在解决这种问题之前只需要记住,将带有元素下标指针的判断条件与运算响应部分改为(font+1)%MaxSize,或者(tail+1)%MaxSize即可!

在这里插入图片描述

在这里插入图片描述
在此,我也进行了顺序循环队列的实现:

队列–代码实战

//
// Created by Zhu Shichong on 2023/1/9.
// 循环链表队列
//
#include <stdio.h>
#include<stdlib.h>
#define MaxSize 6
#define bool int
#define true 1
#define false 0
typedef int ElemType;
//数组类型
struct myList{
    
    
    ElemType data[MaxSize];
    int font;
    int tail;
    int maxsize
};
typedef struct myList myList;

//这样写,最后一个位置是留空的
bool push_queue(myList *tail,ElemType e){
    
    
    if((tail->tail+1)%tail->maxsize==tail->font){
    
    
        return false;
    }
    tail->data[tail->tail]=e;
    tail->tail=(tail->tail+1)%tail->maxsize;
    return true;
}
ElemType pop_queue(myList *queue){
    
    
    if(queue->tail==queue->font){
    
    
        return false;
    }
    ElemType e;
    e=queue->data[queue->font];
    queue->font=(queue->font+1)%queue->maxsize;
    return e;
}
int main() {
    
    
    myList *queue=(myList*)malloc(sizeof (myList));
    queue->font=queue->tail=0;
    queue->maxsize=MaxSize;
    ElemType a;
    for(int i=0;i<5;i++){
    
    
        scanf("%d",&a);
        push_queue(queue,a);
    }
    for(int i=0;i<3;i++){
    
    
        printf("%d ", pop_queue(queue));
    }
    printf("\n");
    for(int i=0;i<5;i++){
    
    
        scanf("%d",&a);
        push_queue(queue,a);
    }
    while(queue->font!=queue->tail){
    
    
        printf("%d ", pop_queue(queue));
    }
    printf("\n");
    return 0;
}

在这里插入图片描述

真题实战!

顺序循环队列是常考的内容,但是链式循环队列也会考,就像文章开头那道19年的题,虽然没有让写代码,只让写思路,但是有了思路写代码就会很快,会写代码思路就很清晰,所以下面代码对链式循环队列进行了实现!
在这里插入图片描述
(1)该队列应选择链式存储结构(涉及到空间开辟)。
(2)初始状态,一个头节点指向自己,队空时:head==tail,队满时:tail->next==head
(3)第一个元素入队后 head->tail(存第一个元素数据)->head
(4)基本操作过程如下:

//
// Created by Zhu Shichong on 2023/1/9.
// 循环链表队列
//
#include <stdio.h>
#include<stdlib.h>
#define bool int
#define true 1
#define false 0
typedef int ElemType;
//数组类型
struct myList{
    
    
    ElemType data;
    struct myList *next;
};
typedef struct myList myList;

bool push_queue(myList **queue,myList **tail,ElemType e){
    
    
    if((*tail)->next==*queue){
    
    
        (*tail)->data=e;
        myList *p=(myList*) malloc(sizeof (myList));
        p->next=*queue;
        (*tail)->next=p;
        (*tail)=p;
        printf("malooc!!!\n");
    }else{
    
    
        (*tail)->data=e;
        *tail=(*tail)->next;
    }
    return true;

}
ElemType pop_queue(myList **queue,myList **tail){
    
    
    if(*queue==*tail) {
    
    
        return false;
    }
    ElemType e;
    e=(*queue)->data;
    (*queue)=(*queue)->next;
    return e;
}
int main() {
    
    
    myList *tail,*queue=(myList*)malloc(sizeof (myList));
    queue->next=queue;
    tail=queue;
    int a;
    for(int i=0;i<5;i++){
    
    
        scanf("%d",&a);
        push_queue(&queue,&tail,a);
    }
    for(int i=0;i<3;i++){
    
    
        printf("element out:%d\n", pop_queue(&queue,&tail));
    }
    for(int i=0;i<5;i++){
    
    
        scanf("%d",&a);
        push_queue(&queue,&tail,a);
    }
    printf("\n");
    return 0;
}

在这里插入图片描述


在这里插入图片描述


今天的内容就到此结束了,后续复习数据结构的时候估计会对栈与队列进行详细的总结!

猜你喜欢

转载自blog.csdn.net/apple_51931783/article/details/129121505