一定义
1.1概述:
队列只允许在一端进行插入操作,而在另一端进行删除操作的线性表
特点:队列是先进先出的线性表 允许插入的一端称为队尾,允许删除的一端是队头
这里我们就介绍链式的
1.2 建立队列
这里说一句 其实不管是栈还是队列都是一种特殊的线性表,我们只需要将线性表了解透彻 其他的都是按照一些特殊的规则来要求线性表的
#include <stdio.h>
#include <malloc.h>
typedef struct qnode
{
int data;
struct qnode *next;
}qnode,*queueptr;//定义结构体数据域和指针域
typedef struct Linkqueue
{
queueptr front,rear;//队头,队尾指针
}Linkqueue;
//初始化队列函数,将队头,队尾结构体变量传入,以及队列的个数
void initlist(Linkqueue *L,int n)
{
//下面就是尾插法建立队列了
queueptr head;
queueptr temp;
queueptr tail;
head=(queueptr)malloc(sizeof(qnode));
head->next=NULL;
for(int i=0;i<n;i++)
{
temp=(queueptr)malloc(sizeof(qnode));
temp->data=i;
if(head->next==NULL)
{
head->next=temp;
L->front=head;//将对头指针指向头结点
}
else
{
tail->next=temp;
}
tail=temp;
}
L->rear=tail;//将队尾指针指向尾结点
tail->next=NULL;//尾结点的指针指向空
}
int main()
{
Linkqueue L;
initlist(&L,5);
printf("队头指针指向的元素数据域%d\n",L.front->next->data);
printf("队尾指针指向的元素数据域%d\n",L.rear->data);
L.front=L.front->next;// 我们队头指针指向的是头结点不是首元结点所以需要指向后继结点才能输出需要的数据域
for(int i=0;i<5;i++)
{
printf("%d\n",L.front->data);
L.front=L.front->next;
}
return 0;
}
1.3入队操作
入队操作时,其实就是在链表的尾部插入结点
核心代码:
void enqueuelist(Linkqueue *L,int n)
{
queueptr new;//声明一个新的结点
new=(queueptr)malloc(sizeof(qnode));
new->data=n;
L->rear->next=new;//将之前尾结点的指针域指向新建结点
new->next=NULL;
L->rear=new;//将队尾指针指向新的尾元素
}
完整实现,插入一个新结点数据域是6
#include <stdio.h>
#include <malloc.h>
typedef struct qnode
{
int data;
struct qnode *next;
}qnode,*queueptr;//定义结构体数据域和指针域
typedef struct Linkqueue
{
queueptr front,rear;//队头,队尾指针
}Linkqueue;
//初始化队列函数,将队头,队尾结构体变量传入,以及队列的个数
void initlist(Linkqueue *L,int n)
{
//下面就是尾插法建立队列了
queueptr head;
queueptr temp;
queueptr tail;
head=(queueptr)malloc(sizeof(qnode));
head->next=NULL;
for(int i=0;i<n;i++)
{
temp=(queueptr)malloc(sizeof(qnode));
temp->data=i;
if(head->next==NULL)
{
head->next=temp;
L->front=head;//将对头指针指向头结点
}
else
{
tail->next=temp;
}
tail=temp;
}
L->rear=tail;//将队尾指针指向尾结点
tail->next=NULL;//尾结点的指针指向空
}
void enqueuelist(Linkqueue *L,int n)
{
queueptr new;//声明一个新的结点
new=(queueptr)malloc(sizeof(qnode));
new->data=n;
L->rear->next=new;//将之前尾结点的指针域指向新建结点
new->next=NULL;
L->rear=new;//将队尾指针指向新的尾元素
}
int main()
{
Linkqueue L;
initlist(&L,5);
enqueuelist(&L,6);
printf("队头指针指向的元素数据域%d\n",L.front->next->data);
printf("队尾指针指向的元素数据域%d\n",L.rear->data);
L.front=L.front->next;// 我们队头指针指向的是头结点不是首元结点所以需要指向后继结点才能输出需要的数据域
for(int i=0;i<6;i++)
{
printf("%d\n",L.front->data);
L.front=L.front->next;
}
return 0;
}
1.4出队操作
int deletelist(Linkqueue *L)
{
//出栈操作时,将头节点指向的结点出栈
queueptr p;
if(L->front==L->rear)
{
return 0;
}
p=L->front->next;//p是要删除的首元结点
L->front->next=p->next;//将头结点后继指向p的后继结点
if(L->rear==p)
{
L->rear=L->front;//如果只有一个结点 队头和队尾指针应相同
}
free(p);
return 1;
}
#include <stdio.h>
#include <malloc.h>
typedef struct qnode
{
int data;
struct qnode *next;
}qnode,*queueptr;//定义结构体数据域和指针域
typedef struct Linkqueue
{
queueptr front,rear;//队头,队尾指针
}Linkqueue;
//初始化队列函数,将队头,队尾结构体变量传入,以及队列的个数
void initlist(Linkqueue *L,int n)
{
//下面就是尾插法建立队列了
queueptr head;
queueptr temp;
queueptr tail;
head=(queueptr)malloc(sizeof(qnode));
head->next=NULL;
for(int i=0;i<n;i++)
{
temp=(queueptr)malloc(sizeof(qnode));
temp->data=i;
if(head->next==NULL)
{
head->next=temp;
L->front=head;//将对头指针指向头结点
}
else
{
tail->next=temp;
}
tail=temp;
}
L->rear=tail;//将队尾指针指向尾结点
tail->next=NULL;//尾结点的指针指向空
}
int deletelist(Linkqueue *L)
{
//出栈操作时,将头节点指向的结点出栈
queueptr p;
if(L->front==L->rear)
{
return 0;
}
p=L->front->next;//p是要删除的首元结点
L->front->next=p->next;//将头结点后继指向p的后继结点
if(L->rear==p)
{
L->rear=L->front;//如果只有一个结点 队头和队尾指针应相同
}
free(p);
return 1;
}
int main()
{
Linkqueue L;
initlist(&L,5);
int a=deletelist(&L);
if(a)
{
printf("队头指针指向的元素数据域%d\n",L.front->next->data);
printf("队尾指针指向的元素数据域%d\n",L.rear->data);
L.front=L.front->next;// 我们队头指针指向的是头结点不是首元结点所以需要指向后继结点才能输出需要的数据域
for(int i=0;i<4;i++)
{
printf("%d\n",L.front->data);
L.front=L.front->next;
}
}
else
printf("delete error");
return 0;
}