一、栈
1.1 栈的概念及结构
栈:一种特殊的线性表,其只允许在固定的一端进行插入和删除元素操作。 进行数据插入和删除操作的一端 称为栈顶,另一端称为栈底。 栈中的数据元素遵守后进先出 LIFO ( Last In First Out )的原则。
压栈 :栈的插入操作叫做进栈 / 压栈 / 入栈, 入数据在栈顶。
出栈 :栈的删除操作叫做出栈。 出数据也在栈顶。
1.2 栈的实现(数组栈)
栈的实现一般可以使用 数组或者链表实现 ,相对而言数组的结构实现更优一些。因为数组在尾上插入数据的代价比较小。
1.2.1 栈的基本功能实现
#include<stdio.h> #include<stdbool.h> #include<assert.h> typedef int SDateType; typedef struct Stack { SDateType* a; int top; int capacity; }Stack; //初始化栈和销毁栈 void InitStack(Stack* ps); void DestoryStack(Stack* ps); //出栈和入栈 void StackPush(Stack* ps, SDateType x); void StackPop(Stack* ps); //栈的有效个数和栈顶元素 int StackSize(Stack* ps); int StackTop(Stack* ps); //栈是否为空 bool StackEmpty(Stack* ps);
1.2.1.1 栈的初始化和销毁
//初始化栈和销毁栈 void InitStack(Stack* ps) { assert(ps); ps->a = NULL; ps->capacity = ps->top = 0; } void DestoryStack(Stack* ps) { assert(ps); free(ps->a); ps->a = NULL; ps->capacity = ps->top = 0; }
1.2.1.2 入栈和出栈
//出栈和入栈 void StackPush(Stack* ps, SDateType x) { assert(ps); //扩容 if (ps->top == ps->capacity) { int newcapacity = ps->capacity == 0 ? 4 : ps->capacity * 2; SDateType* tmp = (SDateType*)realloc(ps->a,newcapacity*sizeof(SDateType)); if (tmp == NULL) { perror("realloc fail:"); return; } ps->a = tmp; ps->capacity = newcapacity; } //尾插 ps->a[ps->top] = x; ps->top++; } void StackPop(Stack* ps) { assert(ps); assert(ps->top > 0);//只少有一个元素,才能删除 ps->top--; }
1.2.1.3 栈的元素个数和栈顶元素
//栈的有效个数和栈顶元素 int StackSize(Stack* ps) { assert(ps); return ps->top; } int StackTop(Stack* ps) { assert(ps); assert(ps->top > 0); return ps->a[ps->top - 1]; }
1.2.1.4 栈是否为空
//栈是否为空 bool StackEmpty(Stack* ps) { assert(ps); return ps->top == 0; }
1.2.2 Stack.h
#include<stdio.h> #include<stdbool.h> #include<assert.h> typedef int SDateType; typedef struct Stack { SDateType* a; int top; int capacity; }Stack; //初始化栈和销毁栈 void InitStack(Stack* ps); void DestoryStack(Stack* ps); //出栈和入栈 void StackPush(Stack* ps, SDateType x); void StackPop(Stack* ps); //栈的有效个数和栈顶元素 int StackSize(Stack* ps); int StackTop(Stack* ps); //栈是否为空 bool StackEmpty(Stack* ps);
1.2.3 Stach.c
#include"Stack.h" //初始化栈和销毁栈 void InitStack(Stack* ps) { assert(ps); ps->a = NULL; ps->capacity = ps->top = 0; } void DestoryStack(Stack* ps) { assert(ps); free(ps->a); ps->a = NULL; ps->capacity = ps->top = 0; } //出栈和入栈 void StackPush(Stack* ps, SDateType x) { assert(ps); //扩容 if (ps->top == ps->capacity) { SDateType newcapacity = ps->capacity == 0 ? 4 : ps->capacity * 2; SDateType* tmp = (SDateType*)realloc(ps->a,newcapacity*sizeof(SDateType)); if (tmp == NULL) { perror("realloc fail:"); return; } ps->a = tmp; ps->capacity = newcapacity; } //尾插 ps->a[ps->top] = x; ps->top++; } void StackPop(Stack* ps) { assert(ps); assert(ps->top > 0);//只少有一个元素,才能删除 ps->top--; } //栈的有效个数和栈顶元素 int StackSize(Stack* ps) { assert(ps); return ps->top; } int StackTop(Stack* ps) { assert(ps); assert(ps->top > 0); return ps->a[ps->top - 1]; } //栈是否为空 bool StackEmpty(Stack* ps) { assert(ps); return ps->top == 0; }
二、队列
2.1 队列的概念及结构
队列:只允许在一端进行插入数据操作,在另一端进行删除数据操作的特殊线性表,队列具有先进先出 FIFO(First In First Out)的原则。
入队列:进行插入操作的一端称为队尾
出队列:进行删除操作的一端称为队头
2.2 队列的实现(单链表队列)
队列也可以数组和链表的结构实现,使用链表的结构实现更优一些,因为如果使用数组的结构,出队列在数 组头上出数据,效率会比较低。
2.2.1 队列的基本功能实现
#include<stdio.h> #include<stdbool.h> #include<stdlib.h> #include<assert.h> typedef int QDateType; typedef struct QueueNode { QDateType val; struct QueueNode * next; }QueueNode; typedef struct Queue { QueueNode *head; QueueNode *tail; QDateType size; }Queue; // 初始化队列 void QueueInit(Queue* pq); void QueueDestroy(Queue* pq); // 队尾入列和出列 void QueuePush(Queue* pq, QDateType x); void QueuePop(Queue* pq); // 返回队头和队尾 QDateType QueueFront(Queue* pq); QDateType QueueBack(Queue* pq); // 获取队列中有效元素个数 int QueueSize(Queue* pq); // 检测队列是否为空 bool QueueEmpty(Queue* pq);
2.2.1.1 队列的初始化和销毁
// 初始化队列 void QueueInit(Queue* pq) { assert(pq); pq->head = pq->tail = NULL; pq->size = 0; } //队列的销毁 bool QueueEmpty(Queue* pq) { assert(pq); return pq->head==NULL; }
2.2.1.2 入列和出列
//入列 void QueuePush(Queue* pq, QDateType x) { assert(pq); QueueNode* node = (QueueNode*)malloc(sizeof(QueueNode)); node->val = x; node->next = NULL; if (pq->tail == NULL) { pq->head = pq->tail = node; pq->size++; } else { pq->tail->next = node; pq->tail = node; pq->size++; } } //出列 void QueuePop(Queue* pq) { assert(pq); assert(pq->head != NULL);//只少保证一个节点 QueueNode* del = pq->head; pq->head = pq->head->next; free(del); del = NULL; pq->size--; if (pq->head == NULL)//只有一个节点处理 { pq->tail = NULL; } }
2.2.1.3 返回队头和队尾元素
// 返回队头和队尾 QDateType QueueFront(Queue* pq) { assert(pq); return pq->head->val; } QDateType QueueBack(Queue* pq) { assert(pq); return pq->tail->val; }
2.2.1.4 队列元素个数
// 获取队列中有效元素个数 int QueueSize(Queue* pq) { assert(pq); return pq->size; }
2.2.1.5 队列是否为空
bool QueueEmpty(Queue* pq) { assert(pq); return pq->head==NULL; }
2.2.2 Queue.h
#include<stdio.h> #include<stdbool.h> #include<stdlib.h> #include<assert.h> typedef int QDateType; typedef struct QueueNode { QDateType val; struct QueueNode * next; }QueueNode; typedef struct Queue { QueueNode *head; QueueNode *tail; QDateType size; }Queue; // 初始化队列 void QueueInit(Queue* pq); void QueueDestroy(Queue* pq); // 队尾入列和出列 void QueuePush(Queue* pq, QDateType x); void QueuePop(Queue* pq); // 返回队头和队尾 QDateType QueueFront(Queue* pq); QDateType QueueBack(Queue* pq); // 获取队列中有效元素个数 int QueueSize(Queue* pq); // 检测队列是否为空 bool QueueEmpty(Queue* pq);
2.2.1 Queue.c
#include"Queue.h" // 初始化队列 void QueueInit(Queue* pq) { assert(pq); pq->head = pq->tail = NULL; pq->size = 0; } void QueuePush(Queue* pq, QDateType x) { assert(pq); QueueNode* node = (QueueNode*)malloc(sizeof(QueueNode)); node->val = x; node->next = NULL; if (pq->tail == NULL) { pq->head = pq->tail = node; pq->size++; } else { pq->tail->next = node; pq->tail = node; pq->size++; } } void QueuePop(Queue* pq) { assert(pq); assert(pq->head != NULL);//只少保证一个节点 QueueNode* del = pq->head; pq->head = pq->head->next; free(del); del = NULL; pq->size--; if (pq->head == NULL)//只有一个节点处理 { pq->tail = NULL; } } // 返回队头和队尾 QDateType QueueFront(Queue* pq) { assert(pq); return pq->head->val; } QDateType QueueBack(Queue* pq) { assert(pq); return pq->tail->val; } // 获取队列中有效元素个数 int QueueSize(Queue* pq) { assert(pq); return pq->size; } bool QueueEmpty(Queue* pq) { assert(pq); return pq->head==NULL; } void QueueDestroy(Queue* pq) { assert(pq); QueueNode* cur = pq->head; while (cur) { QueueNode* next = cur->next; free(cur); cur = next; } pq->head = pq->tail = NULL; pq->size = 0; }