运行环境:VS2019
主要内容:顺序栈、链栈、队列
1.顺序栈
1.1顺序栈基础操作:初始化栈、判断栈是否为空、进栈、出栈、获得栈顶元素
初始化栈:就是将栈的栈顶指针指向-1,指栈空
void InitStack(sqStack *s)
{
s->top = -1;
}
判断栈是否为空:可以使用if函数来对top位置是否在空的位置,当然直接return更加方便
int StackEmpty(sqStack s)
{
return s.top == -1;
}
进栈:首先先判断一下栈溢出了没,具体操作可以大家自己去找,实际操作是对栈顶指针加1,因为指针指向的栈顶的元素,必须先加1再赋值。
void Push(sqStack* s,ElemType value)
{
if (s->top >= MaxSize)
return;
s->data[++s->top] = value;
}
出栈:如果你要输出值,那就先保存值再把top指针减一,不需要直接将top减一。
ElemType Pop(sqStack* s)
{
if (s->top == -1)
return 5555555555;
ElemType value = s->data[s->top--];
return value;
}
获得栈顶元素:就是直接返回data以top为索引的值就行了。
ElemType GetTopValue(sqStack S)
{
ElemType e = S.data[S.top];
return e;
}
顺序栈全部代码如下:
#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
#include <stdlib.h>
typedef int ElemType;
#define MaxSize 50
//栈的数据结构
typedef struct sqStack
{
ElemType data[MaxSize];
int top;
}sqStack;
void printfStack(sqStack s)
{
while (s.top != -1)
{
printf("%d\t",s.data[s.top--]);
}
}
//初始化栈顶
void InitStack(sqStack *s)
{
s->top = -1;
}
//判断栈是否为空
int StackEmpty(sqStack s)
{
return s.top == -1;
}
//进栈
void Push(sqStack* s,ElemType value)
{
if (s->top >= MaxSize)
return;
s->data[++s->top] = value;
}
//出栈
ElemType Pop(sqStack* s)
{
if (s->top == -1)
return 5555555555;
ElemType value = s->data[s->top--];
return value;
}
ElemType GetTopValue(sqStack S)
{
ElemType e = S.data[S.top];
return e;
}
int main(void)
{
sqStack s;
InitStack(&s);
if (StackEmpty(s))
printf("Yes\n");
else
printf("No\n");
Push(&s, 5);
Push(&s, 6);
Push(&s, 7);
printfStack(s);
Pop(&s);
printf("\n");
printfStack(s);
printf("\nThe top number is %d\n", GetTopValue(s));
}
2.链栈
2.1链栈内容包括:入栈,出栈
入栈、出栈:入栈的思维其实和线性链表思维一样,因为他的结构体如下。
typedef struct StackNode
{
ElemType data;
struct StackNode * next;
}StackNode,*StackList;
具体方法同线性链表。可参考下面连接数据结构C语言基础代码5:单链表相关操作(全)_Maxg1en-的博客-CSDN博客
数据结构C语言基础代码6:双链表相关操作(全)_Maxg1en-的博客-CSDN博客
void Push(StackList *s,ElemType value)
{
StackList p = (StackList)malloc(sizeof(StackNode));
p->data = value;
p->next = *s;
*s = p;
}
这里出栈需要考虑一个返回值问题,具体如何解决在播客其他文章可见。
void Pop(StackList* s)
{
StackList h = *s;//他只是复制了数值到这个h上
if (h->next == NULL)
return;
*s = h->next;//得到指针后用*s 来。
}
链栈全部代码如下:
#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
#include <stdlib.h>
typedef int ElemType;
#define MaxSize 50
//栈的数据结构
typedef struct StackNode
{
ElemType data;
struct StackNode * next;
}StackNode,*StackList;
void printfStack(StackList s)
{
while (s->next != NULL)
{
printf("%d", s->data);
s = s->next;
}
}
void Push(StackList *s,ElemType value)
{
StackList p = (StackList)malloc(sizeof(StackNode));
p->data = value;
p->next = *s;
*s = p;
}
//出栈
void Pop(StackList* s)
{
StackList h = *s;//他只是复制了数值到这个h上
if (h->next == NULL)
return;
*s = h->next;//得到指针后用*s 来。
}
int main()
{
StackList s=(StackList)malloc(sizeof(StackNode));
s->next = NULL;
Push(&s,5);Push(&s, 5);
printfStack(s);
Pop(&s);
printfStack(s);
return 0;
}
3队列
队列:初始化队、判断队是否为空、进队、出队。
3.1队的结构体:队有头指针,尾指针和数据域,这是由队列的性质决定的,他只能从队尾进入,队头出去。
typedef struct sqqueue
{
ElemType data[MaxSize];
int front,
rear;
}sqqueue;
3.2初始化队:将队头等于队尾等于0,表示队空
void Initqueue(sqqueue *s)
{
s->front = s->rear = 0;
}
3.3 判断队是否为空:当队头等于队尾的时候,则队满了
int queueEmpty(sqqueue s)
{
return s.front == s.rear;
}
3.4入队:首先就是保证代码的健壮性,具体自己思考不做赘述,rear是指向有数据的下一个位置,而头指针一直指向队首。rear的数值不能简单+1,会造成溢出,可以使用循环队列解决,rear = (rear+1)%Maxsize,比如数组有10大小,那么当将9位置赋值后,给10位置赋值造成溢出,(9+1)%10=0,所以存到了0位置。
//入队
void EnQueue(sqqueue* s,int x)
{
if ((s->rear + 1) % MaxSize == s->front)
{
printf("队满");
return;
}
s->data[s->rear] = x;
s->rear = (s->rear + 1) % MaxSize;
}
3.5出队:当头指针本来在9位置,后来输出后常理其应该走到10,但是10属于溢出,故将头指针移动到0.
void OutQueue(sqqueue* s)
{
s->front = (s->front + 1) % MaxSize;
}
关于队列的全部内容如下,链队过于重复,不做多赘述,大概原理同链表无本质区别,
#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
#include <stdlib.h>
typedef int ElemType;
#define MaxSize 50
//队的数据结构
typedef struct sqqueue
{
ElemType data[MaxSize];
int front,
rear;
}sqqueue;
//输出队列
void printfqueue(sqqueue s)
{
while (s.front != s.rear)
{
printf("%d",s.data[s.front]);
s.front = (s.front + 1) % MaxSize;
}
printf("\n");
}
//初始化
void Initqueue(sqqueue *s)
{
s->front = s->rear = 0;
}
//判断是否为空
int queueEmpty(sqqueue s)
{
return s.front == s.rear;
}
//入队
void EnQueue(sqqueue* s,int x)
{
if ((s->rear + 1) % MaxSize == s->front)
{
printf("队满");
return;
}
s->data[s->rear] = x;
s->rear = (s->rear + 1) % MaxSize;
}
//出队
void OutQueue(sqqueue* s)
{
s->front = (s->front + 1) % MaxSize;
}
int main()
{
sqqueue s;
Initqueue(&s);
if (queueEmpty(s))
{
printf("yes\n");
}
else
printf("No\n");
EnQueue(&s, 5);
EnQueue(&s, 6);
EnQueue(&s, 7);
printfqueue(s);
OutQueue(&s);
printfqueue(s);
return 0;
}