目录
1、栈
1.1栈的概念
栈:是一种特殊的线性表,只允许在固定的一端进行插入或者删除。进行数据的插入和删除的一端为栈顶,另一端为栈低。栈中的元素遵守后进先出的原则。
压栈:栈的插入操作叫做进栈/压栈/入栈,入数据在栈顶。
出栈:栈的删除操作叫做出栈,出数据也在栈顶。
1.2栈的实现
栈的实现一般使用数组或者链表,相对而言数组的结构实现更优一些,数组尾插时代价较小。
Stack.h文件:
#include<stdio.h>
#include<assert.h>
#include<stdlib.h>
#include<stdbool.h>
typedef int STDataType;
typedef struct Stack
{
STDataType* _arr;
int _top;
int _capacity;
}Stack;
//初始化
void StackInit(Stack*ps);
//销毁
void StackDestroy(Stack*ps);
//入栈
void StackPush(Stack* ps, STDataType x);
//出栈
void StackPop(Stack* ps);
//取栈顶元素
STDataType StackTop(Stack* ps);
//取栈的有效个数
int StackSize(Stack* ps);
//检查栈是不是为空
bool StackEmpty(Stack* ps);
Stack.c文件:
#include"Stack.h"
void StackInit(Stack* ps)
{
ps->_arr = NULL;
ps->_top = ps->_capacity = 0;//_top指向栈顶元素的下一个
}
void StackDestroy(Stack* ps)
{
assert(ps);
free(ps->_arr);
ps->_arr = NULL;
ps->_capacity = ps->_top = 0;
}
void StackCheckCapacity(Stack*ps)
{
assert(ps);
if (ps->_capacity == ps->_top)
{
int newcapacity = ps->_capacity == 0 ? 4 : 2 * ps->_capacity;
STDataType* arr = (STDataType*)malloc(sizeof(STDataType)*newcapacity);
if (arr == NULL)
{
perror("malloc fail");
exit(1);
}
ps->_arr = arr;
ps->_capacity = newcapacity;
}
}
void StackPush(Stack* ps, STDataType x)
{
assert(ps);
StackCheckCapacity(ps);
ps->_arr[ps->_top++] = x;
}
void StackPop(Stack* ps)
{
assert(ps);
assert(ps->_top>0);
ps->_top--;
}
STDataType StackTop(Stack* ps)
{
assert(ps);
assert(ps->_top > 0);
return ps->_arr[ps->_top - 1];
}
int StackSize(Stack* ps)
{
assert(ps);
return ps->_top;
}
bool StackEmpty(Stack* ps)
{
assert(ps);
return ps->_top == 0;
}
test.c文件:
#include"Stack.h"
void test()
{
Stack s;
StackInit(&s);
StackPush(&s, 1);
StackPush(&s, 2);
StackPush(&s, 3);
StackPush(&s, 4);
printf("%d\n", StackTop(&s));
StackPop(&s);
printf("%d\n", StackTop(&s));
printf("%d\n", StackSize(&s));
StackDestroy(&s);
}
int main()
{
test();
return 0;
}
2、队列
2.1队列的概念
队列:只允许在一端插入数据,在另一端删除数据,队列具有先进先出的原则
入队列:进行插入操作的一端称为队尾
出队列:进行删除操作的一端称为队头
2.2队列的实现
队列也可以数组和链表的结构实现,使用链表的结构实现更优一些,因为如果使用数组的结构,出队列在数 组头上出数据,效率会比较低。
Queue.h:
#include<stdio.h>
#include<assert.h>
#include<stdlib.h>
#include<stdbool.h>
typedef int QLDataType;
typedef struct QListNode
{
QLDataType val;
struct QListNode* next;
}QL;
typedef struct QueueNode
{
QL* head;
QL* rear;
int size;
}Queue;
//初始化
void QueueInit(Queue* pq);
//销毁
void QueueDestroy(Queue* pq);
//队尾插入
void QueuePush(Queue*pq,QLDataType x);
//队头删除
void QueuePop(Queue*pq);
//取队头数据
QLDataType QueueFront(Queue* pq);
//取队尾数据
QLDataType QueueBack(Queue* pq);
//队列节点个数
int QueueSize(Queue* pq);
//判空
bool QueueEmpty(Queue* pq);
QL* QLCreate(QLDataType x);
Queue.c:
#include"Queue.h"
//初始化
void QueueInit(Queue* pq)
{
assert(pq);
pq->head = NULL;
pq->rear = NULL;
pq->size = 0;
}
//销毁
void QueueDestroy(Queue* pq)
{
assert(pq);
QL* pcur = pq->head;
while (pcur)
{
QL* next = pcur->next;
free(pcur);
pcur = next;
}
pq->head=pq->rear=NULL;
pq->size = 0;
}
//队尾插入
QL* QLCreate(QLDataType x)
{
QL* tmp = (QL*)malloc(sizeof(QL));
if (tmp == NULL)
{
perror("malloc fail");
return;
}
tmp->val = x;
tmp->next = NULL;
return tmp;
}
void QueuePush(Queue* pq, QLDataType x)
{
if (pq->rear==NULL)
{
pq->head = pq->rear = QLCreate(x);
}
else
{
pq->rear->next = QLCreate(x);
pq->rear = QLCreate(x);
}
pq->size++;
}
//队头删除
void QueuePop(Queue* pq)
{
assert(pq && pq->size > 0);
if (pq->head->next == NULL)
{
free(pq->head);
pq->head = pq->rear == NULL;
}
else
{
QL* next = pq->head->next;
free(pq->head);
pq->head = next;
}
pq->size--;
}
//取队头数据
QLDataType QueueFront(Queue* pq)
{
assert(pq && pq->size > 0);
return pq->head->val;
}
//取队尾数据
QLDataType QueueBack(Queue* pq)
{
assert(pq && pq->size > 0);
return pq->rear->val;
}
//队列节点个数
int QueueSize(Queue* pq)
{
assert(pq);
return pq->size;
}
//判空
bool QueueEmpty(Queue* pq)
{
assert(pq);
return pq->size == 0;
}
test.c:
#include"Queue.h"
void test()
{
Queue q;
QueueInit(&q);
QueuePush(&q, 1);
QueuePush(&q, 2);
printf("%d\n", QueueFront(&q));
QueuePop(&q);
QueuePush(&q, 3);
QueuePush(&q, 4);
printf("%d\n", QueueFront(&q));
printf("%d\n", QueueSize(&q));
}
int main()
{
test();
return 0;
}
3、栈和队列的OJ题
有效括号:
typedef char STDataType;
typedef struct Stack
{
STDataType*a;
int top;
int capacity;
}ST;
void StackInit(ST*ps);
void StackDestroy(ST*ps);
void StackPush(ST*ps,STDataType x);
void StackPop(ST*ps);
STDataType StackTop(ST*ps);
bool StackEmpty(ST*ps);
void StackInit(ST*ps)
{
assert(ps);
ps->a=NULL;
ps->top=0;
ps->capacity=0;
}
void StackDestroy(ST*ps)
{
assert(ps);
free(ps->a);
ps->a=NULL;
ps->top=0;
ps->capacity=0;
}
void StackPush(ST*ps,STDataType x)
{
assert(ps);
if(ps->top==ps->capacity)
{
int newcapacity=ps->capacity==0?4:ps->capacity*2;
STDataType*tmp=realloc(ps->a,sizeof(STDataType)*newcapacity);
if(tmp==NULL)
{
perror("realloc fail");
return;
}
ps->a=tmp;
ps->capacity=newcapacity;
}
ps->a[ps->top++]=x;
}
void StackPop(ST*ps)
{
assert(ps&&ps->top>0);
ps->top--;
}
STDataType StackTop(ST*ps)
{
assert(ps&&ps->top>0);
return ps->a[ps->top-1];
}
bool StackEmpty(ST*ps)
{
assert(ps);
return ps->top==0;
}
bool isValid(char* s){
ST st;
StackInit(&st);
while(*s)
{
if(*s=='['||*s=='{'||*s=='(')
{
StackPush(&st,*s);
}
else
{
if(StackEmpty(&st))
{
StackDestroy(&st);
return false;
}
STDataType top=StackTop(&st);
StackPop(&st);
if((*s=='}'&&top!='{')
||(*s==']'&&top!='[')
||(*s==')'&&top!='('))
{
StackDestroy(&st);
return false;
}
}
s++;
}
bool ret=StackEmpty(&st);
StackDestroy(&st);
return ret;
}
两个队列实现栈:
typedef int QDataType;
typedef struct QueueNode
{
struct QueueNode* next;
QDataType val;
}QNode;
typedef struct Queue
{
QNode* phead;
QNode* ptail;
int size;
}Queue;
void QueueInit(Queue* pq);
void QueuePush(Queue*pq, QDataType x);
void QueuePop(Queue*pq);
QDataType QueueFront(Queue* pq);
QDataType QueueBack(Queue* pq);
int QueueSize(Queue* pq);
bool QueueEmpty(Queue* pq);
void QueueDestroy(Queue* pq);
void QueueInit(Queue* pq)
{
assert(pq);
pq->phead = NULL;
pq->ptail = NULL;
pq->size = 0;
}
void QueuePush(Queue* pq, QDataType x)
{
assert(pq);
QNode* newnode = (QNode*)malloc(sizeof(QNode));
if (newnode==NULL)
{
perror("malloc fail");
return;
}
newnode->next = NULL;
newnode->val=x;
if (pq->ptail == NULL)
{
pq->phead = pq->ptail = newnode;
}
else
{
pq->ptail->next = newnode;
pq->ptail = newnode;
}
pq->size++;
}
void QueuePop(Queue* pq)
{
assert(pq && QueueSize(pq) != 0);
if (pq->phead->next == NULL)
{
free(pq->phead);
pq->phead = pq->ptail = NULL;
}
else
{
Queue* next = pq->phead->next;
free(pq->phead);
pq->phead = next;
}
pq->size--;
}
QDataType QueueFront(Queue* pq)
{
assert(pq);
assert(pq->phead);
return pq->phead->val;
}
QDataType QueueBack(Queue* pq)
{
assert(pq);
assert(pq->ptail);
return pq->ptail->val;
}
int QueueSize(Queue* pq)
{
assert(pq);
return pq->size;
}
bool QueueEmpty(Queue* pq)
{
assert(pq);
return pq->size == 0;
}
void QueueDestroy(Queue* pq)
{
assert(pq);
QNode* cur = pq->phead;
while (cur)
{
QNode* next = cur->next;
free(cur);
cur = next;
}
pq->phead = pq->ptail = NULL;
pq->size = 0;
}
typedef struct {
Queue q1;
Queue q2;
} MyStack;
MyStack* myStackCreate() {
MyStack*obj=(MyStack*)malloc(sizeof(MyStack));
if(obj==NULL)
{
perror("malloc fail");
exit(1);
}
QueueInit(&obj->q1);
QueueInit(&obj->q2);
return obj;
}
void myStackPush(MyStack* obj, int x) {
if(!QueueEmpty(&obj->q1))
{
QueuePush(&obj->q1,x);
}
else
{
QueuePush(&obj->q2,x);
}
}
int myStackPop(MyStack* obj) {
Queue*empty=&obj->q1;
Queue*nonempty=&obj->q2;
if(!QueueEmpty(&obj->q1))
{
empty=&obj->q2;
nonempty=&obj->q1;
}
while(QueueSize(nonempty)>1)
{
QueuePush(empty,QueueFront(nonempty));
QueuePop(nonempty);
}
int top=QueueFront(nonempty);
QueuePop(nonempty);
return top;
}
int myStackTop(MyStack* obj) {
if(!QueueEmpty(&obj->q1))
{
return QueueBack(&obj->q1);
}
else
{
return QueueBack(&obj->q2);
}
}
bool myStackEmpty(MyStack* obj) {
return QueueEmpty(&obj->q1)&&QueueEmpty(&obj->q2);
}
void myStackFree(MyStack* obj) {
QueueDestroy(&obj->q1);
QueueDestroy(&obj->q2);
free(obj);
}
两个栈实现队列:
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);
STDataType STTop(ST* ps);
int STSize(ST* ps);
bool STEmpty(ST* ps);
void STInit(ST* ps)
{
assert(ps);
ps->a = NULL;
ps->top = 0;
ps->capacity = 0;
}
void STDestroy(ST* ps)
{
assert(ps);
free(ps->a);
ps->a = NULL;
ps->top = ps->capacity = 0;
}
void STPush(ST* ps, STDataType x)
{
assert(ps);
if (ps->top == ps->capacity)
{
int newcapacity = ps->capacity == 0 ? 4 : ps->capacity * 2;
STDataType* tmp = (STDataType*)realloc(ps->a, newcapacity * sizeof(STDataType));
if (tmp == NULL)
{
perror("realloc fail");
return;
}
ps->a = tmp;
ps->capacity = newcapacity;
}
ps->a[ps->top] = x;
ps->top++;
}
void STPop(ST* ps)
{
assert(ps);
assert(!STEmpty(ps));
ps->top--;
}
STDataType STTop(ST* ps)
{
assert(ps);
assert(!STEmpty(ps));
return ps->a[ps->top - 1];
}
int STSize(ST* ps)
{
assert(ps);
return ps->top;
}
bool STEmpty(ST* ps)
{
assert(ps);
return ps->top == 0;
}
typedef struct {
ST pushst;
ST popst;
} MyQueue;
MyQueue* myQueueCreate() {
MyQueue* obj = (MyQueue*)malloc(sizeof(MyQueue));
STInit(&obj->pushst);
STInit(&obj->popst);
return obj;
}
void myQueuePush(MyQueue* obj, int x) {
STPush(&obj->pushst, x);
}
int myQueuePop(MyQueue* obj) {
int front = myQueuePeek(obj);
STPop(&obj->popst);
return front;
}
int myQueuePeek(MyQueue* obj) {
if(STEmpty(&obj->popst))
{
while(!STEmpty(&obj->pushst))
{
int top = STTop(&obj->pushst);
STPop(&obj->pushst);
STPush(&obj->popst, top);
}
}
return STTop(&obj->popst);
}
bool myQueueEmpty(MyQueue* obj) {
return STEmpty(&obj->pushst) && STEmpty(&obj->popst);
}
void myQueueFree(MyQueue* obj) {
STDestroy(&obj->pushst);
STDestroy(&obj->popst);
free(obj);
}
设计循环队列:
typedef struct {
int*a;
int head;
int tail;
int k;
} MyCircularQueue;
MyCircularQueue* myCircularQueueCreate(int k) {
MyCircularQueue*obj=(MyCircularQueue*)malloc(sizeof(MyCircularQueue));
obj->a=(int*)malloc(sizeof(int)*(k+1));
obj->head=0;
obj->tail=0;
obj->k=k;
return obj;
}
bool myCircularQueueEnQueue(MyCircularQueue* obj, int value) {
if((obj->tail+1)%(obj->k+1)==obj->head)
{
return false;
}
obj->a[obj->tail++]=value;
obj->tail%=(obj->k+1);
return true;
}
bool myCircularQueueDeQueue(MyCircularQueue* obj) {
if(obj->head==obj->tail)
return false;
obj->head++;
if(obj->head==obj->k+1)
obj->head=0;
return true;
}
int myCircularQueueFront(MyCircularQueue* obj) {
if(obj->head==obj->tail)
return -1;
else
return obj->a[obj->head];
}
int myCircularQueueRear(MyCircularQueue* obj) {
if(obj->head==obj->tail)
return -1;
else
return obj->tail==0?obj->a[obj->k]:obj->a[obj->tail-1];
//return obj->a[(obj->tail+obj->k)%(obj->k+1)];
}
bool myCircularQueueIsEmpty(MyCircularQueue* obj) {
return obj->head==obj->tail;
}
bool myCircularQueueIsFull(MyCircularQueue* obj) {
return (obj->tail+1)%(obj->k+1)==obj->head;
}
void myCircularQueueFree(MyCircularQueue* obj) {
free(obj->a);
obj->a=NULL;
obj->head=obj->tail=0;
obj->k=0;
free(obj);
}
完!
谢谢大家观看