栈
栈的概念及结构
栈是一种特殊的线性表,只允许在固定的一端进行插入删除操作,进行数据的插入删除操作的一端被称为栈顶,另一端被称为栈底,栈中的数据遵循后进先出的原则,栈的插入操作叫做压栈/进栈/入栈,入数据在栈顶,栈的删除操作称为出栈,出数据也在栈顶。分别有链式栈和数组栈。
栈的实现(数组栈)
栈的结构
typedef int valuetype;
typedef struct stack
{
valuetype* arr;
int top;
int capacity;
}stack;
初始化
void Init(stack* pst)
{
assert(pst);
pst->arr=(valuetype*)malloc(sizeof(valuetype)*4);
if(pst->arr==NULL)
{
perror("malloc fail");
return;
}
pst->top=0;
pst->capacity=4;
}
销毁
void destroy(stack* pst)
{
free(pst->arr);
}
删除栈顶元素
void pop(stack* pst)
{
assert(pst);
assert(!isempty(pst));
pst->top--;
}
插入元素
void push(stack* pst,valuetype x)
{
if(isfull(pst))
{
pst->capacity*=2;//若刚开始容量给的是0则这个地方还要进行一个三目判断
valuetype* tmp=(valuetype*)realloc(pst->arr,pst->capacity*sizeof(valuetype));
if(tmp==NULL)
{
perror("realloc fail");
return;
}
pst->arr=tmp;
}
pst->arr[pst->top]=x;
pst->top++;
}
判空
bool isempty(stack* pst)
{
assert(pst);
if(pst->top==0)
return true;
return false;
}
判满
bool isfull(stack* pst)
{
if(pst->top==pst->capacity)
return true;
return false;
}
栈顶元素
valuetype top(stack* pst)
{
assert(pst);
assert(pst->top);
return pst->arr[pst->top-1];
}//为什么要有这个函数,因为使用的人并不知道你初始化是哪种初始化,还得回去看你的初始化源码
数据个数
int size(stack* pst)
{
assert(pst);
return pst->size;
}
队列
队列的概念与结构
只允许在一段进行插入操作,在另一端进行删除操作,进行插入数据的一端叫做队尾,删除数据的一端称为队头,插入数据称为入队,删除数据称为出队。
队列的实现
队列的结构
typedef int valuetype
typedef struct queuenode
{
struct queue next;
valuetype data;
}node;
typedef struct queue
{
node* phead;
node* ptail;
int size;
}queue;
初始化
void Init(queue* pq)
{
pq->phead = pq->ptail = NULL;
pq->size = 0;
}
销毁
void destroy(queue* pq)
{
node* cur = pq->phead;
while (cur != NULL)
{
node* next = cur->next;
free(cur);
cur = next;
}
pq->phead = pq->ptail = NULL;
}
插入
void push(queue* pq, valuetype x)
{
node* newnode = (node*)malloc(sizeof(node));
if (newnode == NULL)
{
perror("malloc fail");
return;
}
newnode->next = NULL;
newnode->data = x;
if (pq->phead == NULL&&pq->ptail == NULL)
{
pq->phead = pq->ptail = newnode;
}
else
{
newnode->next = NULL;
newnode->data = x;
pq->ptail->next = newnode;
pq->ptail = newnode;
}
pq->size++;
}
删除
void erase(queue* pq)
{
assert(pq);
assert(pq->phead!=NULL);
node* cur = pq->phead;
node* next = cur->next;
free(cur);
pq->phead = next;
if (pq->phead == NULL)
{
pq->ptail = NULL;
}
pq->size--;
}
返回队头元素
valuetype returnfront(queue* pq)
{
assert(pq);
assert(pq->phead);
return pq->phead->data;
}
判断队列是否为空
bool isempty(queue* pq)
{
if (pq->size == 0)
return true;
return false;
}
返回队尾元素
valuetype returnback(queue* pq)
{
assert(pq);
assert(pq->ptail);
return pq->ptail->data;
}
加深印象推荐题目
用队列实现栈
https://leetcode.cn/problems/implement-stack-using-queues/
typedef int valuetype;
typedef struct queuenode
{
struct queuenode* next;
valuetype data;
}node;
typedef struct queue
{
node* phead;
node* ptail;
int size;
}queue;
void Init(queue* pq)
{
pq->phead = pq->ptail = NULL;
pq->size = 0;
}
void destroy(queue* pq)
{
node* cur = pq->phead;
while (cur != NULL)
{
node* next = cur->next;
free(cur);
cur = next;
}
pq->phead = pq->ptail = NULL;
}
void push(queue* pq, valuetype x)
{
node* newnode = (node*)malloc(sizeof(node));
if (newnode == NULL)
{
perror("malloc fail");
return;
}
newnode->next = NULL;
newnode->data = x;
if (pq->phead == NULL&&pq->ptail == NULL)
{
pq->phead = pq->ptail = newnode;
}
else
{
newnode->next = NULL;
newnode->data = x;
pq->ptail->next = newnode;
pq->ptail = newnode;
}
pq->size++;
}
void erase(queue* pq)
{
assert(pq);
assert(pq->phead!=NULL);
node* cur = pq->phead;
node* next = cur->next;
free(cur);
pq->phead = next;
if (pq->phead == NULL)
{
pq->ptail = NULL;
}
pq->size--;
}
valuetype returnfront(queue* pq)
{
assert(pq);
assert(pq->phead);
return pq->phead->data;
}
bool isempty(queue* pq)
{
if (pq->size == 0)
return true;
return false;
}
valuetype returnback(queue* pq)
{
assert(pq);
assert(pq->ptail);
return pq->ptail->data;
}
typedef struct {
queue* a1;
queue* a2;
} MyStack;
MyStack* myStackCreate() {
MyStack* obj=(MyStack*)malloc(sizeof(MyStack));
if(obj==NULL)
{
perror("malloc fail");
return NULL;
}
obj->a1=(queue*)malloc(sizeof(queue));
obj->a2=(queue*)malloc(sizeof(queue));
Init(obj->a1);
Init(obj->a2);
return obj;
}
void myStackPush(MyStack* obj, int x) {
if(isempty(obj->a1))
{
push(obj->a2,x);
}
else if(isempty(obj->a2))
{
push(obj->a1,x);
}
}
int myStackPop(MyStack* obj) {
valuetype x=0;
if(isempty(obj->a1))
{
while(obj->a2->size!=1)
{
valuetype tmp=returnfront(obj->a2);
erase(obj->a2);
push(obj->a1,tmp);
}
x=returnfront(obj->a2);
erase(obj->a2);
}
else if(isempty(obj->a2))
{
while(obj->a1->size!=1)
{
valuetype tmp=returnfront(obj->a1);
erase(obj->a1);
push(obj->a2,tmp);
}
x=returnfront(obj->a1);
erase(obj->a1);
}
return x;
}
int myStackTop(MyStack* obj) {
valuetype x=0;
if(isempty(obj->a1))
{
while(obj->a2->size)
{
valuetype tmp=returnfront(obj->a2);
erase(obj->a2);
push(obj->a1,tmp);
x=tmp;
}
}
else if(isempty(obj->a2))
{
while(obj->a1->size!=0)
{
valuetype tmp=returnfront(obj->a1);
erase(obj->a1);
push(obj->a2,tmp);
x=tmp;
}
}
return x;
}
bool myStackEmpty(MyStack* obj) {
if(((!isempty(obj->a1))&&(!isempty(obj->a2)))
||(isempty(obj->a1)&&(!isempty(obj->a2)))
||((!isempty(obj->a1))&&isempty(obj->a2)))
return false;
return true;
}
void myStackFree(MyStack* obj) {
free(obj->a1);
free(obj->a2);
free(obj);
}
用栈实现队列
https://leetcode.cn/problems/implement-queue-using-stacks/
typedef int valuetype;
typedef struct stack
{
valuetype* arr;
int top;
int capacity;
}stack;
void Init(stack* pst)
{
assert(pst);
pst->arr=(valuetype*)malloc(sizeof(valuetype)*4);
if(pst->arr==NULL)
{
perror("malloc fail");
return;
}
pst->top=0;
pst->capacity=4;
}
bool isempty(stack* pst)
{
assert(pst);
if(pst->top==0)
return true;
return false;
}
bool isfull(stack* pst)
{
if(pst->top==pst->capacity)
return true;
return false;
}
valuetype top(stack* pst)
{
assert(pst);
assert(pst->top);
return pst->arr[pst->top-1];
}//为什么要有这个函数,因为使用的人并不知道你初始化是哪种初始化,还得回去看你的初始化源码
void pop(stack* pst)
{
assert(pst);
assert(!isempty(pst));
pst->top--;
}
void push(stack* pst,valuetype x)
{
if(isfull(pst))
{
pst->capacity*=2;//若刚开始容量给的是0则这个地方还要进行一个三目判断
valuetype* tmp=(valuetype*)realloc(pst->arr,pst->capacity*sizeof(valuetype));
if(tmp==NULL)
{
perror("realloc fail");
return;
}
pst->arr=tmp;
}
pst->arr[pst->top]=x;
pst->top++;
}
void destroy(stack* pst)
{
free(pst->arr);
}
typedef struct {
stack* a1;
stack* a2;
} MyQueue;
MyQueue* myQueueCreate() {
MyQueue* obj=(MyQueue*)malloc(sizeof(MyQueue));
obj->a1=(stack*)malloc(sizeof(stack));
obj->a2=(stack*)malloc(sizeof(stack));
Init(obj->a1);
Init(obj->a2);
return obj;
}
void myQueuePush(MyQueue* obj, int x) {
push(obj->a1,x);
}
int myQueuePop(MyQueue* obj) {
if(isempty(obj->a2))
{
while(!isempty(obj->a1))
{
valuetype tmp=obj->a1->arr[obj->a1->top-1];
pop(obj->a1);
push(obj->a2,tmp);
}
}
valuetype tmp=obj->a2->arr[obj->a2->top-1];
pop(obj->a2);
return tmp;
}
int myQueuePeek(MyQueue* obj) {
if(isempty(obj->a2))
{
while(!isempty(obj->a1))
{
valuetype tmp=obj->a1->arr[obj->a1->top-1];
pop(obj->a1);
push(obj->a2,tmp);
}
}
return obj->a2->arr[obj->a2->top-1];
}
bool myQueueEmpty(MyQueue* obj) {
if((isempty(obj->a1)&&!isempty(obj->a2))||(!isempty(obj->a1)&&isempty(obj->a2))||((!isempty(obj->a1))&&(!isempty(obj->a2))))
{
return false;
}
return true;
}
void myQueueFree(MyQueue* obj) {
free(obj->a1);
free(obj->a2);
free(obj);
}
设计循环队列
https://leetcode.cn/problems/design-circular-queue/
这一题有两种解法,下面只实现链表的解法
typedef struct qnode
{
struct qnode* next;
int data;
}node;
typedef struct {
node* phead;
node* ptail;
} MyCircularQueue;
MyCircularQueue* myCircularQueueCreate(int k) {
MyCircularQueue* obj=(MyCircularQueue*)malloc(sizeof(MyCircularQueue));
obj->phead=obj->ptail=NULL;
node* head=(node*)malloc(sizeof(node));
head->next=head;
head->data=-1;
obj->phead=obj->ptail=head;
for(int i=0;i<k;i++)
{
node* tmp=(node*)malloc(sizeof(node));
tmp->next=obj->phead;
tmp->data=-1;
obj->ptail->next=tmp;
obj->ptail=tmp;
}
obj->ptail=obj->phead;
return obj;
}
bool myCircularQueueEnQueue(MyCircularQueue* obj, int value) {
if(obj->phead==obj->ptail->next)
{
return false;
}
node* cur=obj->ptail->next;
cur->data=value;
obj->ptail=cur;
return true;
}
bool myCircularQueueDeQueue(MyCircularQueue* obj) {
if(obj->phead==obj->ptail)
return false;
obj->phead=obj->phead->next;
return true;
}
int myCircularQueueFront(MyCircularQueue* obj) {
if(obj->phead==obj->ptail)
return -1;
return obj->phead->next->data;
}
int myCircularQueueRear(MyCircularQueue* obj) {
if(obj->phead==obj->ptail)
return -1;
return obj->ptail->data;
}
bool myCircularQueueIsEmpty(MyCircularQueue* obj) {
if(obj->phead==obj->ptail)
return true;
return false;
}
bool myCircularQueueIsFull(MyCircularQueue* obj) {
if(obj->ptail->next==obj->phead)
return true;
return false;
}
void myCircularQueueFree(MyCircularQueue* obj) {
node* cur=obj->phead;
node* next=cur->next;
while(cur->next!=obj->phead)
{
free(cur);
cur=next;
next=cur->next;
}
free(cur);
free(obj);
}