一、栈
1.栈的概念及结构
栈:一种特殊的线性表,只允许在一端进行插入和删除,进行插入数据和删除数据的是栈顶,另一端叫栈底。遵循:后进先出。。。
压栈:栈的插入叫压栈、进栈、入栈。在栈顶进行操作。
出栈:栈的数据删除。在栈顶进行操作。
2.栈的实现
一般可以用数组或者链表进行栈的实现,但数组相对而言更优,因为插入数据时,数组在尾上进行的操作代价更小。
Stack.h
#include<stdio.h>
#include<stdlib.h>
#include<assert.h>
#include<stdbool.h>
typedef int 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);//检测栈是否为空,
int StackSize(ST* ps);//获取栈的有效个数
几乎都是顺序表的操作。。。直接展示全部代码。
Stack.c
#include"Stack.h"
void StackInit(ST* ps)
{
assert(ps);
ps->a = NULL;
ps->top = ps->capacity = 0;
}
void StackDestroy(ST* ps)
{
assert(ps);
free(ps->a);
ps->a = NULL;
ps->capacity = ps->top = 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 = (STDataType*)realloc(ps->a, newCapacity * sizeof(STDataType));
if (tmp == NULL)
{
perror("realloc fail");
exit(-1);
}
ps->a = tmp;
ps->capacity = newCapacity;
}
ps->a[ps->top] = x;
ps->top++;
}
void StackPop(ST* ps)
{
assert(ps);
assert(!StackEmpty(ps));
--ps->top;
}
STDataType StackTop(ST* ps)
{
assert(ps);
assert(!StackEmpty(ps));
return ps->a[ps->top - 1];
}
bool StackEmpty(ST* ps)
{
assert(ps);
return ps->top = 0;
}
int StackSize(ST* ps)
{
assert(ps);
return ps->top;
}
二、队列
1.队列的概念及结构
队列:只允许在一端进行插入数据,另一端进行删除数据,是一个特殊的线性表。具有先进先出的特质,进行插入的一端叫队尾,进行删除的一端叫队头,
2.队列的实现
Queue.h 函数声明:
#include<stdio.h>
#include<stdlib.h>
#include<assert.h>
#include<stdbool.h>
typedef int QDataType;
typedef struct QueueNode
{
struct QueueNode* next;
QDataType data;
}QNode;
typedef struct Queue
{
QNode* head;
QNode* tail;
int size;
}Queue;
void QueueInit(Queue* pq);
void QueueDestory(Queue* pq);
void QueuePush(Queue* pq, QDataType x);
void QueuePop(Queue* pq);
QDataType QueueFront(Queue* pq);
QDataType QueueBack(Queue* pq);
bool QueueEmty(Queue* pq);
int QueuSize(Queue* pq);
Queue.c 函数的具体实现:
#include"Queue.h"
void QueueInit(Queue* pq)//创建队列
{
assert(pq);
pq->head = pq->tail = NULL;
pq->size = 0;
}
void QueueDestory(Queue* pq)//销毁队列
{
assert(pq);
QNode* cur = pq->head;
while (cur)
{
QNode* del = cur;
cur = cur->next;
free(del);
}
pq->head = pq->tail = NULL;
}
void QueuePush(Queue* pq, QDataType x)//尾插
{
assert(pq);
QNode* newnode = (QNode*)malloc(sizeof(QNode));
if (newnode == NULL)
{
printf("malloc fail");
exit(-1);
}
else
{
pq->tail->next - newnode;
pq->tail = newnode;
}
pq->size++;
}
void QueuePop(Queue* pq)//删除队头
{
assert(pq);
assert(!QueueEmty(pq));
if (pq->head->next == NULL)
{
free(pq->head);
pq->head = pq->tail = NULL;
}
else
{
QNode* del = pq->head;
pq->head = pq->head->next;
free(del);
del = NULL;
}
pq->size--;
}
QDataType QueueFront(Queue* pq)//读取队头数据
{
assert(pq);
assert(!QueueEmty(pq));
return pq->head->data;
}
QDataType QueueBack(Queue* pq)//读取队尾数据
{
assert(pq);
assert(!QueueEmty(pq));
return pq->tail->data;
}
bool QueueEmty(Queue* pq)
{
assert(pq);
return pq->head ==NULL && pq->tail == NULL;
}
int QueuSize(Queue* pq)
{
assert(pq);
/*QNode* cur = pq->head;
int n = 0;
while (cur)
{
++n;
cur = cur->next;
}*/
return pq->size;
}
大家可以自己试试用队列实现栈,栈实现队列,虽然没有实际意义,但可以加强对栈和队列的理解。
接下来展示队列实现栈,栈实现队列。
三、队列实现栈
重复此操作就可以了。
代码实现:
#include<stdio.h>
#include<stdlib.h>
#include<assert.h>
#include<stdbool.h>
//用队列实现栈
typedef int QDataType;
typedef struct QueueNode
{
struct QueueNode* next;
QDataType data;
}QNode;
typedef struct Queue
{
QNode* phead;
QNode* ptail;
int size;
}Queue;
//#include"Queue.h"
void QueueInit(Queue* pq)
{
assert(pq);
pq-> phead = NULL;
pq-> ptail = NULL;
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;
}
void QueuePush(Queue* pq, QDataType x)
{
assert(pq);
QNode* newnode = (QNode*)malloc(sizeof(QNode));
if (newnode == NULL)
{
printf("malloc fail");
exit(-1);
}
newnode->data = x;
newnode->next = NULL;
if (pq->ptail == NULL)
{
assert(pq->phead == NULL);
pq->phead = pq->ptail = newnode;
}
else
{
pq->ptail->next = newnode;
pq->ptail = newnode;
}
pq->size++;
}
void QueuePop(Queue* pq)
{
assert(pq);
//assert(!QueueEmpty(pq));
//队列中有一个节点或多个节点
if (pq->phead->next == NULL)
{
free(pq->phead);
pq->phead = pq->ptail = NULL;
}
else
{
//头删
QNode* next = pq->phead->next;
free(pq->phead);
pq->phead = next;
}
pq->size--;
}
QDataType QueueFront(Queue* pq)
{
assert(pq);
//assert(!QueueEmpty(pq));
return pq->phead->data;
}
QDataType QueueBack(Queue* pq)
{
assert(pq);
//assert(!QueueEmpty(pq));
return pq->ptail->data;
}
int QueueSize(Queue* pq)
{
assert(pq);
return pq->size;
}
bool QueueEmpty(Queue* pq)
{
assert(pq);
return pq->size == 0;
}
typedef struct Qstack
{
Queue push;
Queue pop;
}Qstack;
void QsInit(Qstack* ps)
{
assert(ps);
QueueInit(&(ps->push));
QueueInit(&(ps->pop));
}
void QsPush(Qstack* ps, QDataType x)
{
assert(ps);
QueuePush(&(ps->push), x);
}
void QsPop(Qstack* ps)
{
while (QueueSize(&(ps->push)) > 1)
{
QueuePush(&(ps->pop), QueueFront(&(ps->push)));
QueuePop(&(ps->push));
}
while (!QueueEmpty(&(ps->pop)))
{
QueuePush(&(ps->push), QueueFront(&(ps->pop)));
QueuePop(&(ps->pop));
}
}
QDataType QsTop(Qstack* ps)
{
assert(ps);
return ps->push.ptail->data;
}
bool QsEmpty(Qstack* ps)
{
if (ps->push.size == 0)
return true;
return false;
}
int main()
{
Qstack s;
QsInit(&s);
QsPush(&s, 1);
QsPush(&s, 2);
QsPush(&s, 3);
QsPush(&s, 4);
QsPush(&s, 5);
QsPush(&s, 6);
while (!QsEmpty(&s))
{
printf("%d ", QsTop(&s));
QsPop(&s);
}
return 0;
}
四、栈实现队列
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <stdbool.h>
// 支持动态增长的栈
typedef int STDataType;
typedef struct Stack
{
STDataType* _a;
int _top; // 栈顶
int _capacity; // 容量
}Stack;
void StackInit(Stack* ps)
{
assert(ps);
ps->_a = NULL;
ps->_top = 0;
ps->_capacity = 0;
}
void StackPush(Stack* ps, STDataType data)
{
assert(ps);
if (ps->_capacity == ps->_top)
{
STDataType* tmp = NULL;
int newcapacity = ps->_capacity == 0 ? 4 : ps->_capacity * 2;
tmp = (STDataType*)realloc(ps->_a, sizeof(STDataType) * newcapacity);
if (tmp == NULL)
{
perror("realloc fail");
return;
}
ps->_capacity = newcapacity;
ps->_a = tmp;
}
ps->_a[ps->_top] = data;
ps->_top++;
}
bool STEmpty(Stack* ps)
{
assert(ps);
return ps->_top == 0;
}
void StackPop(Stack* ps)
{
assert(ps);
assert(!STEmpty(ps));
ps->_top--;
}
STDataType StackTop(Stack* ps)
{
assert(ps);
assert(!STEmpty(ps));
return ps->_a[ps->_top - 1];
}
int StackSize(Stack* ps)
{
assert(ps);
return ps->_top;
}
int StackEmpty(Stack* ps)
{
assert(ps);
if (0 == ps->_top)
return 1;
else
return 0;
}
void StackDestroy(Stack* ps)
{
assert(ps);
ps->_capacity = 0;
ps->_top = 0;
free(ps->_a);
ps->_a = NULL;
}
typedef struct Myqueue
{
Stack Push;
Stack Pop;
}Myqueue;
void MqInit(Myqueue* pq)
{
assert(pq);
StackInit(&(pq->Push));
StackInit(&(pq->Pop));
}
void MqPush(Myqueue* pq, STDataType x)
{
assert(pq);
StackPush(&(pq->Push), x);
}
void MqPop(Myqueue* pq)
{
while (!StackEmpty(&(pq->Push)))
{
StackPush(&(pq->Pop), StackTop(&(pq->Push)));
StackPop(&(pq->Push));
}
StackPop(&(pq->Pop));
while (!StackEmpty(&(pq->Pop)))
{
StackPush(&(pq->Push), StackTop(&(pq->Pop)));
StackPop(&(pq->Pop));
}
}
STDataType MqTop(Myqueue* pq)
{
// 把数据从push弄到pop
while (!StackEmpty(&(pq->Push)))
{
StackPush(&(pq->Pop), StackTop(&(pq->Push)));
StackPop(&(pq->Push));
}
STDataType ret = pq->Pop._a[pq->Pop._top - 1];
// 再把数据弄回去
while (!StackEmpty(&(pq->Pop)))
{
StackPush(&(pq->Push), StackTop(&(pq->Pop)));
StackPop(&(pq->Pop));
}
return ret;
}
int MqEmpty(Myqueue* pq)
{
if (pq->Push._top == 0)
return 1;
return 0;
}
int main()
{
Myqueue q;
MqInit(&q);
MqPush(&q, 1);
MqPush(&q, 2);
MqPush(&q, 3);
MqPush(&q, 4);
while (!MqEmpty(&q))
{
printf("%d ", MqTop(&q));
MqPop(&q);
}
return 0;
}