1.队列的链式存储
1.1 实现方法:
- 队列与栈的区别在于:队列的规则是先进先出。
- 定义企业级链表的方式来实现
/*节点结构体*/
typedef struct LinkNode
{
struct LinkNode* next;
}LinkNode;
/*链式队列结构体*/
typedef struct listQueue
{
LinkNode pHeader;
int m_size;
}listQueue;
- 为了避免用户通过链表地址而对链表进行操作,需要封装创建的链表数据类型。
(1)void*类型是万能类型,可以将任何类型转为void*
,需要使用时可将void*
类型转回为已知类型。
typedef void* Lqueue;
1.2 初始化栈
- 申请栈空间;
- 初始化队中的头节点和队大小;
- 将类型封装后的申请的队地址返回。
/*初始化栈*/
/*初始化队列*/
Lqueue init_listQueue()
{
listQueue* queue = malloc(sizeof(listQueue));
queue->m_size = 0;
queue->pHeader.next = NULL;
return queue;
}
1.3 入队
本质就是头插或者尾插节点。
- 将封装的队地址的类型转为原类型;
- 取出用户数据中的前四字节的指针域;
- 判断当前的队是否已满:
(1)若已满则返回;
(2)若未满则头插; - 更新队的大小
void push_listQueue(Lqueue pQueue, void* pData)
{
if (pQueue == NULL)
{
return;
}
listQueue* queue = pQueue;
LinkNode* data = pData;
if (queue->m_size == MAX)
{
return;
}
//1.入队
data->next = queue->pHeader.next;
queue->pHeader.next = data;
queue->m_size++;
}
1.4 出队
本质就是头删或者尾删节点。
- 将封装的队地址的类型转为原类型;
- 取出用户数据中的前四字节的指针域;
- 判断当前的队是否为空:
(1)若已空则返回;
(2)若未空则头删; - 更新队的大小
/*出栈:头删*/
void pop_listQueue(Lqueue pQueue)
{
if (pQueue == NULL)
{
return;
}
listQueue* queue = pQueue;
if (queue->m_size == 0)
{
return;
}
LinkNode* pCurrent = &queue->pHeader;
for (int i = 0; i < queue->m_size; i++)
{
pCurrent = pCurrent->next;
}
pCurrent->next = NULL;
queue->m_size--;
}
1.5 获取队头和队尾元素
void* front_listQueue(Lqueue pQueue)
{
if (pQueue == NULL)
{
return NULL;
}
listQueue* queue = pQueue;
if (queue->m_size == 0);
{
printf("queue->m_size = %d\n", queue->m_size);
return NULL;
}
return queue->pHeader.next;
}
/*获取队尾*/
void* back_listQueue(Lqueue pQueue)
{
if (pQueue == NULL)
{
return NULL;
}
listQueue* queue = pQueue;
if (queue->m_size == 0);
{
return NULL;
}
LinkNode* pCurrent = &queue->pHeader;
for (int i = 0; i < queue->m_size; i++)
{
pCurrent = pCurrent->next;
}
return pCurrent;
}
1.6 判断队列是否为空
- 直接判断链表结构体中的链表大小是否是0;
/*判断是否为空*/
int empty_listQueue(Lqueue pQueue)
{
if (pQueue == NULL)
{
return -1;
}
listQueue* queue = pQueue;
if (queue->m_size == 0)
{
return 1;
}
return 0;
}
/*返回大小*/
int size_listQueue(Lqueue pQueue)
{
if (pQueue == NULL)
{
return 0;
}
listQueue* queue = pQueue;
return queue->m_size;
}
1.7 销毁队列
- 释放栈的空间
- 注意不能释放节点空间,因为节点中的数据域是用户的数据。
/*销毁队列*/
void destory_listQueue(Lqueue pQueue)
{
if (pQueue == NULL)
{
return;
}
free(pQueue);
pQueue = NULL;
}
2.栈的顺序存储
/*定义数组队列结构体*/
typedef struct arrayQueue
{
void** arr;
int m_size;
}arrayQueue;
typedef void* aQueue;
/*初始化队列*/
aQueue init_arrayQueue()
{
arrayQueue* Queue = malloc(sizeof(arrayQueue));
if (Queue == NULL)
{
return NULL;
}
Queue->arr = malloc(sizeof(void*) * Max);
if (Queue->arr == NULL)
{
return NULL;
}
memset(Queue->arr, 0, sizeof(void*) * Max);
Queue->m_size = 0;
return Queue;
}
/*插入队列:尾插*/
void push_arrayQueue(aQueue pQueue, void* data)
{
if (pQueue == NULL)
{
return;
}
arrayQueue* queue = pQueue;
if (queue->m_size == Max)
{
return;
}
queue->arr[queue->m_size] = data;
queue->m_size++;
}
/*出队:头删*/
void pop_arrayQueue(aQueue pQueue)
{
if (pQueue == NULL)
{
return;
}
arrayQueue* queue = pQueue;
if (queue->m_size == 0)
{
return;
}
for (int i = 0; i < queue->m_size; i++)
{
queue->arr[i] = queue->arr[i + 1];
}
queue->m_size--;
}
/*获取队顶*/
void* front_arrayQueue(aQueue pQueue)
{
if (pQueue == NULL)
{
return;
}
arrayQueue* queue = pQueue;
if (queue->m_size == 0)
{
return NULL;
}
return queue->arr[0];
}
/*获取队尾*/
void* back_arrayQueue(aQueue pQueue)
{
if (pQueue == NULL)
{
return;
}
arrayQueue* queue = pQueue;
if (queue->m_size == 0)
{
return NULL;
}
return queue->arr[queue->m_size-1];
}
/*返回队列大小*/
int size_arrayQueue(aQueue pQueue)
{
if (pQueue == NULL)
{
return 0;
}
arrayQueue* queue = pQueue;
return queue->m_size;
}
/*判断是否为空*/
int Empty_arrayQueue(aQueue pQueue)
{
if (pQueue == NULL)
{
return -1;
}
arrayQueue* queue = pQueue;
if (queue->m_size == 0)
{
return 1;
}
return 0;
}
/*销毁队列*/
void destory_arrayQueue(aQueue pQueue)
{
if (pQueue == NULL)
{
return;
}
arrayQueue* queue = pQueue;
if (queue->arr != NULL)
{
free(queue->arr);
queue->arr = NULL;
}
free(pQueue);
pQueue = NULL;
}
struct Person
{
char name[64];
int age;
};
void test01()
{
/*初始化队列*/
aQueue queue = init_arrayQueue();
//创建数据
struct Person p1 = { "aaa", 11 };
struct Person p2 = { "bbb", 22 };
struct Person p3 = { "ccc", 33 };
struct Person p4 = { "ddd", 44 };
struct Person p5 = { "eee", 55 };
/*入队*/
push_arrayQueue(queue, &p1);
push_arrayQueue(queue, &p2);
push_arrayQueue(queue, &p3);
push_arrayQueue(queue, &p4);
push_arrayQueue(queue, &p5);
printf("size = %d\n", size_arrayQueue(queue));
/*当队列不为空时*/
while (Empty_arrayQueue(queue) == 0)
{
/*返回队头元素*/
struct Person* p = front_arrayQueue(queue);
printf("name:%s\tage:%d\n", p->name, p->age);
struct Person* p1 = back_arrayQueue(queue);
printf("name:%s\tage:%d\n", p1->name, p1->age);
/*出队*/
pop_arrayQueue(queue);
printf("size = %d\n", size_arrayQueue(queue));
}
/*销毁队列*/
destory_arrayQueue(queue);
}
int main()
{
test01();
system("pause");
}