在数据结构中,有两个知识体系特别重要,分别是栈和队列。两个定义方法很类似,区别在于栈是先入后出,队列是先入先出。
栈:一种先入后出的操作,主要以顺序栈为基础,栈其实类似与小时候的玩具枪的弹夹,最先按进去的子弹,最后才会发射。
栈的顺序实现:
#pragma once
#include <stdlib.h>
#include <assert.h>
#include <string.h>
#include <stdio.h>
#define MAX_SIZE 100
typedef int SDataType;
typedef struct Stack {
SDataType array[MAX_SIZE];
int top;
} Stack;
// 初始化
void StackInit(Stack *pStack){
assert(pStack != NULL);
pStack->top = 0;
}
// 压栈
void StackPush(Stack *pStack, SDataType data){
assert(pStack != NULL);
assert(pStack->top < MAX_SIZE);
pStack->array[pStack->top++] = data;
}
// 出栈
void StackPop(Stack *pStack){
assert(pStack != NULL);
assert(pStack->top>0);
pStack->top--;
}
// 返回栈顶元素
SDataType StackTop(Stack *pStack){
assert(pStack != NULL);
assert(pStack->top>0);
return pStack->array[pStack->top-1];
}
// 判断是否为空
// 1 空
// 0 不空
int StackIsEmpty(Stack *pStack){
assert(pStack != NULL);
if (pStack->top > 0){
return 0;
}
else return 1;
}
// 返回数据个数
int StackSize(Stack *pStack)
{
assert(pStack != NULL);
assert(pStack->top>0);
return pStack->top;
}
void TestStack(){
Stack stack;
StackInit(&stack);
StackPush(&stack, 1);
StackPush(&stack, 2);
StackPush(&stack, 3);
StackPush(&stack, 4);
int ret;
ret = StackSize(&stack);
printf("栈:");
for (int i = ret-1; i >=0; i--){
printf("%d", stack.array[i]);
}
printf("\n");
}
这是栈的顺序存储,常用的比较多。
队列:队列是一种先入先出的结构,和我们日常生活中的排队特别相似,排在队头的人,第一个享受服务。
队列中链式队列使用的较多,这次主要以链式队列为主。
链式队列代码:
#pragma once
#include <stdio.h>
#include <assert.h>
#include <stdlib.h>
typedef int QDataType;
typedef struct QNode {
QDataType data;
struct QNode *pNext;
} QNode;
typedef struct Queue {
QNode *pFront;
QNode *pRear;
int size;
} Queue;
// 初始化
void QueueInit(Queue *pQueue)
{
assert(pQueue!=NULL);
pQueue->pFront = pQueue->pRear = NULL;
pQueue->size = 0;
}
// 入队列
void QueuePush(Queue *pQueue, QDataType data){
assert(pQueue!= NULL);
QNode *pNewNode = (QNode*)malloc(sizeof(QNode));
pNewNode->data = data;
pNewNode->pNext = NULL;
pQueue->size++;
//队尾指针为空,空队列。
if (pQueue->pRear ==NULL){
pQueue->pFront = pQueue->pRear = pNewNode;
return;
}
pQueue->pRear->pNext = pNewNode;//此时队尾元素的下一个指向新元素
pQueue->pRear = pNewNode;//将队尾重置
}
// 出队列
void QueuePop(Queue *pQueue){
assert(pQueue != NULL);
pQueue->size--;
QNode *OldFront = pQueue->pFront;
pQueue->pFront = pQueue->pFront->pNext;
free(OldFront);
if (pQueue->pFront = NULL){
pQueue->pRear = NULL;
}
}
// 返回队首元素
QDataType QueueFront(Queue *pQueue){
assert(pQueue != NULL);
return pQueue->pFront->data;
}
// 判断是否为空
// 1 空
// 0 不空
int QueueIsEmpty(Queue *pQueue){
assert(pQueue != NULL);
return pQueue->size > 0 ? 1 : 0;
}
// 返回数据个数
int QueueSize(Queue *pQueue){
assert(pQueue != NULL);
return pQueue->size;
}
void TestQueue(){
Queue pQueue;
QueueInit(&pQueue);
QueuePush(&pQueue, 2);
QueuePush(&pQueue, 4);
QueuePush(&pQueue, 5);
QueuePush(&pQueue, 6);
printf("队列:");
while (pQueue.pFront!=NULL){
printf("%d", pQueue.pFront->data);
pQueue.pFront = pQueue.pFront->pNext;
}
printf("\n");
}
至此,栈与队列的代码就显示完毕,大多数的操作已经在代码中体现出来,博主就不赘言太多,因为代码就是博主最想表露的心声。