数据结构ky备战Day2 - 栈和队列(受限的线性表)
栈
*顺序栈 SeqStack
重点内容:
入栈时判满 S->top == Stack_Size(栈顶指针指向栈顶元素的元素版本)
出栈时判空 S->top == -1
#include<stdio.h>
#include<stdlib.h>
#define StackElemType char
#define OK 1
#define Error -1
#define Stack_Size 50
typedef struct
{
StackElemType elem[Stack_Size]; /* elem是存放栈中的一维数组 */
int top; /* 栈顶元素的下标,空栈为-1 */
}SeqStack;
// 基操 1 初始化
void InitStack(SeqStack *S){
S->top = -1;
}
// 基操2 入栈 注意判满 , 我用的是栈顶指针指向元素的版本
int push(SeqStack *S, StackElemType x)
{
if(S->top == Stack_Size) return Error; // 栈满
S->top ++ ;
S->elem[S->top] = x ;
return OK;
}
// 基操3 出栈 注意判空
int pop(SeqStack *S, StackElemType *x){
if(S->top == -1) return Error;
*x = S->elem[S->top];
S->top--;
return OK;
}
// 基操4 取栈顶元素 注意判空
int getTop(SeqStack S, StackElemType *x){
if(S.top == -1) return Error;
*x = S.elem[S.top];
return OK;
}
链栈 LinkStack
没什么好说的,因为就是受限的单链表,所有操作在表头进行了,相当于复习了一下头插法
#include<stdio.h>
#include<stdlib.h>
#define StackElemType char
#define OK 1
#define Error -1
#define Stack_Size 50
// 链栈注意,他是链表中受限的结构,即只允许在表头进行插入和删除操作
typedef struct node
{
StackElemType data;
struct node *next;
}LinkStackNode, *LinkStack;
// 链栈基操1 进栈
int push(LinkStack top, StackElemType x){
/* 元素x压入栈中,top是头节点 */
LinkStackNode *temp = (LinkStackNode *)malloc(sizeof(LinkStackNode)); // 申请新结点
if(temp == NULL) return Error;
// 头插法插入操作
temp->data = x;
temp->next = top->next;
top->next = temp;
return OK;
}
// 链栈基操2 出栈
int pop(LinkStack top, StackElemType *x){
/* 将栈顶元素弹出 存入x存储空间中 */
LinkStackNode *temp = top->next;
if(temp == NULL) return Error; // 空栈的情况直接返回错误
top->next = temp->next;
*x = temp->data; // 存入x空间
free(temp); // 释放空间
return OK;
}
// 注意多栈的概念,Linkstack top[N]
队列
*循环队列 SeqQueue
重点内容
循环队列的出现就是为了解决假溢出
当rear == Maxsize - 1 时 ,队头可能因为出队而产生空单元,但由于只能在队尾插入,因此导致空单元无法使用
队空:Q->rear == Q.front
队满:(Q->rear + 1) % MaxSize == Q->front
元素长度:(Q->rear - Q->front + MaxSize) % MaxSize
#include<stdio.h>
#include<stdlib.h>
#define QueueElemType char
#define OK 1
#define Error -1
#define MAXSIZE 50
typedef struct{
QueueElemType elem[MAXSIZE];
int front; // 指向表头
int rear; // 指向表尾
}SeqQueue;
// 循环队列基操1 初始化
void InitQueue(SeqQueue *Q){
Q->front = Q->rear = 0;
}
// 循环队列基操2 入队 注意队满的情况
int EnQueue(SeqQueue *Q, QueueElemType x){
if((Q->rear + 1) % MAXSIZE == Q->front) return Error;
Q->elem[Q->rear] = x;
Q->rear = (Q->rear + 1) % MAXSIZE;
return OK;
}
// 循环队列基操3 出队 注意队空的情况
int DeQueue(SeqQueue *Q, QueueElemType *x){
if(Q->front == Q->rear) return Error;
*x = Q->elem[Q->front]; // 队首元素出队
Q->front = (Q->front + 1) % MAXSIZE;
return OK;
}
*法二:tag变量来区分队空和队满
tag == 0 时 队空,tag == 1时 队满,此时不必像法一那样空出一个存储空间来判断队空和队满了
注意两点即可。
- 入队的时候,要注意入队前队空的情况,tag = 0 --- tag =1
- 出队的时候,要注意出队后队空的情况,tag = 1 --- tag = 0
// 循环队列基操2 入队 注意队满的情况
int EnQueue(SeqQueue *Q, QueueElemType x){
if(Q->rear == Q->front && tag == 1) return Error;
if(Q->rear == Q->front && tag == 0) tag = 1; // 队空的情况
Q->elem[Q->rear] = x;
Q->rear = (Q->rear + 1) % MAXSIZE;
return OK;
}
// 循环队列基操3 出队 注意队空的情况
int DeQueue(SeqQueue *Q, QueueElemType *x){
if(Q->front == Q->rear && tag == 0) return Error;
*x = Q->elem[Q->front]; // 队首元素出队
Q->front = (Q->front + 1) % MAXSIZE;
return OK;
}
链队列 LinkQueue
这个没啥好说,就是链表多了两个指针罢了。其他和单链表差不多,所以也不是考察的核心。
仅当单链表基操的练习
#include<stdio.h>
#include<stdlib.h>
#define QueueElemType char
#define OK 1
#define Error -1
#define Stack_Size 50
typedef struct Node{
QueueElemType data;
struct Node *next;
}LinkQueueNode;
typedef struct{
LinkQueueNode *front;
LinkQueueNode *rear;
}LinkQueue;
// 链队列初始化
int initQueue(LinkQueue *Q){
Q->front = (LinkQueueNode *)malloc(sizeof(LinkQueueNode));
if(Q->front != NULL){
Q->rear = Q->front; // 链队列空的条件
Q->front->next = NULL;
return OK;
}
else return Error; // 溢出
}
// 链队列入队
int EnQueue(LinkQueue *Q, QueueElemType x){
LinkQueueNode *newNode;
newNode = (LinkQueueNode *)malloc(sizeof(LinkQueueNode));
if(newNode == NULL) return Error;
// 尾插法
newNode->data = x;
Q->rear->next = newNode; // 注意 表尾在尾部
Q->rear = newNode;
return OK;
}
// 链队列出队
int DeQueue(LinkQueue *Q, QueueElemType *x){
LinkQueueNode *p;
if(Q->front == Q->rear) return Error; // 判空
// 头部删除
p = Q->front->next;
Q->front->next = p->next;
*x = p->data;
free(p);
return OK;
}