day23:顺序栈、链式栈、循环队列和链式队列(链式栈和链式队列)

1、链式栈

linkstack.h:

#ifndef _LINKSTACK_H_
#define _LINKSTACK_H_

#include <string.h>
#include <stdlib.h>
#include <stdio.h>

typedef int datatype;

typedef struct node
{
	union{
		datatype data; //存储数据域
		int top; 	//记录栈顶位置
	};
	struct node *next;
}LinkStack,*LinkStackPtr;

//创建链式栈
LinkStackPtr stack_create();

//判空
int stack_empty(LinkStackPtr S);

//入栈
int stack_push(LinkStackPtr S,datatype e);

//遍历
void stack_show(LinkStackPtr S);

//出栈
int stack_pop(LinkStackPtr S);

//销毁
void stack_free(LinkStackPtr S);

#endif

linkstack.c:

#include "linkstack.h"

/*
函数功能:创建链式栈
函数参数:无
函数返回值:成功返回链表栈地址,失败返回NULL
*/
LinkStackPtr stack_create()
{
	LinkStackPtr S=(LinkStackPtr)malloc(sizeof(LinkStack));
	if(NULL == S)
	{
		printf("创建链表栈失败\n");
		return NULL;
	}
	//top从-1开始计数,表示链式栈为空
	S->top=-1;
	printf("创建成功\n");
	return S;
}

/*
函数功能:判空
函数参数:链式栈
函数返回:链式栈为空返回真,不为空返回假
*/
int stack_empty(LinkStackPtr S)
{
	//判断逻辑
	if(NULL == S)
	{
		printf("所给链表不合法\n");
		return 0;
	}
	return S->top==-1;
}

/*
函数功能:入栈
函数参数:链式栈,入栈元素
函数返回值:入栈成功返回真,失败返回假
*/
int stack_push(LinkStackPtr S,datatype e)
{
	//判断逻辑
	if(NULL == S)
	{
		printf("所给链表不合法\n");
		return 0;
	}
	//封装节点
	LinkStackPtr p=(LinkStackPtr)malloc(sizeof(LinkStack));
	p->data=e;
	//头插
	p->next=S->next;
	S->next=p;
	//表长变化
	S->top++;
	printf("入栈成功\n");
	return 1;
}

/*
函数功能:遍历
函数参数:链式栈
函数返回值:无
*/
void stack_show(LinkStackPtr S)
{
	//判断逻辑
	if(NULL == S)
	{
		printf("遍历失败\n");
		return;
	}
	LinkStackPtr q=S->next;
	//遍历输出,直到最后一个
	while(q!=NULL)
	{
		printf("%d",q->data);
		q=q->next;
	}
	puts("");
	printf("遍历成功\n");
}

/*
函数功能:出栈
函数参数:链式栈
函数返回值:出栈成功返回真,失败返回假
*/
int stack_pop(LinkStackPtr S)
{
	//判断逻辑
	if(NULL == S || stack_empty(S))
	{
		printf("出栈失败\n");
	}
	LinkStackPtr p=S->next;
	//当不是只剩一个节点的时候
	if(S->top>0)
	{
		//让头节点指向下一个的下一个
		S->next=S->next->next;
	}else{
		//当是最后一个节点时,置空
		S->next=NULL;
	}
	printf("%d出栈成功\n",p->data);
	free(p);
	//表长变化
	S->top--;
	printf("出栈成功\n");
	return 1;
}

/*
函数功能:销毁链式栈
函数参数:链式栈
函数返回值:无
*/
void stack_free(LinkStackPtr S)
{
	//判断逻辑
	if(NULL == S)
	{
		printf("销毁失败\n");
		return;
	}
	LinkStackPtr q=S->next;
	//链式栈不为空则一直出栈
	while(!stack_empty(S))
	{
		stack_pop(S);
	}
	free(S);
	S=NULL;
	printf("销毁成功\n");
}

main.c:

#include "linkstack.h"

int main()
{
	//调用创建链式栈函数
	LinkStackPtr S=stack_create();
	if(NULL == S)
	{
		printf("创建链表栈失败\n");
		return -1;
	}
	//调用入栈函数
	stack_push(S,9);
	stack_push(S,5);
	stack_push(S,2);
	stack_push(S,7);
	//调用遍历函数
	stack_show(S);
	//调用出栈函数
	stack_pop(S);
	//调用销毁函数
	stack_free(S);
	S=NULL;
	return 0;
}

2、链式队列

linkqueue.h:

#ifndef _LINKQUEUE_H_
#define _LINKQUEUE_H_

#include <stdlib.h>
#include <string.h>
#include <stdio.h>

typedef int datatype;
typedef struct node
{
	union
	{
		datatype data;
		int len;
	};
	struct node *next;
}Node;

typedef struct 
{
	Node *head;
	Node *tail;
}LinkQueue,*LinkQueuePtr;

