1.栈和队列
栈和队列
栈:栈是限制在一端进行插入操作和删除操作的线性表(俗称堆栈),
允许进行操作的一端称为“栈顶”,另一固定端称为“栈底”,
当栈中没有元素时称为“空栈”。
特点 :后进先出(LIFO)先进后出。
线性表有两种存储方式:顺序存储、链式存储
栈的存储方式:顺序存储、链式存储
称为:顺序栈和链式栈
对栈的操作:
创建、销毁、清空、入栈、出栈、取栈顶元素、判断栈空
顺序栈的特点:
1. 大小固定、连续存储、存储密度高
2. 只能在一端操作,可以使用下标
3. 建议:栈顶在表尾,栈底在表头
例如:顺序栈
定义一个数据结构来描述顺序栈
struct student
{
char name[SIZE];
int age;
};
typedef struct student dataType;
struct stack
{
dataType data[SIZE];
int count;
};
对栈的操作:
创建栈:
和创建顺序表一样
销毁栈
和销毁顺序表一样
清空栈
计数器 = 0
入栈
和顺序表的尾插法一样
出栈
和顺序表的尾删法一样
取栈顶元素
和顺序表的查看表尾元素是一样
判断栈空
if (0 == count)
return TRUE;
else
return FALSE;
判断栈满
if (SIZE == count)
return TRUE;
else
return FALSE;
链式栈(栈的链式存储)
特点:
1. 大小不固定,可以不连续,
2. 访问不方便,从链表的头结点开始访问,
3. 插入和删除不需要移动元素,插入和删除只能在链表的一端进行(在链表的头部进行)
//如果在链表的尾部进行的话,每次找尾结点,比较复杂
定义一个数据结构来描述链式栈
struct student
{
char name[SIZE];
int age;
};
typedef struct student dataType;
struct stack
{
dataType data;
struct stack * pNext;
};
操作:
创建栈:
和创建链表一样
销毁栈
和销毁链表一样
清空栈
使用头删法不停的删除结点,直到链表中只剩头结点为止;头结点的指针域改为NULL。
入栈
和链表的头插法一样
出栈
和链表的头删法一样
取栈顶元素
和链表的查看首结点元素是一样
判断栈空
和判断空链表是一样。
if (NULL == pList->pNext)
return TRUE;
else
return FALSE;
队列 :
头文件:
#ifndef XX
#define XX
常量定义
全局变量声明
类型声明
函数的声明
#endif //XX
源文件:
stack.c
全局变量定义
函数(接口、API)的定义
test.c
接口、API测试
2.顺序栈
Stack.h:
#ifndef _STACK_H_
#define _STACK_H_
//常量定义
#define SIZE 10
typedef enum e_result
{
ERROR = -1,
OK,
FALSE = 0,
TRUE,
}E_RESULT;
//类型申明
typedef int data_type;
typedef unsigned int uInt;
struct Stack
{
data_type data[SIZE];
uInt count;
};
typedef struct Stack STACK;
//全局变量申明
//extern int gIntVal;
//函数的申明
/*
函数名:createSTACK
函数功能:创建线性表
函数参数:无
函数返回值:成功时返回线性表的首地址,失败返回NULL.
*/
STACK * createStack(void);
/*
函数名:destroySTACK
函数功能:销毁线性表
函数参数:STACK * pSTACK 表示要销毁的线性表的首地址
函数返回值:无.
*/
void destroyStack(STACK * pStack);
/*
函数名:insertToSTACK
函数功能:插入一个元素到线性表中
函数参数:
STACK * pSTACK 表示要插入的线性表的首地址
int offset :表示要插入的位置
data_type newItem : 表示要插入的元素的值
函数返回值:成功时返回0,失败返回-1.
*/
int push(STACK * pStack, data_type newItem);
/*
函数名:deleteFromSTACK
函数功能:从线性表中删除一个元素
函数参数:
STACK * pSTACK 表示要操作的线性表的首地址
int offset :表示要删除的位置
data_type * pDelItem : 保存被删除的元素的值
函数返回值:成功时返回0,失败返回-1.
*/
int pop(STACK * const pStack, data_type * pDelItem);
/*
函数名:updateSTACK
函数功能:修改线性表中的一个元素
函数参数:
STACK * pSTACK 表示要操作的线性表的首地址
int offset :表示要修改的位置
data_type newValue : 修改后元素的值
函数返回值:成功时返回0,失败返回-1.
*/
int updateStack(STACK * const pStack, data_type newValue);
/*
函数名:searchItemFormSTACK
函数功能:从线性表中查找和指定元素相等的元素,返回第一次出现的位置
函数参数:
STACK * pSTACK 表示要操作的线性表的首地址
data_type item : 被查找的元素的值
函数返回值:成功时返回下标,失败返回-1.
*/
int getDataFromStack(STACK * const pStack, data_type * pTopitem);
int isFull(STACK * pStack);
int isEmpty(STACK * pStack);
int clearStack(STACK * pStack);
#endif // _STACK_H_
Stack.c:
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "Stack.h"
/*
函数名:createStack
函数功能:创建栈
函数参数:无
函数返回值:成功时返回栈的首地址,失败返回NULL.
*/
STACK * createStack(void)
{
STACK * pStack = NULL;
pStack = (STACK *)malloc(sizeof(STACK));
if (NULL != pStack)
{
memset(pStack, 0, sizeof(STACK));
pStack->count = 0; //表是空的
}
return pStack;
}
/*
函数名:destroyStack
函数功能:销毁栈
函数参数:STACK * pStack 表示要销毁的栈的首地址
函数返回值:无.
*/
void destroyStack(STACK * pStack)
{
if (NULL == pStack)
return ;
free(pStack);
pStack = NULL;
}
/*
函数名:clearStack
函数功能:清空栈
函数参数:STACK * pStack 表示要清空的栈的首地址
函数返回值:成功时返回0,失败返回-1.
*/
int clearStack(STACK * pStack)
{
if (NULL == pStack)
{
return ERROR;
}
else
{
0 == pStack->count;
return OK;
}
}
/*
函数名:push
函数功能:插入一个元素到栈中
函数参数:
STACK * pSTACK 表示要插入的栈的首地址
data_type newItem : 表示要插入的元素的值
函数返回值:成功时返回0,失败返回-1.
*/
int push(STACK * const pStack, data_type newItem)
{
int i = 0;
//参数判断
if (NULL == pStack)
{
printf("参数不对\r\n");
return ERROR;
}
//表是否为满
if (SIZE == pStack->count)
{
printf("栈满\r\n");
return ERROR;
}
pStack->data[pStack->count] = newItem;
//更新计数器
pStack->count++;
return OK;
}
/*
函数名:pop
函数功能:从栈中删除一个元素
函数参数:
STACK * pSTACK 表示要操作的栈的首地址
data_type * pDelItem : 保存被删除的元素的值
函数返回值:成功时返回0,失败返回-1.
*/
int pop(STACK * const pStack, data_type * pDelItem)
{
int i = 0;
//判断参数
if (NULL == pStack)
{
printf("参数不对\r\n");
return ERROR;
}
//保存被删除的元素的值
if (NULL != pDelItem)
{
*pDelItem = pStack->data[pStack->count-1];
}
//更新计数器
pStack->count--;
return OK;
}
/*
函数名:updateStack
函数功能:修改栈中的一个元素
函数参数:
STACK * pStack 表示要操作的栈的首地址
int offset :表示要修改的位置
data_type newValue : 修改后元素的值
函数返回值:成功时返回0,失败返回-1.
*/
int updateStack(STACK * const pStack, data_type newValue)
{
if (NULL == pStack)
{
return ERROR;
}
pStack->data[pStack->count-1] = newValue;
return OK;
}
/*
函数名:getDataFormSTACK
函数功能:查看栈顶元素
函数参数:
STACK * pSTACK 表示要操作的栈的首地址
data_type item : 被查找的元素的值
函数返回值:成功时返回下标,失败返回-1.
*/
int getDataFromStack(STACK * const pStack, data_type * pTopItem)
{
int i = 0;
if (NULL == pStack)
{
printf("当前栈不存在\r\n");
return ERROR;
}
if (0 == pStack->count)
{
printf("当前栈是空栈\r\n");
return ERROR;
}
if (NULL != pTopItem)
{
*pTopItem = pStack->data[pStack->count-1];
return OK;
}
}
//如果栈满,返回1,如果栈不满,返回0,如果表不存在-1;
/*
函数名:isFull
函数功能:判断栈是否为满
函数参数:
STACK * pStack 表示要判断的栈的首地址
函数返回值:栈满返回1,栈不满返回0. 栈不存在返回-1.
*/
int isFull(STACK * pStack)
{
if (NULL == pStack)
return ERROR;
if (SIZE == pStack->count)
return TRUE;
else
return FALSE;
}
/*
函数名:isEmpty
函数功能:判断栈是否为空
函数参数:
STACK * pStack 表示要判断的栈的首地址
函数返回值:栈空返回1,栈不空返回0. 栈不存在返回-1.
*/
int isEmpty(STACK * pStack)
{
if (NULL == pStack)
{
return ERROR;
}
if (0 == pStack->count)
return TRUE;
else
return FALSE;
}
test.c:
#include <stdio.h>
#include "Stack.h"
int main()
{
STACK * pStack = NULL;
data_type * pDelItem;
data_type data;
int ret1 = 0;
int ret2 = 0;
//创建栈
pStack = createStack();
if (NULL == pStack)
{
printf("栈创建失败\r\n");
return ERROR;
}
//插入数据
push(pStack, 1);
push(pStack, 3);
push(pStack, 5);
push(pStack, 4); // 1,4,3,5
//取出栈顶元素
if (OK == getDataFromStack(pStack, &data))
{
printf("top value =%d\r\n", data );
}
updateStack(pStack, 12);
//取出栈顶元素
if (OK == getDataFromStack(pStack, &data))
{
printf("top value =%d\r\n", data );
}
//判断栈是否为空
ret1 = isEmpty(pStack);
if (TRUE == ret1)
{
printf("空栈\r\n");
}
else if (FALSE == ret1)
{
printf("不是空栈\r\n");
}
else
printf("出错\r\n");
//判断栈是否为满
ret2 = isFull(pStack);
if (TRUE == ret2)
{
printf("满栈\r\n");
}
else if (FALSE == ret2)
{
printf("不是满栈\r\n");
}
else
printf("出错\r\n");
//出栈
if (OK == pop(pStack, &data))
{
printf("出栈 value : %d\r\n", data);
}
if (OK == pop(pStack, &data))
{
printf("出栈 value : %d\r\n", data);
}
if (OK == pop(pStack, &data))
{
printf("出栈 value : %d\r\n", data);
}
if (OK == pop(pStack, &data))
{
printf("出栈 value : %d\r\n", data);
}
//判断栈是否为空
ret2 = isEmpty(pStack);
if (TRUE == ret2)
{
printf("空栈\r\n");
}
else if (FALSE == ret2)
{
printf("不是空栈\r\n");
}
else
printf("出错\r\n");
//销毁栈
destroyStack(pStack);
return 0;
}
输出结果:
top value =4
top value =12
不是空栈
不是满栈
出栈 value : 12
出栈 value : 5
出栈 value : 3
出栈 value : 1
空栈
3.链式栈
stack.h:
#ifndef _STACK_H_
#define _STACK_H_
//常量定义
typedef enum e_result
{
ERROR = -1,
OK,
FALSE = 0,
TRUE,
}E_RESULT;
//类型申明
typedef int data_type;
struct stack
{
data_type data;
struct stack * pNext;
};
typedef struct stack STACK;
//全局变量申明
//extern int gIntVal;
//函数的申明
/*
函数名:createStack
函数功能:创建栈
函数参数:无
函数返回值:成功时返回栈的首地址,失败返回NULL.
*/
STACK * createStack(void);
/*
函数名:destroyStack
函数功能:销毁栈
函数参数:STACK * pStack 表示要销毁的栈的首地址
函数返回值:无.
*/
void destroyStack(STACK * pStack);
/*
函数名:push
函数功能:插入一个元素到栈中
函数参数:
STACK * pStack 表示要插入的栈的首地址
data_type newItem : 表示要插入的元素的值
函数返回值:成功时返回0,失败返回-1.
*/
int push(STACK * pStack, data_type newItem);
/*
函数名:pop
函数功能:从栈中删除一个元素
函数参数:
STACK * pStack 表示要操作的栈的首地址
data_type * pDelItem : 保存被出栈的元素的值
函数返回值:成功时返回0,失败返回-1.
*/
int pop(STACK * pStack, data_type * pDelItem);
/*
函数名:updateStack
函数功能:修改栈顶元素
函数参数:
STACK * pStack 表示要操作的栈的首地址
data_type newValue : 修改后元素的值
函数返回值:成功时返回0,失败返回-1.
*/
int updateStack(STACK * pStack, data_type newValue);
/*
函数名:getDataFromStack
函数功能:查看栈顶元素
函数参数:
STACK * pStack 表示要操作的栈的首地址
data_type * pTopItem : 栈顶元素的值
函数返回值:成功时返回0,失败返回-1.
*/
int getDataFromStack(const STACK * pStack, data_type * pTopItem);
/*
函数名:isEmpty
函数功能:判断栈是否为空
函数参数:
STACK * pStack 表示要判断的栈的首地址
函数返回值:栈空返回1,栈不空返回0.
*/
int isEmpty(const STACK * pStack);
#endif // _STACK_H_
stack.c:
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include "stack.h"
/*
函数名:createStack
函数功能:创建栈
函数参数:无
函数返回值:成功时返回栈的首地址,失败返回NULL.
*/
STACK * createStack(void)
{
STACK * pStack = NULL;
pStack = (STACK *)malloc(sizeof(STACK));
if (NULL != pStack)
{
memset(pStack, 0, sizeof(STACK));
}
return pStack;
}
/*
函数名:destroyStack
函数功能:销毁栈
函数参数:STACK * pStack 表示要销毁的栈的首地址
函数返回值:无.
*/
void destroyStack(STACK * pStack)
{
STACK * pDel = NULL;
if (NULL == pStack)
{
return ;
}
//给pDel赋值,赋值为首结点
pDel = pStack->pNext;
while (NULL != pDel)
{
//保护pDel后面的结点
pStack->pNext = pDel->pNext;
//释放pDel
free(pDel);
//重新给pDel赋值,赋值为首结点
pDel = pStack->pNext;
}
free(pStack);
pStack = NULL;
}
/*
函数名:push
函数功能:插入一个元素到栈中
函数参数:
STACK * pStack 表示要插入的栈的首地址
data_type newItem : 表示要插入的元素的值
函数返回值:成功时返回0,失败返回-1.
*/
int push(STACK * pStack, data_type newItem)
{
STACK * pNew = NULL;
//参数判断
if (NULL == pStack)
{
printf("当前的栈不存在 \r\n");
return ERROR;
}
//申请新结点
pNew = (STACK *)malloc(sizeof(STACK));
if (NULL == pNew)
{
return ERROR;
}
memset(pNew, 0, sizeof(STACK));
pNew->data = newItem;
//头插法
//先找到插入位置的前一个结点:pStack
//保护pStack后面的所有结点
pNew->pNext = pStack->pNext;
//pStack指向新结点
pStack->pNext = pNew;
return OK;
}
/*
函数名:pop
函数功能:从栈中删除一个元素
函数参数:
STACK * pStack 表示要操作的栈的首地址
data_type * pDelItem : 保存被出栈的元素的值
函数返回值:成功时返回0,失败返回-1.
*/
int pop(STACK * pStack, data_type * pDelItem)
{
STACK * pDel = NULL;
//判断参数(有没有栈,栈是否为空)
if (NULL == pStack)
{
printf("当前的栈不存在 \r\n");
return ERROR;
}
if (NULL == pStack->pNext)
{
printf("当前的栈是空栈 \r\n");
return ERROR;
}
//先找到要删除的结点pDel的前一个结点pStack
pDel = pStack->pNext;
//保护pDel后面的结点
pStack->pNext = pDel->pNext;
//给*pDelItem赋值
if (NULL != pDelItem)
{
*pDelItem = pDel->data;
}
//释放pDel
free(pDel);
pDel = NULL;
return OK;
}
/*
函数名:updateStack
函数功能:修改栈顶元素
函数参数:
STACK * pStack 表示要操作的栈的首地址
data_type newValue : 修改后元素的值
函数返回值:成功时返回0,失败返回-1.
*/
int updateStack(STACK * pStack, data_type newValue)
{
STACK * pTmp = NULL;
//判断参数(有没有栈,栈是否为空)
if (NULL == pStack)
{
printf("当前的栈不存在 \r\n");
return ERROR;
}
if (NULL == pStack->pNext)
{
printf("当前的栈是空栈 \r\n");
return ERROR;
}
//找到要改的结点pTmp
pTmp = pStack->pNext;
//修改
pTmp->data = newValue;
return OK;
}
/*
函数名:getDataFromStack
函数功能:查看栈顶元素
函数参数:
STACK * pStack 表示要操作的栈的首地址
data_type * pTopItem : 栈顶元素的值
函数返回值:成功时返回0,失败返回-1.
*/
int getDataFromStack(const STACK * pStack, data_type * pTopItem)
{
STACK * pTmp = NULL;
//判断参数(有没有栈,栈是否为空)
if (NULL == pStack)
{
printf("当前的栈不存在 \r\n");
return ERROR;
}
if (NULL == pStack->pNext)
{
printf("当前的栈是空栈 \r\n");
return ERROR;
}
if (NULL == pTopItem)
{
printf("参数pTmpItem错误\r\n");
return ERROR;
}
//找到栈顶元素pTmp
pTmp = pStack->pNext;
//取栈顶元素的值
*pTopItem = pTmp->data;
return OK;
}
/*
函数名:isEmpty
函数功能:判断栈是否为空
函数参数:
STACK * pStack 表示要判断的栈的首地址
函数返回值:栈空返回1,栈不空返回0. 栈不存在返回-1.
*/
int isEmpty(const STACK * pStack)
{
//判断参数(有没有栈,栈是否为空)
if (NULL == pStack)
{
printf("当前的栈不存在 \r\n");
return ERROR;
}
if (NULL == pStack->pNext)
{
printf("当前的栈是空栈 \r\n");
return TRUE;
}
return FALSE;
}
test.c:
#include <stdio.h>
#include "stack.h"
int main()
{
STACK * pStack = NULL;
data_type data;
int ret = 0;
//创建栈
pStack = createStack();
if (NULL == pStack)
{
printf("创建栈失败\r\n");
return -1;
}
//入栈
push(pStack, 1);
push(pStack, 2);
push(pStack, 3);
//取出栈顶元素
if (OK == getDataFromStack(pStack, &data))
{
printf("top value : %d\r\n", data);
}
updateStack(pStack, 33);
//取出栈顶元素
if (OK == getDataFromStack(pStack, &data))
{
printf("top value : %d\r\n", data);
}
//判断栈是否为空
ret = isEmpty(pStack);
if (TRUE == ret)
{
printf("空栈\r\n");
}
else if (FALSE == ret)
{
printf("不是空栈\r\n");
}
else
printf("出错\r\n");
//出栈
if (OK == pop(pStack, &data))
{
printf("出栈 value : %d\r\n", data);
}
if (OK == pop(pStack, &data))
{
printf("出栈 value : %d\r\n", data);
}
if (OK == pop(pStack, &data))
{
printf("出栈 value : %d\r\n", data);
}
if (OK != pop(pStack, &data))
{
printf("空栈 \r\n");
}
//销毁栈
destroyStack(pStack);
return 0;
}
输出结果:
top value : 3
top value : 33
不是空栈
出栈 value : 33
出栈 value : 2
出栈 value : 1
当前的栈是空栈
空栈
4.顺序队列
queue.h:
#ifndef _QUEUE_H_
#define _QUEUE_H_
#define SIZE 10
//常量定义
typedef enum e_result
{
ERROR = -1,
OK,
FALSE = 0,
TRUE,
}E_RESULT;
//类型申明
typedef int data_type;
struct Queue
{
data_type data[SIZE];
int count;
};
typedef struct Queue QUEUE;
//全局变量申明
//extern int gIntVal;
//函数的申明
/*
函数名:createQueue
函数功能:创建队列
函数参数:无
函数返回值:成功时返回队列的首地址,失败返回NULL.
*/
QUEUE * createQueue(void);
/*
函数名:destroyQueue
函数功能:销毁队列
函数参数:QUEUE * pQueue 表示要销毁的队列的首地址
函数返回值:无.
*/
void destroyQueue(QUEUE * pQueue);
/*
函数名:push
函数功能:插入一个元素到队列中
函数参数:
QUEUE * pQueue 表示要插入的队列的首地址
data_type newItem : 表示要插入的元素的值
函数返回值:成功时返回0,失败返回-1.
*/
int push(QUEUE * pQueue, data_type newItem);
/*
函数名:pop
函数功能:从队列中删除一个元素
函数参数:
QUEUE * pQueue 表示要操作的队列的首地址
data_type * pDelItem : 保存被出队列的元素的值
函数返回值:成功时返回0,失败返回-1.
*/
int pop(QUEUE * pQueue, data_type * pDelItem);
/*
函数名:updateQueue
函数功能:修改队列首元素
函数参数:
QUEUE * pQueue 表示要操作的队列的首地址
data_type newValue : 修改后元素的值
函数返回值:成功时返回0,失败返回-1.
*/
int updateQueue(QUEUE * pQueue, data_type newValue);
/*
函数名:getDataFromQueue
函数功能:查看队列首元素
函数参数:
QUEUE * pQueue 表示要操作的队列的首地址
data_type * pTopItem : 队列顶元素的值
函数返回值:成功时返回0,失败返回-1.
*/
int getDataFromQueue(const QUEUE * pQueue, data_type * pTopItem);
/*
函数名:isEmpty
函数功能:判断队列是否为空
函数参数:
QUEUE * pQueue 表示要判断的队列的首地址
函数返回值:队列空返回1,队列不空返回0.
*/
int isEmpty(const QUEUE * pQueue);
#endif // _QUEUE_H_
queue.c:
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include "queue.h"
/*
函数名:createQueue
函数功能:创建队列
函数参数:无
函数返回值:成功时返回队列的首地址,失败返回NULL.
*/
QUEUE * createQueue(void)
{
QUEUE * pQueue = NULL;
pQueue = (QUEUE *)malloc(sizeof(QUEUE));
if (NULL != pQueue)
{
memset(pQueue, 0, sizeof(QUEUE));
pQueue->count = 0;
}
return pQueue;
}
/*
函数名:destroyQueue
函数功能:销毁队列
函数参数:QUEUE * pQueue 表示要销毁的队列的首地址
函数返回值:无.
*/
void destroyQueue(QUEUE * pQueue)
{
if (NULL == pQueue)
{
return ;
}
free(pQueue);
pQueue = NULL;
}
/*
函数名:push
函数功能:插入一个元素到队列中
函数参数:
QUEUE * pQueue 表示要插入的队列的首地址
data_type newItem : 表示要插入的元素的值
函数返回值:成功时返回0,失败返回-1.
*/
int push(QUEUE * pQueue, data_type newItem)
{
//参数判断
if (NULL == pQueue)
{
printf("当前的队列不存在 \r\n");
return ERROR;
}
if(SIZE == pQueue->count)
{
printf("队列满\n");
return ERROR;
}
pQueue->data[pQueue->count++] = newItem;
return OK;
}
/*
函数名:pop
函数功能:从队列中删除一个元素
函数参数:
QUEUE * pQueue 表示要操作的队列的首地址
data_type * pDelItem : 保存被出队列的元素的值
函数返回值:成功时返回0,失败返回-1.
*/
int pop(QUEUE * pQueue, data_type * pDelItem)
{
int i = 0;
//判断参数(有没有队列,队列是否为空)
if (NULL == pQueue)
{
printf("当前的队列不存在 \r\n");
return ERROR;
}
if (0 == pQueue->count)
{
printf("当前的队列是空队列 \r\n");
return ERROR;
}
if(NULL == pDelItem)
{
printf("pDelItem错误\n");
return ERROR;
}
*pDelItem = pQueue->data[0];
for(i = 0; i < pQueue->count - 1;i++)
{
pQueue->data[i] = pQueue->data[i + 1];
}
pQueue->count--;
return OK;
}
/*
函数名:updateQueue
函数功能:修改队列首元素
函数参数:
QUEUE * pQueue 表示要操作的队列的首地址
data_type newValue : 修改后元素的值
函数返回值:成功时返回0,失败返回-1.
*/
int updateQueue(QUEUE * pQueue, data_type newValue)
{
//判断参数(有没有队列,队列是否为空)
if (NULL == pQueue)
{
printf("当前的队列不存在 \r\n");
return ERROR;
}
if (0 == pQueue->count)
{
printf("当前的队列是空队列 \r\n");
return ERROR;
}
//修改
pQueue->data[0] = newValue;
return OK;
}
/*
函数名:getDataFromQueue
函数功能:查看队列首元素
函数参数:
QUEUE * pQueue 表示要操作的队列的首地址
data_type * pTopItem : 队列顶元素的值
函数返回值:成功时返回0,失败返回-1.
*/
int getDataFromQueue(const QUEUE * pQueue, data_type * pTopItem)
{
//判断参数(有没有队列,队列是否为空)
if (NULL == pQueue)
{
printf("当前的队列不存在 \r\n");
return ERROR;
}
if (0 == pQueue->count)
{
printf("当前的队列是空队列 \r\n");
return ERROR;
}
if (NULL == pTopItem)
{
printf("参数pTmpItem错误\r\n");
return ERROR;
}
//取队列顶元素的值
*pTopItem = pQueue->data[0];
return OK;
}
/*
函数名:isEmpty
函数功能:判断队列是否为空
函数参数:
QUEUE * pQueue 表示要判断的队列的首地址
函数返回值:队列空返回1,队列不空返回0. 队列不存在返回-1.
*/
int isEmpty(const QUEUE * pQueue)
{
//判断参数(有没有队列,队列是否为空)
if (NULL == pQueue)
{
printf("当前的队列不存在 \r\n");
return ERROR;
}
if (0 == pQueue->count)
{
printf("当前的队列是空队列 \r\n");
return TRUE;
}
return FALSE;
}
test.c:
#include <stdio.h>
#include "queue.h"
int main()
{
QUEUE * pQueue = NULL;
data_type data;
int ret = 0;
//创建队
pQueue = createQueue();
if (NULL == pQueue)
{
printf("创建队失败\r\n");
return -1;
}
//入队
push(pQueue, 1);
push(pQueue, 2);
push(pQueue, 3);
//取出队首元素
if (OK == getDataFromQueue(pQueue, &data))
{
printf("top value : %d\r\n", data);
}
updateQueue(pQueue, 33);
//取出队首元素
if (OK == getDataFromQueue(pQueue, &data))
{
printf("top value : %d\r\n", data);
}
//判断队是否为空
ret = isEmpty(pQueue);
if (TRUE == ret)
{
printf("空队\r\n");
}
else if (FALSE == ret)
{
printf("不是空队\r\n");
}
else
printf("出错\r\n");
//出队
if (OK == pop(pQueue, &data))
{
printf("出队 value : %d\r\n", data);
}
if (OK == pop(pQueue, &data))
{
printf("出队 value : %d\r\n", data);
}
if (OK == pop(pQueue, &data))
{
printf("出队 value : %d\r\n", data);
}
if (OK != pop(pQueue, &data))
{
printf("空队 \r\n");
}
//销毁队
destroyQueue(pQueue);
return 0;
}
输出结果:
top value : 1
top value : 33
不是空队
出队 value : 33
出队 value : 2
出队 value : 3
当前的队列是空队列
空队
5.链式队列
queque.h:
#ifndef _QUEUE_H_
#define _QUEUE_H_
//常量定义
typedef enum e_result
{
ERROR = -1,
OK,
FALSE = 0,
TRUE,
}E_RESULT;
//类型申明
typedef int data_type;
struct queue
{
data_type data;
struct queue * pNext;
};
typedef struct queue QUEUE;
//全局变量申明
//extern int gIntVal;
//函数的申明
/*
函数名:createQueue
函数功能:创建队
函数参数:无
函数返回值:成功时返回队的首地址,失败返回NULL.
*/
QUEUE * createQueue(void);
/*
函数名:destroyQueue
函数功能:销毁队
函数参数:QUEUE * pQueue 表示要销毁的队的首地址
函数返回值:无.
*/
void destroyQueue(QUEUE * pQueue);
/*
函数名:push
函数功能:插入一个元素到队中
函数参数:
QUEUE * pQueue 表示要插入的队的首地址
data_type newItem : 表示要插入的元素的值
函数返回值:成功时返回0,失败返回-1.
*/
int push(QUEUE * pQueue, data_type newItem);
/*
函数名:pop
函数功能:从队中删除一个元素
函数参数:
QUEUE * pQueue 表示要操作的队的首地址
data_type * pDelItem : 保存被出队的元素的值
函数返回值:成功时返回0,失败返回-1.
*/
int pop(QUEUE * pQueue, data_type * pDelItem);
/*
函数名:updateQueue
函数功能:修改队顶元素
函数参数:
QUEUE * pQueue 表示要操作的队的首地址
data_type newValue : 修改后元素的值
函数返回值:成功时返回0,失败返回-1.
*/
int updateQueue(QUEUE * pQueue, data_type newValue);
/*
函数名:getDataFromQueue
函数功能:查看队顶元素
函数参数:
QUEUE * pQueue 表示要操作的队的首地址
data_type * pTopItem : 队顶元素的值
函数返回值:成功时返回0,失败返回-1.
*/
int getDataFromQueue(const QUEUE * pQueue, data_type * pTopItem);
/*
函数名:isEmpty
函数功能:判断队是否为空
函数参数:
QUEUE * pQueue 表示要判断的队的首地址
函数返回值:队空返回1,队不空返回0.
*/
int isEmpty(const QUEUE * pQueue);
#endif // _QUEUE_H_
queue.c:
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include "queue.h"
/*
函数名:createQueue
函数功能:创建队
函数参数:无
函数返回值:成功时返回队的首地址,失败返回NULL.
*/
QUEUE * createQueue(void)
{
QUEUE * pQueue = NULL;
pQueue = (QUEUE *)malloc(sizeof(QUEUE));
if (NULL != pQueue)
{
memset(pQueue, 0, sizeof(QUEUE));
}
return pQueue;
}
/*
函数名:destroyQueue
函数功能:销毁队
函数参数:QUEUE * pQueue 表示要销毁的队的首地址
函数返回值:无.
*/
void destroyQueue(QUEUE * pQueue)
{
QUEUE * pDel = NULL;
if (NULL == pQueue)
{
return ;
}
//给pDel赋值,赋值为首结点
pDel = pQueue->pNext;
while (NULL != pDel)
{
//保护pDel后面的结点
pQueue->pNext = pDel->pNext;
//释放pDel
free(pDel);
//重新给pDel赋值,赋值为首结点
pDel = pQueue->pNext;
}
free(pQueue);
pQueue = NULL;
}
/*
函数名:push
函数功能:插入一个元素到队中
函数参数:
QUEUE * pQueue 表示要插入的队的首地址
data_type newItem : 表示要插入的元素的值
函数返回值:成功时返回0,失败返回-1.
*/
int push(QUEUE * pQueue, data_type newItem)
{
QUEUE * pNew = NULL;
QUEUE * pTmp = NULL;
//参数判断
if (NULL == pQueue)
{
printf("当前的队不存在 \r\n");
return ERROR;
}
//申请新结点
pNew = (QUEUE *)malloc(sizeof(QUEUE));
if (NULL == pNew)
{
return ERROR;
}
memset(pNew, 0, sizeof(QUEUE));
pNew->data = newItem;
//尾插法
pTmp = pQueue;
//先找到插入位置的前一个结点:pTmp
while(NULL != pTmp->pNext)
{
pTmp = pTmp->pNext;
}
//保护pQueue后面的所有结点
pNew->pNext = pTmp->pNext;
//pQueue指向新结点
pTmp->pNext = pNew;
return OK;
}
/*
函数名:pop
函数功能:从队中删除一个元素
函数参数:
QUEUE * pQueue 表示要操作的队的首地址
data_type * pDelItem : 保存被出队的元素的值
函数返回值:成功时返回0,失败返回-1.
*/
int pop(QUEUE * pQueue, data_type * pDelItem)
{
QUEUE * pDel = NULL;
//判断参数(有没有队,队是否为空)
if (NULL == pQueue)
{
printf("当前的队不存在 \r\n");
return ERROR;
}
if (NULL == pQueue->pNext)
{
printf("当前的队是空队 \r\n");
return ERROR;
}
//先找到要删除的结点pDel的前一个结点pQueue
pDel = pQueue->pNext;
//保护pDel后面的结点
pQueue->pNext = pDel->pNext;
//给*pDelItem赋值
if (NULL != pDelItem)
{
*pDelItem = pDel->data;
}
//释放pDel
free(pDel);
pDel = NULL;
return OK;
}
/*
函数名:updateQueue
函数功能:修改队首元素
函数参数:
QUEUE * pQueue 表示要操作的队的首地址
data_type newValue : 修改后元素的值
函数返回值:成功时返回0,失败返回-1.
*/
int updateQueue(QUEUE * pQueue, data_type newValue)
{
QUEUE * pTmp = NULL;
//判断参数(有没有队,队是否为空)
if (NULL == pQueue)
{
printf("当前的队不存在 \r\n");
return ERROR;
}
if (NULL == pQueue->pNext)
{
printf("当前的队是空队 \r\n");
return ERROR;
}
//找到要改的结点pTmp
pTmp = pQueue->pNext;
//修改
pTmp->data = newValue;
return OK;
}
/*
函数名:getDataFromQueue
函数功能:查看队首元素
函数参数:
QUEUE * pQueue 表示要操作的队的首地址
data_type * pTopItem : 队顶元素的值
函数返回值:成功时返回0,失败返回-1.
*/
int getDataFromQueue(const QUEUE * pQueue, data_type * pTopItem)
{
QUEUE * pTmp = NULL;
//判断参数(有没有队,队是否为空)
if (NULL == pQueue)
{
printf("当前的队不存在 \r\n");
return ERROR;
}
if (NULL == pQueue->pNext)
{
printf("当前的队是空队 \r\n");
return ERROR;
}
if (NULL == pTopItem)
{
printf("参数pTmpItem错误\r\n");
return ERROR;
}
//找到队首元素pTmp
pTmp = pQueue->pNext;
//取队首元素的值
*pTopItem = pTmp->data;
return OK;
}
/*
函数名:isEmpty
函数功能:判断队是否为空
函数参数:
QUEUE * pQueue 表示要判断的队的首地址
函数返回值:队空返回1,队不空返回0. 队不存在返回-1.
*/
int isEmpty(const QUEUE * pQueue)
{
//判断参数(有没有队,队是否为空)
if (NULL == pQueue)
{
printf("当前的队不存在 \r\n");
return ERROR;
}
if (NULL == pQueue->pNext)
{
printf("当前的队是空队 \r\n");
return TRUE;
}
return FALSE;
}
test.c:
#include <stdio.h>
#include "queue.h"
int main()
{
QUEUE * pQueue = NULL;
data_type data;
int ret = 0;
//创建队
pQueue = createQueue();
if (NULL == pQueue)
{
printf("创建队失败\r\n");
return -1;
}
//入队
push(pQueue, 1);
push(pQueue, 2);
push(pQueue, 3);
//取出队首元素
if (OK == getDataFromQueue(pQueue, &data))
{
printf("top value : %d\r\n", data);
}
updateQueue(pQueue, 22);
//取出队首元素
if (OK == getDataFromQueue(pQueue, &data))
{
printf("top value : %d\r\n", data);
}
//判断队是否为空
ret = isEmpty(pQueue);
if (TRUE == ret)
{
printf("空队\r\n");
}
else if (FALSE == ret)
{
printf("不是空队\r\n");
}
else
printf("出错\r\n");
//出队
if (OK == pop(pQueue, &data))
{
printf("出队 value : %d\r\n", data);
}
if (OK == pop(pQueue, &data))
{
printf("出队 value : %d\r\n", data);
}
if (OK == pop(pQueue, &data))
{
printf("出队 value : %d\r\n", data);
}
if (OK != pop(pQueue, &data))
{
printf("空队 \r\n");
}
//销毁队
destroyQueue(pQueue);
return 0;
}
输出结果:
top value : 1
top value : 22
不是空队
出队 value : 22
出队 value : 2
出队 value : 3
当前的队是空队
空队