数据结构——栈与队列

1. 创作灵感

在学习了链表之后,可以衍生出另外两个新的数据结构:栈(先进后出的线性表)、队列(先进先出的线性表)。通过几个简单的例子,实现栈和队列,提升数据结构的熟练程度

2. 栈的顺序存储结构及实现

通过数组存储数据,实现先进后出的效果。在实现的过程中要注意,初始化栈顶。

cpp 复制代码
/*栈和队列*/
#define  MAXSIZE 10

typedef int SElemType;
typedef struct 
{
	SElemType data[MAXSIZE];
	int top; //栈顶

}SqStack;

//入栈
Status Push(SqStack* S, SElemType e)
{
	if (S->top == MAXSIZE - 1)
	{
		return ERR;

	}
	S->top++;
	S->data[S->top] = e;
	return OK;


}

//出栈
Status Pop(SqStack *S, SElemType* e)
{
	if (S->top == -1)
	{
		return ERR;

	}
	
	*e=S->data[S->top] ;
	S->top--;

	return OK;


}


int main()
{	//test
	int a = 1, b = 2, c = 3;
	int d, e, f;
	SqStack MYStack;
	MYStack.top = -1;

	Push(&MYStack, a);
	Push(&MYStack, b);
	Push(&MYStack, c);
	Pop(&MYStack, &d);
	Pop(&MYStack, &e);
	Pop(&MYStack, &f);
	printf("%d,%d,%d\n", d, e, f);
	


	return 0;
}

3. 栈的链式存储结构

有的时候栈内的元素的个数是不确定的,为了节约存储空间,我们使用链式结构存储栈,以下是链式栈的实现方式

3.1 链式栈的定义

cpp 复制代码
//首先定义栈的一个节点
typedef struct StackNode
{
	char name[30];//存储数据
	struct StackNode* next;//指向下一个节点

}stacknode,*linkstackptr;

//定义一个结构体表示链式栈
typedef struct LinkStack
{
	linkstackptr top;
	int count;
}LinkStack;

3.2 入栈操作

cpp 复制代码
//链站的入栈操作
Status Push(LinkStack* S, const char* e)
{
	linkstackptr s = (linkstackptr)malloc(sizeof(stacknode));
	strcpy_s(s->name,30,e);//将字符串保存到新节点的数据中
	s -> next = S->top;    //新节点的指向栈
	S->top = s;				//更新栈顶
	S->count++;
	return OK;

}

3.3 出栈操作

cpp 复制代码
//链栈的出栈操作
Status Pop(LinkStack* S, char* e)
{
	linkstackptr p;
	strcpy_s(e, 30, S->top->name);
	p = S->top;
	S->top = S->top->next;
	free(p);
	S->count--;
	return OK;
}

3.4 程序的调用

cpp 复制代码
int main()
{    //test
    LinkStack Mylinkstack;
    char e1[30];
    Push(&Mylinkstack, "zhang san");
    Push(&Mylinkstack, "LI si");
    Push(&Mylinkstack, "wang er");
    Push(&Mylinkstack, "zhao liu");

    Pop(&Mylinkstack, e1);
    printf("%s\n", e1);
    Pop(&Mylinkstack, e1);
    printf("%s\n", e1);
    Pop(&Mylinkstack, e1);
    printf("%s\n", e1);

    return 0;
}

运行结果:

从运行结果看实现了先进后出的顺序。

4.队列的链式结构

队列是为了实现先进先出(FIFO)顺序调用的线性表,在存储元素个数不确定的情况下,为了节约存储空间,同样适合使用链式存储结构去实现。

4.1 队列的定义以及初始化

cpp 复制代码
//定义链式队列的一个节点
typedef struct QNode
{
	char name[30];
	struct QNode* next;
}Qnode, * Qnodeptr;

//定义链式队列
typedef struct
{
	Qnodeptr front, rear;
}LinkQueue;

// 链式队列初始化函数
Status InitQueue(LinkQueue* Q)
{
	// 为头节点分配内存
	Q->front = Q->rear = (Qnodeptr)malloc(sizeof(Qnode));
	if (!Q->front) // 检查头节点内存分配是否成功
	{
		printf("Queue init failed: malloc error!\n");
		return ERR;
	}
	Q->front->next = NULL; // 头节点的next置空,队列初始为空
	return OK;
}

4.2 尾部插入元素

cpp 复制代码
/插入元素e在队尾
Status EnQueue(LinkQueue* Q, const char* e)
{
	Qnodeptr s = (Qnodeptr)malloc(sizeof(Qnode));
	if (!s)
		printf("Error!\n");
	strcpy_s(s->name, 30, e);//将字符串保存到新节点的数据中
	s->next = NULL;
	Q->rear->next = s;
	Q->rear = s;
	return OK;

}

4.3 队头取出元素

cpp 复制代码
//出队
Status ExQueue(LinkQueue* Q, char* e)
{
	Qnodeptr p;//定义一个节点的指针
	if (Q->front == Q->rear)
		return ERR;
	p = Q->front->next;
	strcpy_s(e, 30, p->name);
	Q->front->next = p->next;
	if (Q->rear == p)
		Q->rear = Q->front;
	free(p);
	return OK;

}

4.4 测试调用

cpp 复制代码
int main()
{	
	LinkQueue MyQueue;
	char e1[30];
	if (InitQueue(&MyQueue) != OK)
	{
		return -1; // 初始化失败,直接退出程序
	}


	EnQueue(&MyQueue, "Zhangsan");
	EnQueue(&MyQueue, "Lisi");
	EnQueue(&MyQueue, "Wanger");
	EnQueue(&MyQueue, "Zhaoliu");

	ExQueue(&MyQueue, e1);
	printf("%s\n", e1);
	ExQueue(&MyQueue, e1);
	printf("%s\n", e1);
	ExQueue(&MyQueue, e1);
	printf("%s\n", e1);
	return 0;
}

测试结果:

符合先进先出的顺序

相关推荐
Zik----1 小时前
Leetcode27 —— 移除元素(双指针)
数据结构·算法
睡一觉就好了。2 小时前
list容器简介及其接口函数
数据结构·list
adore.9682 小时前
2.22 oj基础92 93 94+U12
数据结构·c++·算法
Rhystt3 小时前
代码随想录第二十六天|669. 修剪二叉搜索树、108.将有序数组转换为二叉搜索树、538.把二叉搜索树转换为累加树
数据结构·c++·算法·leetcode
想做功的洛伦兹力13 小时前
2026/2/22日打卡
数据结构·算法
不染尘.3 小时前
字符串哈希
开发语言·数据结构·c++·算法·哈希算法
今儿敲了吗3 小时前
25| 丢手绢
数据结构·c++·笔记·学习·算法
wostcdk3 小时前
归并排序 & 逆序对
数据结构·算法
手握风云-4 小时前
Java 数据结构第三十期:LRUCache 的“遗忘机制”
数据结构
重生之后端学习4 小时前
17. 电话号码的字母组合
java·开发语言·数据结构·算法·深度优先