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、思维导图:有道云笔记