//创建链表队列
LinkQueuePtr queue_create();

//判空
int queue_empty(LinkQueuePtr LQ);

//入队
int queue_push(LinkQueuePtr LQ,datatype e);

//遍历
void queue_show(LinkQueuePtr LQ);

//出队
int queue_pop(LinkQueuePtr LQ);

//销毁
void queue_free(LinkQueuePtr LQ);

#endif

 linkqueue.c:

#include "linkqueue.h"


/*
函数功能:创建链式队列
函数参数:无
函数返回值:成功返回链式队列首地址,失败返回NULL
*/
LinkQueuePtr queue_create()
{
	LinkQueuePtr LQ=(LinkQueuePtr)malloc(sizeof(LinkQueue));
	if(NULL == LQ)
	{
		printf("创建链表队列失败\n");
		return NULL;
	}
	LQ->head=(Node *)malloc(sizeof(Node));
	if(NULL == LQ->head)
	{
		free(LQ);
		printf("创建队列失败\n");
		return NULL;
	}
	//让头指针指向空,长度置0
	LQ->head->next=NULL;
	LQ->head->len=0;
	//让尾指针指向头指针
	LQ->tail=LQ->head;
	printf("创建成功\n");
	return LQ;
}

/*
函数功能:判空
函数参数:链式队列
函数返回值:队列为空返回真,不为空返回假
*/
int queue_empty(LinkQueuePtr LQ)
{
	//判断逻辑
	if(NULL == LQ || NULL == LQ->head)
	{
		printf("所给队列非法\n");
		return 0;
	}
	return LQ->head==LQ->tail;
}

/*
函数功能:入队
函数参数:链式队列,入队元素
函数返回值:入队成功返回真,失败返回假
*/
int queue_push(LinkQueuePtr LQ,datatype e)
{
	if(NULL == LQ || NULL == LQ->head)
	{
		printf("所给队列非法\n");
		return 0;
	}
	//申请节点
	Node *p=(Node *)malloc(sizeof(Node));
	if(NULL == p)
	{
		printf("入队失败\n");
		return 0;
	}
	p->data=e;
	p->next=NULL;
	//让尾指针所在节点的指针域指向新的节点,并移动尾指针
	LQ->tail->next=p;
	LQ->tail=p;
	LQ->head->len++;
	printf("入队成功\n");
	return 1;
}

/*
函数功能:遍历
函数参数:链式队列
函数返回值:无
*/
void queue_show(LinkQueuePtr LQ)
{
	//判断逻辑
	if(NULL == LQ || queue_empty(LQ))
	{
		printf("遍历失败\n");
		return;
	}
	//让遍历从头节点开始
	Node *q=LQ->head;
	while(q!=NULL)
	{
		printf("%d",q->data);
		q=q->next;
	}
	puts("");
	printf("遍历成功\n");
}
/*
函数功能:出队
函数参数:链式队列
函数返回值:出队成功返回真,失败返回假
*/

//出队
int queue_pop(LinkQueuePtr LQ)
{
	//判断逻辑
	if(NULL == LQ || queue_empty(LQ))
	{
		printf("出队失败\n");
		return 0;
	}
	Node *p=LQ->head->next;
	LQ->head->next=p->next;
	printf("%d出队\n",p->data);
	LQ->head->len--;
	free(p);
	//如果已经删完了最后一个节点了,就让尾指针指向头节点,防止出现野指针
	if(LQ->head->next==NULL)
	{
		LQ->tail=LQ->head;
	}
	printf("出队成功\n");
	return 1;
}
/*
函数功能:销毁
函数参数:链式队列
函数返回值:成功返回真,失败返回假
*/

//销毁
void queue_free(LinkQueuePtr LQ)
{
	//判断逻辑
	if(NULL == LQ ||NULL == LQ->head)
	{
		printf("销毁失败\n");
		return;
	}
	//释放节点
	while(!queue_empty(LQ))
	{
		queue_pop(LQ);
	}
	//释放头节点
	free(LQ->head);
	LQ->head=NULL;
	LQ->tail=NULL;
	//释放队列
	free(LQ);
	LQ=NULL;
	printf("销毁成功\n");
}

main.c:

#include "linkqueue.h"
int main()
{
	//调用创建链表队列函数
	LinkQueuePtr LQ=queue_create();
	if(NULL == LQ)
	{
		printf("队列创建失败\n");
		return -1;
	}
	//调用入队函数
	queue_push(LQ,9);
	queue_push(LQ,5);
	queue_push(LQ,2);
	queue_push(LQ,7);
	//调用遍历函数
	queue_show(LQ);
	//调用出队函数
	queue_pop(LQ);
	//调用销毁函数
	queue_free(LQ);
	LQ->head=NULL;
	LQ->tail=NULL;
	LQ=NULL;
	return 0;
}

3、思维导图:有道云笔记

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值