1.栈
定义
是一种特殊的线性表,只能在一端插入和删除数据元素,这一端被称为栈顶,相对地,把另一端称为栈底
进栈、入栈或压栈:向一个栈插入新元素,把新元素放到栈顶元素的上面,使之成为新的栈顶元素
出栈或退栈:从一个栈删除元素,是把栈顶元素删除掉,使其相邻的元素成为新的栈顶元素
栈又称为后进先出(Last In First Out)的线性表
底层选择:链表和顺序表都可以,优先选取顺序表,因为在插入数据时时间复杂度较小为O(1)
实现:Stack.h
(与顺序表实现类似)
typedef int STDataType;
typedef struct stack
{
STDataType* arr;
int capacity;//空间大小
int top;//栈顶
}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);
要想打印栈内元素,栈不能遍历,必须将栈顶元素出栈后,相邻元素才能成为新栈顶,方可再次出栈打印 ,操作如下:
while(!STEmpty(&ps))
{
//取栈顶元素
STDataType ret= STTop(&s);
printf("%d ", ret);
//出栈
STPop(&s)
}
2.队列
定义
一种特殊的线性表,特殊之处在于它只允许在表的前端(front)进行删除操作,而在表的后端(rear)进行插入操作
进行插入操作的端称为队尾
进行删除操作的端称为队头
队列中没有元素时,称为空队列
底层选择:使用稍加改造后的链表更优
实现:Queue.h
typedef int QDataType;
typedef struct Queuenode
{
int data;
struct Queuenode* next;
}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);
//队列判空
bool QueueEmpty(Queue* pq);
//取队头数据
QDataType QueueFront(Queue* pq);
//取队尾数据
QDataType QueueBack(Queue* pq);
//队列有效元素个数
int QueueSize(Queue* pq);
//销毁队列
void QueueDestroy(Queue* pq);
入队列操作如下:
void QueuePush(Queue* pq, QDataType x)
{
assert(pq);
QNode* newnode=(QNode*)malloc(sizeof(QNode));
if (newnode == NULL)
{
perror("malloc");
exit(1);
}
newnode->data = x;
newnode->next = NULL;
//如果队列为空
if (pq->phead == NULL)
{
pq->phead = pq->ptail = newnode;
}
//队列不为空时
else
{
pq->ptail->next = newnode;
pq->ptail = newnode;
}
pq->size++;
}
出队列操作:
bool QueueEmpty(Queue* pq)
{
assert(pq);
return pq->phead == NULL;
}
void QueuePop(Queue* pq)
{
assert(pq);
//当队列为空时不能出栈
assert(!QueueEmpty(pq));
//只有一个结点情况
if (pq->phead == pq->ptail)
{
free(pq->phead);
pq->phead = pq->ptail = NULL;
}
//多个节点情况
else
{
QNode* next = pq->phead->next;
free(pq->phead);
pq->phead = next;
}
}