1、链式栈
头文件
#ifndef _LINKSTACK_H_
#define _LINKSTACK_H_
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
//类型重命名
typedef int datatype;
//定义结点类型
typedef struct Node
{
union
{
datatype data; //数据域
int len; //头结点数据域
};
struct Node *next; //指针域
}Node, *LinkListPtr;
//定义结构体类型
typedef struct
{
datatype *data;
Node *top;
}LinkStack, *LinkStackPtr;
//创建栈
LinkStackPtr stack_create();
//判空
int stack_empty(LinkStackPtr S);
//入栈
LinkStackPtr stack_push(LinkStackPtr S, datatype e);
//遍历栈
void stack_show(LinkStackPtr S);
//出栈
int stack_pop(LinkStackPtr S);
//销毁栈
void stack_free(LinkStackPtr S);
#endif
源文件
#include "linkstack.h"
//创建栈
LinkStackPtr stack_create()
{
//在堆区申请一个链式栈的大小
LinkStackPtr S = (LinkStackPtr)malloc(sizeof(LinkStack));
if(NULL == S)
{
printf("栈申请失败\n");
return NULL;
}
S->top = (Node *)malloc(sizeof(Node));
if(NULL == S->top)
{
printf("申请失败\n");
free(S);
return NULL;
}
//初始化
S->top->len = 0;
S->top->next = NULL;
printf("创建成功\n");
return S;
}
//判空
int stack_empty(LinkStackPtr S)
{
//判断逻辑
if(NULL != S)
{
return S->top == -1;
}
printf("所给链表不合法\n");
return -1;
}
//入栈
LinkStackPtr stack_push(LinkStackPtr S, datatype e)
{
//判断逻辑
if(NULL==S)
{
printf("入栈失败\n");
return NULL;
}
//申请结点封装数据
LinkListPtr p = (LinkListPtr)malloc(sizeof(Node));
if(NULL == p)
{
printf("结点申请失败\n");
return NULL;
}
//结点申请成功,将数据封装进去
p->data = e;
p->next = S->top;
S->top = p;
S->len++;
printf("入栈成功\n");
return S;
}
//遍历栈
void stack_show(LinkStackPtr S)
{
//判断逻辑
if(NULL==S || stack_empty(S))
{
printf("遍历失败\n");
return ;
}
LinkListPtr q = S->top;
//开始遍历
printf("从栈顶到栈底元素分别是:");
while(q->next != NULL)
{
printf("%d",q->data);
q = q->next;
}
return ;
}
//出栈
int stack_pop(LinkStackPtr S)
{
//判断逻辑
if(NULL==S || stack_empty(S))
{
printf("删除失败\n");
return 0;
}
LinkListPtr q = S->top;
S->top = S->top->next;
printf("%d",p->data);
free(p);
S->top--;
printf("出栈成功\n");
return 1;
}
//销毁栈
void stack_free(LinkStackPtr S)
{
//判断逻辑
if(NULL == S)
{
printf("释放失败\n");
return ;
}
//将所有结点释放
while(!stack_empty(S))
{
free(S);
S = S->next;
}
free(S->next);
S = NULL;
printf("释放成功\n");
}
测试文件
#include "linkstack.h"
int main(int argc, const char *argv[])
{
//创建一个链式栈
LinkStackPtr S = stack_create();
if(NULL == S)
{
return -1;
}
//调用入栈函数
stack_push(S, 2);
//调用遍历函数
stack_show(S);
//调用出栈函数
stack_pop;
//调用释放函数
stack_free(S);
return 0;
}
2、链式队列
头文件
#ifndef _LINKQUEUE_H_
#define _LINKQUEUE_H_
#include <stdio.h>
#include <stdlib.h>
#include <string.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 list_create();
//判空
int list_empty(LinkQueuePtr LQ);
//入队
int list_push(LinkQueuePtr LQ, datatype e);
//出队
int list_pop(LinkQueuePtr LQ);
//遍历队(遍历从Head出发,
int list_show(LinkQueuePtr LQ);
//销毁队
void list_free(LinkQueuePtr LQ);
#endif
源文件
#include "linkqueue.h"
//创建队列
LinkQueuePtr list_create()
{
//创建一个队列
LinkQueuePtr LQ = (LinkQueuePtr)malloc(sizeof(LinkQueue));
if(NULL == LQ)
{
printf("创建失败\n");
return NULL;
}
//创建成功的话,说明里面有两个指针
//LQ->Head LQ->Tail 这两个是野指针
//申请一个链表,将Head指针指向头结点
LQ->Head = (Node *)malloc(sizeof(Node));
if(NULL == LQ->Head)
{
printf("创建失败\n");
return NULL;
}
//成功后需要对链表初始化
LQ->Head->len = 0;
LQ->Head->next = NULL;
//将尾指针指向头结点
LQ->Tail = LQ->Head;
printf("队列创建成功\n");
return LQ;
}
//判空
int list_empty(LinkQueuePtr LQ)
{
//判断逻辑
if(NULL==LQ || NULL==LQ->Head)
{
printf("所给队列不合法\n");
return -1;
}
return LQ->Head == LQ->Tail; //相等为空,不等则不空
}
//入队
int list_push(LinkQueuePtr LQ, datatype e)
{
//判断逻辑
if(NULL == LQ)
{
printf("所给队列不合法\n");
return 0;
}
//1、申请结点封装数据
Node *p = (Node *)malloc(sizeof(Node));
if(NULL == p)
{
printf("入队失败\n");
return 0;
}
//将数据封装到结点中
p->data = e;
p->next = NULL;
//2、将新结点连接到队尾指针指向的结点后面
LQ->Tail->next = p;
//3、更新尾指针
LQ->Tail = p;
//队长变化
LQ->Head->len++;
printf("入队成功\n");
return 1;
}
//出队
int list_pop(LinkQueuePtr LQ)
{
//判断逻辑
if(NULL==LQ || list_empty(LQ));
{
return -1;
}
//1、标记要出队的结点(头删
Node *p = LQ->Head->next;
//2、孤立要出队的结点
LQ->Head->next = p->next;
printf("%d出队成功\n",p->data);
//3、释放要出队的结点
free(p);
p = NULL;
//队长变化
LQ->Head->len--;
//判断队伍中是否已经删除完所有结点
if(LQ->Head->next == NULL)
{
//将尾指针重新指向头结点
LQ->Tail = LQ->Head;
}
return 1;
}
//遍历队
int list_show(LinkQueuePtr LQ)
{
//判断逻辑
if(LQ == NULL||list_empty(LQ))
{
printf("遍历失败!\n");
return 0;
}
//定义一个指针指向第一个结点
Node *p = LQ->Head->next;
//如果p不是最后一个结点进入循环
while(p != LQ->Tail->next)
{
//输出
printf("%d ",p->data);
p = p->next;
}
printf("\n");
return 1;
}
//销毁队
void list_free(LinkQueuePtr LQ)
{
//判断逻辑
if(NULL == LQ)
{
printf("释放失败\n");
return ;
}
//1、释放整个链表
while(!list_empty(LQ))
{
list_pop(LQ);
}
//释放头结点
free(LQ->Head);
LQ->Head = LQ->Tail = NULL;
//2、释放队列
free(LQ);
LQ = NULL;
printf("释放成功\n");
}
测试文件
#include "linkqueue.h"
int main(int argc, const char *argv[])
{
LinkQueuePtr LQ = list_create();
if(NULL == LQ)
{
return -1;
}
//调用入队函数
list_push(LQ, 5);
list_push(LQ, 2);
list_push(LQ, 7);
list_push(LQ, 9);
//调用遍历函数
list_show(LQ);
//调用出队函数
list_pop(LQ);
list_pop(LQ);
list_pop(LQ);
list_pop(LQ);
list_show(LQ);
//调用释放函数
list_free(LQ);
return 0;
}
思维导图