思维导图
完成链队的剩下操作:出队、长度、销毁的功能函数的封装。
link_queue.h代码:
#ifndef __LINK_QUEUE_H__
#define __LINK_QUEUE_H__
#include <stdio.h>
#include <stdlib.h>
typedef int datatype;
typedef struct node//定义链表结构体类型
{
union
{
int length;//头节点的数据域
datatype data;//普通节点的数据域
};
struct node *next;
}node,*node_p;
typedef struct linkqueue//定义链式队列
{
node *head;//定义指针指向链表的头节点
node *tail;//定义指针指向链表的尾节点
}linkqueue,*linkqueue_p;
linkqueue_p create();//创建链式队列
int empty(linkqueue_p Q);//判空
void insert_queue(linkqueue_p Q,datatype data);//入队
void show_queue(linkqueue_p Q);//遍历
void delete_queue(linkqueue_p Q);//出队
void queue_length(linkqueue_p Q);//求链式队列长度
void free_queue(linkqueue_p Q);//释放链式队列
#endif
link_queue.c代码:
#include "link_queue.h"
//创建链式队列
linkqueue_p create()
{
//从堆区申请空间存放链式队列
linkqueue_p Q=(linkqueue_p)malloc(sizeof(linkqueue));
if(NULL == Q)
{
printf("创建链式队列失败!\n");
return NULL;
}
//从堆区申请空间存放链表,用head指针指向
Q->head=(node_p)malloc(sizeof(node));
if(NULL == Q->head)
{
printf("创建链表空间失败!\n");
free(Q);
return NULL;
}
Q->head->length=0;
Q->head->next=NULL;
Q->tail=Q->head;//将链式队列中的队尾指针指向和队头指针指向一样
printf("成功创建链式队列!\n");
return Q;
}
//判空
int empty(linkqueue_p Q)
{
if(NULL == Q)
{
printf("链式队列不合法!\n");
return -1;
}
return Q->head==Q->tail?1:0;
}
//入队(类似于链表的尾插)
void insert_queue(linkqueue_p Q,datatype data)
{
if(NULL == Q)
{
printf("入队失败!\n");
return;
}
node_p P=(node_p)malloc(sizeof(node));
if(NULL == P)
{
printf("创建链表普通节点失败!\n");
return;
}
P->data=data;
P->next=NULL;
//入队
Q->tail->next=P;
Q->tail=P;
Q->head->length++;//链表长度自增
}
//遍历
void show_queue(linkqueue_p Q)
{
if(NULL == Q || empty(Q))
{
printf("遍历失败!\n");
return;
}
node_p p=Q->head;
while(p->next!=NULL)
{
p=p->next;
printf("%d ",p->data);
}
putchar(10);
}
//出队(类似于链表的头删)
void delete_queue(linkqueue_p Q)
{
if(NULL == Q || empty(Q))
{
printf("出队失败!\n");
return;
}
node_p p=Q->head->next;//定义一个指针指向链表的第一个普通节点
Q->head->next=p->next;//链表头节点的next指向要出队节点的下一个节点
free(p);//释放链表的第一个节点
p=NULL;
if(Q->head->next == NULL)
{
Q->tail=Q->head;//如果最后一个节点被释放,将队尾指针指向队头指针,如果不指向,判空操作将不能正常执行
}
Q->head->length--;//链表长度自减
}
//求链式队列的长度
void queue_length(linkqueue_p Q)
{
if(NULL == Q)
{
printf("输出链式队列长度失败!\n");
return;
}
printf("链式队列长度为:%d\n",Q->head->length);
}
//释放链式队列
void free_queue(linkqueue_p Q)
{
if(NULL == Q)
{
printf("释放链式队列失败!\n");
return;
}
while(Q->head->next!=NULL)
{
delete_queue(Q);
}
free(Q->head);
Q->head=NULL;
Q->tail=NULL;//此时队尾指针指向的头节点已经被释放掉了,所以需要将队尾指针置空就可以
free(Q);
printf("成功释放链式队列!\n");
Q=NULL;
}
main.c代码:
#include "link_queue.h"
int main(int argc, const char *argv[])
{
linkqueue_p Q=create();
insert_queue(Q,10);//入队
insert_queue(Q,20);
insert_queue(Q,30);
insert_queue(Q,40);
insert_queue(Q,50);
insert_queue(Q,60);
insert_queue(Q,70);
show_queue(Q);//遍历
delete_queue(Q);//出队
show_queue(Q);
delete_queue(Q);
show_queue(Q);
queue_length(Q);//求链式队列长度
free_queue(Q);//释放链式队列
Q=NULL;
return 0;
}