栈:线性表的一种,只允许在一端进行插入和删除元素的操作。进行数据插入的一端是栈顶,另一端是栈底。栈中的数据遵循后进先出。
压栈:向栈中插入数据,根据定义,压栈自然在栈顶;
出栈:删除栈中数据,根据定义,出栈也在栈顶。
图示:
栈的实现
一般可以用数组或链表实现,但由于连续出栈时数组比链表更快,数组更优,因此选择以数组实现。
构造栈的结构体包括指针a(指向一个数组)、数组的有效数据top、数组的容量capacity(开辟动态空间);包括实现初始化、出入栈、销毁、获取栈顶元素、获取栈中元素个数、检测栈是否为空(空返回true,非空返false)。
代码实现如下:
typedef struct Stack
{
int _top;
STDataType* _a;
int _capacity;
}Stack;
void StackInit(Stack* ps);//初始化栈
void StackPush(Stack* ps, STDataType x);//入栈
void StackDestroy(Stack* ps);//销毁栈
void StackPop(Stack* ps);//出栈
STDataType StackTop(Stack* ps);//获取栈顶元素
int StackSize(Stack* ps);//获取栈中元素的个数
bool StackEmpty(Stack* ps);//检测栈是否为空,空返回真,非空返回假
void StackInit(Stack* ps)//初始化栈
{
assert(ps);
ps->_a = NULL;
ps->_capacity = 0;
ps->_top = 0;
}
void StackPush(Stack* ps, STDataType x)//入栈
{
assert(ps);
if (ps->_capacity == ps->_top)
{
int newcapacity = ps->_capacity == 0 ? 4 : (ps->_capacity) * 2;
STDataType* tmp = realloc(ps->_a, sizeof(STDataType)*newcapacity);
if (tmp == NULL)
{
printf("realloc fail\n");
exit(-1);
}
ps->_a = tmp;
ps->_capacity = newcapacity;
}
ps->_a[ps->_top] = x;
ps->_top++;
}
void StackDestroy(Stack* ps)//销毁栈
{
assert(ps);
free(ps->_a);
ps->_a = NULL;
ps->_capacity = ps->_top = 0;
}
void StackPop(Stack* ps)//出栈
{
assert(ps);
assert(ps->_top > 0);
ps->_top--;
}
STDataType StackTop(Stack* ps)//获取栈顶元素
{
assert(ps);
assert(ps->_top > 0);
return ps->_a[ps->_top - 1];
}
int StackSize(Stack* ps)//获取栈中元素的个数
{
assert(ps);
return ps->_top;
}
bool StackEmpty(Stack* ps)//检测栈是否为空,空返回真,非空返回假
{
assert(ps);
return ps->_top ==0;
}
队列:线性表的一种,一端入数据,另一端出数据。入数据的一端是队尾,出数据的一端是队头:即队中的数据遵循先进先出。
队列的实现
一般可以用数组或链表实现,但由于连续出数据时链表比数组更快(直接输入对头数据,新对头指向原对头的next),链表更优,因此选择以链表实现。
构造链表的结构体包括数据与next指针(指向下一个)、数组的数据个数size(本身可以不要,但是加上的话可以更直接的得出个数,以空间换时间,特别是有的地方会反复用到size,尤为明显);由于实现时的对头队尾总是要用到,不妨封装一个结构体,包括队头指针front、队尾指针rear。
包括实现初始化、队尾入数据、队头出数据、获取队头元素、获取队尾元素、获取队中元素个数、检测队是否为空(空返回true,非空返false)、销毁队列。
typedef int QDataType;
// 链式结构:表示队列
typedef struct QListNode
{
struct QListNode* _next;
QDataType _data;
}QNode;
// 队列的结构
typedef struct Queue
{
QNode* _front;
QNode* _rear;
int size;
}Queue;
void QueueInit(Queue* q);// 初始化队列
void QueuePush(Queue* q, QDataType data);// 队尾入队列
void QueuePop(Queue* q);// 队头出队列
QDataType QueueFront(Queue* q);// 获取队列头部元素
QDataType QueueBack(Queue* q);// 获取队列队尾元素
int QueueSize(Queue* q);// 获取队列中有效元素个数
bool QueueEmpty(Queue* q);// 检测队列是否为空,如果为空返回非零结果,如果非空返回0
void QueueDestroy(Queue* q);// 销毁队列
void QueueInit(Queue* q)// 初始化队列
{
assert(q);
q->_front = q->_rear = NULL;
q->size = 0;
}
void QueueDestroy(Queue* q)// 销毁队列
{
assert(q);
QNode* cur = q->_front;
while (cur)
{
q->_front = cur->_next;
free(cur);
cur = q->_front;
}
q->_front = q->_rear = NULL;
q->size = 0;
}
void QueuePush(Queue* q, QDataType data)// 队尾入队列
{
assert(q);
QNode* newnode = (QNode*)malloc(sizeof(QNode));
if (newnode == NULL)
{
perror("malloc fail");
exit(-1);
}
newnode->_data = data;
newnode->_next = NULL;
if (q->_front == NULL)//无节点情况
{
q->_front = q->_rear = newnode;
q->size++;
}
else//有节点的情况
{
q->_rear->_next = newnode;
q->_rear = newnode;
q->size++;
}
}
void QueuePop(Queue* q)// 队头出队列
{
assert(q);
//assert(q->_front);//无节点情况
assert(!QueueEmpty(q));
if (q->_front->_next == NULL;)//只有一个节点的情况
{
free(q->_front);
q->_rear = q->_front = NULL;
q->size--;
}
else//其他的情况
{
QNode* cur = q->_front;
q->_front = q->_front->_next;
free(cur);
q->size--;
}
}
QDataType QueueFront(Queue* q)// 获取队列头部元素
{
assert(q);
assert(!QueueEmpty(q));
return q->_front->_data;
}
QDataType QueueBack(Queue* q)// 获取队列队尾元素
{
assert(q);
assert(!QueueEmpty(q));
return q->_rear->_data;
}
bool QueueEmpty(Queue* q)// 检测队列是否为空,如果为空返回非零结果,如果非空返回0
{
assert(q);
return q->_rear == NULL && q->_rear == NULL;
}
int QueueSize(Queue* q)// 获取队列中有效元素个数
{
assert(q);
return q->size;
}