栈和队列
- 栈
- 栈的基本概念
- 栈的结构
- 初始化栈
- 销毁栈
- 压栈
- 出栈
- 栈中元素的个数
- 查找栈顶的元素
- 压栈和出栈的一个演示
- 全部代码
- Stack.h
- Stack.c
- Test.c
- 队列
- 队列的基本概念
- 节点和队列的定义
- 队列的初始化
- 销毁队列
- 入队
- 出队
- 计算队列中元素的个数
- 判断队列是否为空
- 返回队列中的队头元素
- 返回队列中的队尾元素
- 队列的一个演示过程
- 全部代码
- Queue.h
- Queue.c
- Test.c
栈
栈的基本概念
我们选用数组的形式来构成栈
栈的结构
以一个结构体的形式来表示栈的一些信息
typedef struct Stack
{STDataType* a;int top;//表示栈顶位置,也表示已存储的数据个数int capacity;//
}ST;
初始化栈
初始化结构体的各个成员,对指针所在位置开辟空间
void STInit(ST* ps)
{assert(ps);ps->a=(STDataType*)malloc(sizeof(STDataType)*4);if(ps->a==NULL){perror("malloc fail");return;}ps->top = 0;ps->capacity = 4;
}
销毁栈
对于malloc函数开辟的空间要释放掉,其它置0
void STDestroy(ST* ps)
{assert(ps);free(ps->a);ps->a = NULL;ps->top = 0;ps->capacity = 0;
}
压栈
空间不够,先开辟空间;给数据,然后top++
void STPush(ST* ps,STDataType x)
{assert(ps);if (ps->top==ps->capacity){STDataType* temp=(STDataType*)realloc(ps->a, sizeof(STDataType) * ps->capacity * 2);if (temp==NULL){perror("realloc fail");return;}ps->a = temp;ps->capacity = ps->capacity * 2;}ps->a[ps->top] = x;ps->top++;
}
出栈
只需要动top的值即可,但是要确保栈中存在元素,用一个函数STEmpty来判断
bool STEmpty(ST* ps)
{assert(ps);return ps->top==0;
}
void STPop(ST* ps)
{assert(ps);assert(!STEmpty(ps));ps->top--;
}
栈中元素的个数
直接返回top
int STSize(ST* ps)
{assert(ps);return ps->top;
}
查找栈顶的元素
要先判断栈中是否含有元素,直接返回栈顶的元素(此处的top已经是++之后的,所以需要-1)
STDataType STTop(ST* ps)
{ assert(ps);assert(!STEmpty(ps));return ps->a[ps->top-1];
}
压栈和出栈的一个演示
如下:
int main()
{ST plist;STInit(&plist);STPush(&plist, 1);STPush(&plist, 2);STPush(&plist, 3);STPop(&plist);STPush(&plist, 4);//打印方式,先返回栈顶的元素,再出栈while (!STEmpty(&plist)){printf("%d ", STTop(&plist));STPop(&plist);}STDestroy(&plist);return 0;
}
结果如下:
全部代码
Stack.h
#pragma once
#include <stdio.h>
#include <stdbool.h>
#include <stdlib.h>
#include <assert.h>typedef int STDataType;
typedef struct Stack
{STDataType* a;int top;//表示栈顶位置,也表示已存储的数据个数int capacity;//
}ST;void STInit(ST* ps);
void STDestroy(ST* ps);//压栈
void STPush(ST* ps,STDataType x);
//出栈
void STPop(ST* ps);bool STEmpty(ST* ps);//栈中元素的个数
int STSize(ST* ps);//查找栈顶的元素
STDataType STTop(ST* ps);
Stack.c
#define _CRT_SECURE_NO_WARNINGS 1
#include "Stack.h"void STInit(ST* ps)
{assert(ps);ps->a=(STDataType*)malloc(sizeof(STDataType)*4);if(ps->a==NULL){perror("malloc fail");return;}ps->top = 0;ps->capacity = 4;
}void STDestroy(ST* ps)
{assert(ps);free(ps->a);ps->a = NULL;ps->top = 0;ps->capacity = 0;
}void STPush(ST* ps,STDataType x)
{assert(ps);if (ps->top==ps->capacity){STDataType* temp=(STDataType*)realloc(ps->a, sizeof(STDataType) * ps->capacity * 2);if (temp==NULL){perror("realloc fail");return;}ps->a = temp;ps->capacity = ps->capacity * 2;}ps->a[ps->top] = x;ps->top++;
}bool STEmpty(ST* ps)
{assert(ps);return ps->top==0;
}
void STPop(ST* ps)
{assert(ps);assert(!STEmpty(ps));ps->top--;
}int STSize(ST* ps)
{assert(ps);return ps->top;
}STDataType STTop(ST* ps)
{ assert(ps);assert(!STEmpty(ps));return ps->a[ps->top-1];
}
Test.c
#define _CRT_SECURE_NO_WARNINGS 1#include "Stack.h"int main()
{ST plist;STInit(&plist);STPush(&plist, 1);STPush(&plist, 2);STPush(&plist, 3);STPop(&plist);STPush(&plist, 4);//打印方式,先返回栈顶的元素,再出栈while (!STEmpty(&plist)){printf("%d ", STTop(&plist));STPop(&plist);}STDestroy(&plist);return 0;
}
队列
队列的基本概念
用单链表的方式来实现队列
基本组成元素为链表的单个节点,由于队列的性质,需要知道队头和队尾,同时我们还想知道队列中元素的个数
单个节点属于队列的局部,而队头和队尾属于队列,地位处于节点之上,这种情况下需要用结构体嵌套来表示
节点和队列的定义
//单个节点
typedef struct QueneNode
{struct QueneNode* next;QDataType data;
}QNode;//整个队列
typedef struct Quene
{QNode* head;QNode* tail;int size;
}Quene;
队列的初始化
需要对pq进行断言,因为当pq所指向的空间为空时,其嵌套的结构体QNode将不存在,这不符合队列的要求。只对队列结构体初始化
void QueueInit(Quene* pq)
{assert(pq);pq->head = pq->tail = NULL;pq->size = 0;
}
销毁队列
同销毁链表一致,同时head和tail置空,size置0
void QueueDestroy(Quene* pq)
{assert(pq);QNode* cur = pq->head;while(cur){QNode* next = cur->next;free(cur);cur = next;}pq->head = pq->tail = NULL;pq->size = 0;
}
入队
申请一个新的节点,并对节点初始化,之后尾插
void QueuePush(Quene* pq, QDataType x)
{assert(pq);QNode* newnode = (QNode*)malloc(sizeof(QNode));if (newnode==NULL){perror("malloc fail");return;}newnode->next = NULL;newnode->data = x;//需要判断队列中是否有元素if (pq->head==NULL){pq->head = pq->tail = newnode;}else{pq->tail->next = newnode;pq->tail = newnode;}pq->size++;
}
出队
要保证队列中有元素,之后头删
void QueuePop(Quene* pq)
{assert(pq);//确保有队列assert(pq->head != NULL);//确保队列不为空if (pq->head->next==NULL){free(pq->head);pq->head = pq->tail = NULL;}else{QNode* next = pq->head->next;free(pq->head);pq->head = next;}pq->size--;
}
计算队列中元素的个数
直接返回结构体中的size
int QueueSize(Quene* pq)
{assert(pq);return pq->size;
}
判断队列是否为空
bool QueueEmpty(Quene* pq)
{assert(pq);return pq->size==0;
}
返回队列中的队头元素
要确保队列中有元素
QDataType QueueFront(Quene* pq)
{assert(pq);assert(!QueueEmpty(pq));return pq->head->data;
}
返回队列中的队尾元素
要确保队列中有元素
QDataType QueueBack(Quene* pq)
{assert(pq);assert(!QueueEmpty(pq));return pq->tail->data;
}
队列的一个演示过程
int main()
{Quene q;QueueInit(&q);QueuePush(&q, 1);QueuePush(&q, 2);QueuePop(&q);QueuePush(&q, 3);while (!QueueEmpty(&q)){printf("%d ", QueueFront(&q));QueuePop(&q);}QueueDestroy(&q);return 0;
}
结果如下:
全部代码
Queue.h
#pragma once
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <assert.h>typedef int QDataType;//单个节点
typedef struct QueneNode
{struct QueneNode* next;QDataType data;
}QNode;//整个队列
typedef struct Quene
{QNode* head;QNode* tail;int size;
}Quene;//初始化
void QueueInit(Quene* pq);
//销毁
void QueueDestroy(Quene* pq);//入队
void QueuePush(Quene* pq, QDataType x);
//出队
void QueuePop(Quene* pq);//计算队列中元素的个数
int QueueSize(Quene* pq);
//判断队列是否为空
bool QueueEmpty(Quene* pq);//队列中的队头元素
QDataType QueueFront(Quene* pq);
//队列中的队尾元素
QDataType QueueBack(Quene* pq);
Queue.c
#define _CRT_SECURE_NO_WARNINGS 1
#include "Queue.h"void QueueInit(Quene* pq)
{assert(pq);pq->head = pq->tail = NULL;pq->size = 0;
}void QueueDestroy(Quene* pq)
{assert(pq);QNode* cur = pq->head;while(cur){QNode* next = cur->next;free(cur);cur = next;}pq->head = pq->tail = NULL;pq->size = 0;
}void QueuePush(Quene* pq, QDataType x)
{assert(pq);QNode* newnode = (QNode*)malloc(sizeof(QNode));if (newnode==NULL){perror("malloc fail");return;}newnode->next = NULL;newnode->data = x;//需要判断队列中是否有元素if (pq->head==NULL){pq->head = pq->tail = newnode;}else{pq->tail->next = newnode;pq->tail = newnode;}pq->size++;
}void QueuePop(Quene* pq)
{assert(pq);//确保有队列assert(pq->head != NULL);//确保队列不为空if (pq->head->next==NULL){free(pq->head);pq->head = pq->tail = NULL;}else{QNode* next = pq->head->next;free(pq->head);pq->head = next;}pq->size--;
}int QueueSize(Quene* pq)
{assert(pq);return pq->size;
}bool QueueEmpty(Quene* pq)
{assert(pq);return pq->size==0;
}QDataType QueueFront(Quene* pq)
{assert(pq);assert(!QueueEmpty(pq));return pq->head->data;
}QDataType QueueBack(Quene* pq)
{assert(pq);assert(!QueueEmpty(pq));return pq->tail->data;
}
Test.c
#define _CRT_SECURE_NO_WARNINGS 1#include "Queue.h"int main()
{Quene q;QueueInit(&q);QueuePush(&q, 1);QueuePush(&q, 2);QueuePop(&q);QueuePush(&q, 3);while (!QueueEmpty(&q)){printf("%d ", QueueFront(&q));QueuePop(&q);}QueueDestroy(&q);return 0;
}