栈和队列

栈和队列

一、栈和队列的基本概念

在数组中,我们可以通过索引(下标)访问随机元素。但是,在某些情况下,我们可能需要限制处理顺序,这就产生了栈和队列这两种功能受限的线性结构。

栈和队列是两种不同的处理顺序:先进后出和先进先出,以及两个相应的线性数据结构。

二、数据结构中的栈和队列

1、栈(stack)

数据后进先出,先进后出 LIFO (last in first out)

栈只有一个开口,先进去的就到下面,后进来的就在上面(top),要是拿出去的话,肯定是从开口端拿出去,所以说先进后出,后进先出。

入栈push

出栈pop

获取栈顶元素 top

判断栈是否已经是空

判断栈是否已经满了 is_full(如果是数组实现的)

2、队列(queue)

先进先出,后进后出 FIFO(first in first out)

队列有队首(front) 和队尾(back), 数据从对尾进去队列,从队首出列,队头(front)指向队列的第一个数据,对尾(back)指向队列中最后一个数据。

入队push

出队pop

队头front

队尾back

三、栈和队列的基本结构

四、栈和队列的实现

1、使用链表或顺序表实现栈
1.1 声明
#define STACK_SIZE_MAX 10//栈的最大大小 typedef struct Stack//栈的结构声明{Type data[STACK_SIZE_MAX];//数据域int top;//栈顶元素下标}Stack;//1 栈的初始化函数Stack* stack_init();//2 数据入栈函数void stack_push(Stack* stack,Type val);//3 数据出栈函数Type stack_pop(Stack* stack);//4 获取栈顶元素Type stack_top(Stack* stack);//5 判断栈是否为空bool stack_empty(Stack* stack);//6 判断栈是否满了bool stack_full(Stack* stack);
1.2 功能实现
//1 栈的初始化函数Stack* stack_init(){Stack* temp = (Stack*)malloc(sizeof(Stack));assert(temp);temp->top = -1;//初始化栈顶元素下标为-1,表示栈中没有数据return temp;}//2 数据入栈函数void stack_push(Stack* stack, Type val){assert(stack);//判断栈是否存在assert(!stack_full(stack));//判断栈是否满了stack->data[++stack->top] = val;//栈顶插入元素}//3 数据出栈函数Type stack_pop(Stack* stack){assert(stack);assert(!stack_empty(stack));//判断栈是否为空Type val = stack->data[stack->top];//记录当前栈顶元素stack->top--;//栈顶下标-1return val;}//4 获取栈顶元素Type stack_top(Stack* stack){assert(stack);assert(!stack_empty(stack));//判断栈是否为空return stack->data[stack->top];}//5 判断栈是否为空bool st 山西干部培训学校 www.nwuplganxun.com ack_empty(Stack* stack){return stack->top == -1;//栈空了}//6 判断栈是否满了bool stack_full(Stack* stack){return stack->top >= STACK_SIZE_MAX - 1;//栈满了}
2、使用链表或顺序表实现队列

对于队列来说,入队和出队比较频繁,所以如果用顺序表实现入队虽然简单,但是每次出队都要移动整个顺序表,效率不高,所以使用链表实现。

2.1 队列声明
//队列节点的声明typedef struct Node{Type data;Node* next;}Node;typedef struct Queue{Node* front;//队首Node* back;//队尾}Queue;//队列单例表的初始化Queue* queue_init();//队列单链表节点的初始化Node* node_create(Type val);//1 数据入队void queue_push(Queue* q, Type val);//2 数据出队Type queue_pop(Queue* q);//3 获取队首元素Type queue_front(Queue* q);//4 获取队尾元素Type queue_back(Queue* q);//5 判断队列是否为空bool queue_isNull(Queue* q);
2.2 功能实现
//1 队列单例表的初始化Queue* queue_init(){Queue* queue = (Queue*)malloc(sizeof(Queue));//开辟空间assert(queue);//断言:如果queue为空或者0,则会弹出报错窗口queue->front = queue->back = nullptr;return queue;}//2 队列单链表节点的初始化Node* node_create(Type val){Node* temp = (Node*)malloc(sizeof(Node));assert(temp);temp->data = val;temp->next = nullptr;return temp;}//3 数据入队void queue_push(Queue* q, Type val)//尾插{assert(q);if (q->front == nullptr)//队首为空{q->front = node_create(val);q->back = q->front;}else{q->back->next = node_create(val);q->back = q->back->next;}}//4 数据出队Type queue_pop(Queue* q)//头删{assert(q);//整个链表不存在assert(q->front);//链表为空Node* temp = q->front;Type val = temp->data;q->front = q->front->next;//当前队首的下一个节点成为新的队首free(temp);//之前的队首出队,空间释放temp = NULL;//避免temp是野指针return val;}//5 获取队首元素Type queue_front(Queue* q){assert(q);//整个链表不存在assert(q->front);//链表为空return q->front->data;}//6 获取队尾元素Type queue_back(Queue* q){assert(q);//整个链表不存在assert(q->front);//链表为空return q->back->data;}//7 判断队列是否为空bool queue_isNull(Queue* q){assert(q);//整个链表不存在if (q->front == NULL){return true;}else{return false;}//或者直接  return q->front == NULL;}
3、检查代码的健壮性,是否能够正常使用
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值