一、栈
定义
栈(stack)又名堆栈,它是一种运算受限的线性表。限定仅在表尾进行插入和删除操作的线性表。这一端被称为栈顶,相对地,把另一端称为栈底。向一个栈插入新元素又称作进栈、入栈或压栈,它是把新元素放到栈顶元素的上面,使之成为新的栈顶元素;从一个栈删除元素又称作出栈或退栈,它是把栈顶元素删除掉,使其相邻的元素成为新的栈顶元素。
功能实现
<0>头文件
#ifndef STACK_H
#define STACK_H
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <stdbool.h>
#endif
typedef int STDataType;
typedef struct StackNode
{
STDataType *a;
int capacity;
int top;//top有两种定义方式,为栈顶元素的下标或站定元素下个位置的下标
} ST;
void STInit(ST *ps);//初始化栈
void STDestroy(ST *ps);//销毁瞻
void STPush(ST *ps,STDataType x);//数据进栈
void STPop(ST *ps);//数据出栈
STDataType STTop(ST *ps);//返回栈顶数据
bool STEmpty(ST *ps);//判断栈是否为空
int STSize(ST *ps);//返回栈的大小
<1>初始化栈
void STInit(ST *ps)//初始化栈
{
assert(ps);//一般在函数外定义结构体,在函数内初始化,这样比较简单,指针记得要判空
//ps->a=NULL;
ps->a=(STDataType*)malloc(sizeof(STDataType)*4);
if(!ps->a)
{
perror("malloc fail");
exit(-1);
}
ps->capacity=4;
ps->top=0;//这种定义方式下top为栈顶数据的下一个位置的下标
return;
}
<2>销毁栈
void STDestroy(ST *ps)//销毁栈
{
assert(ps);
free(ps->a);
ps->a=NULL;
ps->capacity=ps->top=0;
return;
}
<3>数据进栈
void STPush(ST *ps,STDataType x)//数据进栈
{
assert(ps);
if(ps->top==ps->capacity) //自动扩容
{
STDataType *tmp=(STDataType*)realloc(ps->a,sizeof(STDataType)*2*ps->capacity);
if(!tmp)
{
perror("realloc fail");
exit(-1);
}
ps->a=tmp;
ps->capacity*=2;
}
ps->a[ps->top++]=x;
return;
}
<4>数据出栈
void STPop(ST *ps)//数据出栈
{
assert(ps);
assert(!STEmpty(ps));
ps->top--;
return;
}
<5>返回栈顶数据
STDataType STTop(ST *ps)//返回栈顶数据
{
assert(ps);
assert(!STEmpty(ps));
return ps->a[ps->top-1];
}
<6>判断栈是否为空
bool STEmpty(ST *ps)//判断栈是否为空
{
assert(ps);
return ps->top==0;
}
<7>返回栈的大小
int STSize(ST *ps)//返回栈的大小
{
assert(ps);
return ps->top;
}
实例
main函数:
#include "stack.h"
int main()
{
ST st;
STInit(&st);
STPush(&st,1);
STPush(&st,2);
STPush(&st,3);
printf("%d\n",STTop(&st));
printf("size:%d\n",STSize(&st));
STPop(&st);
STPop(&st);
STPop(&st);
if(STEmpty(&st))
printf("empty\n");
STDestroy(&st);
return 0;
}
输出结果:
二、队列
定义
队列是一种特殊的
线性表
,特殊之处在于它只允许在表的前端(front)进行删除操作,而在表的后端(rear)进行插入操作,和栈一样,队列是一种操作受限制的线性表。进行插入操作的端称为队尾,进行删除操作的端称为队头。
功能实现
<0>头文件
#ifndef QUEQUE_H
#define QUEQUE_H
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <stdbool.h>
#endif
typedef int QDataType;
typedef struct QuequeNode
{
QDataType data;
struct QuequeNode *next;
} QNode;
typedef struct Queque
{
QNode *head;//head指向链表的头节点,也是队列的队头
QNode *tail;//tail指向链表的尾节点,也是队列的队尾
//要注意,队列前进的方向和链表的方向是相反的
int size;
} Queque;
void QInit(Queque *pq);//初始化队列
void QDestroy(Queque *pq);//销毁队列
void QPush(Queque *pq,QDataType x);//数据进队列
void QPop(Queque *pq);//数据出队列
QDataType QFront(Queque* pq);//返回队头数据
QDataType QBack(Queque *pq);//返回队尾数据
bool QEmpty(Queque *pq);//判断队列是否为空
int QSize(Queque *pq);//计算队列大小
<1>初始化队列
void QInit(Queque *pq)//初始化队列
{
assert(pq);
pq->head=pq->tail=NULL;
pq->size=0;
return;
}
<2>销毁队列
void QDestroy(Queque *pq)//销毁队列
{
assert(pq);
QNode *cur=pq->head;
while(cur)
{
QNode *del=cur;
cur=cur->next;
free(del);
}
pq->head=pq->tail=NULL;
pq->size=0;
return;
}
<3>数据进队列
void QPush(Queque *pq,QDataType x)//数据进队列
{
assert(pq);
QNode *newnode=(QNode*)malloc(sizeof(QNode));
if(newnode==NULL)
{
perror("malloc fail");
exit(-1);
}
newnode->data=x;
newnode->next=NULL;
if(!pq->head)
{
pq->head=pq->tail=newnode;
}else
{
pq->tail->next=newnode;
pq->tail=newnode;
}
pq->size++;
return;
}
<4>数据出队列
void QPop(Queque *pq)//数据出队列
{
assert(pq);
assert(!QEmpty(pq));
if(!pq->head->next)
{
free(pq->head);
pq->head=pq->tail=NULL;
}else
{
QNode *del=pq->head;
pq->head=pq->head->next;
free(del);
}
pq->size--;
return;
}
<5>返回队头数据
QDataType QFront(Queque* pq)//返回队头数据
{
assert(pq);
assert(!QEmpty(pq));
return pq->head->data;
}
<6>返回队尾数据
QDataType QBack(Queque *pq)//返回队尾数据
{
assert(pq);
assert(!QEmpty(pq));
return pq->tail->data;
}
<7>判断队列是否为空
bool QEmpty(Queque *pq)//判断队列是否为空
{
assert(pq);
return pq->head==NULL&&pq->tail==NULL;
}
<8>返回队列大小
int QSize(Queque *pq)//计算队列大小
{
assert(pq);
return pq->size;
}
3.实例
main函数:
#include "queque.h"
int main()
{
Queque q;
QInit(&q);
QPush(&q,1);
QPush(&q,2);
QPush(&q,3);
printf("head:%dtail:%d\n",QFront(&q),QBack(&q));
printf("size:%d\n",QSize(&q));
QPop(&q);
QPop(&q);
QPop(&q);
if(QEmpty(&q))
printf("empty\n");
QDestroy(&q);
return 0;
}
输出结果: