栈和队列是基本的数据结构,是对于线性表的一种拓展,其实个人理解就是限制了顺序表和链表的一些操作,使其在一些特定的场合可以使用。
栈,stack,first in last out,先进后出,这是栈的基本特性,它犹如一个竖着的柜子,只能从栈顶出入,就像你将衣服放进柜子中,一定是最后放的最后才能取出来,当然如果你是个规则的人的话,因此当我们学习了顺序表和链表的操作后,对于实现栈,就不那么困难了,因为它只是将顺序表改造了一下。
栈的实现底层链表和数组都可以,但是因为其在尾删尾插的特性,显然,数组更加契合其属性。
声明
#pragma once
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
typedef int TypeStack;
typedef struct stack
{
TypeStack* _a;
int _top;
int _capcity;
}stack;
void StackInit(stack* pst);
void StackDestory(stack* pst);
void StackPush(stack* pst,TypeStack x);
void StackPop(stack* pst);
int StackSize(stack* pst);
int StackEmpty(stack* pst);
TypeStack StackTop(stack* pst);
实现
#include "stack.h"
void StackInit(stack* pst)
{
assert(pst);
TypeStack* p = (TypeStack*)malloc(sizeof(TypeStack) * 4);
if (p == NULL)
{
printf("内存不足\n");
exit(-1);
}
pst->_a = p;
pst->_top = 0;
pst->_capcity = 4;
}
void StackDestory(stack* pst)
{
assert(pst);
free(pst->_a);
pst->_a = NULL;
pst->_top = 0;
pst->_capcity = 0;
}
void StackPush(stack* pst,TypeStack x)
{
assert(pst);
if (pst->_top == pst->_capcity)
{
pst->_capcity *= 2;
TypeStack* p = (TypeStack*)realloc(pst->_a,sizeof(TypeStack) * pst->_capcity);
if (p == NULL)
{
printf("内存不足");
exit(-1);
}
else
{
pst->_a = p;
}
}
pst->_a[pst->_top] = x;
pst->_top++;
}
void StackPop(stack* pst)
{
assert(pst);
if (pst->_top > 0)
pst->_top--;
}
int StackSize(stack* pst)
{
assert(pst);
return pst->_top;
}
int StackEmpty(stack* pst)
{
assert(pst);
return !pst->_top;
}
TypeStack StackTop(stack* pst)
{
assert(pst);
assert(pst->_top > 0);
return pst->_a[pst->_top - 1];
}
而队列,则是first in first out,先进先出,像什么场景呢?
排队,你先来的,肯定先进呗,所以队列可以用于抽号机,这样排队就是合理且有序,而队列呢,还是用链表吧。至于为什么,我只能说,如果说不需要随机访问的情况,一般都是链表比较好,且不说队列的头删需要挪动数据的问题。
声明
#pragma once
#include <stdio.h>
#include <assert.h>
#include ""
typedef BTNode* QueueDataType;
typedef struct QueueNode
{
struct QueueNode* _next;
QueueDataType _data;
}QueueNode;
typedef struct Queue
{
struct QueueNode* head;
struct QueueNode* tail;
}Queue;
void QueueInit(Queue* pq);
void QueueDestory(Queue* pq);
void QueuePush(Queue* pq, QueueDataType x);
void QueuePop(Queue* pq);
QueueDataType QueueFront(Queue* pq);
QueueDataType QueueBack(Queue* pq);
int QueueEmpty(Queue* pq);
int QueueSize(Queue* pq);
实现
#include "Queue.h"
void QueueInit(Queue* pq)
{
assert(pq);
pq->head = pq->tail = NULL;
}
void QueueDestory(Queue* pq)
{
assert(pq);
QueueNode* cur = pq->head;
while (cur)
{
QueueNode* next = cur->_next;
free(cur);
cur = next;
}
pq->head = NULL;
}
void QueuePush(Queue* pq, QueueDataType x)
{
assert(pq);
QueueNode* newnode = (QueueNode*)malloc(sizeof(QueueNode));
newnode->_next = NULL;
newnode->_data = x;
if (newnode == NULL)
{
printf("内存不够\n");
exit(-1);
}
if (pq->head == NULL)
{
pq->tail = pq->head = newnode;
}
else
{
pq->tail->_next = newnode;
pq->tail = newnode;
}
}
void QueuePop(Queue* pq)
{
assert(pq);
assert(pq->head);
QueueNode* next = pq->head->_next;
free(pq->head);
pq->head = next;
if (pq->head == NULL)
{
pq->tail = NULL;
}
}
QueueDataType QueueFront(Queue* pq)
{
assert(pq);
assert(pq->head);
return pq->head->_data;
}
QueueDataType QueueBack(Queue* pq)
{
assert(pq);
assert(pq->tail);
return pq->tail->_data;
}
int QueueEmpty(Queue* pq)
{
assert(pq);
return pq->head == NULL ? 1 : 0;
}
int QueueSize(Queue* pq)
{
assert(pq);
QueueNode* cur = pq->head;
int count = 0;
while (cur)
{
cur = cur->_next;
count++;
}
return count;
}
其实栈和队列就是特定场合的一个数据整理,总的来说,数据结构都是用来整理数据,如何方便的处理数据,便用那个数据结构,其实各个之间大差不差,主要会使用且了解怎么实现的,如果出问题怎么排查,这些才是根本。