1.第一个结构是存放链表的数据,第二个结构体是存放头节点和尾节点的以方便找到尾节点,存放头节点的是phead,尾节点的是ptail
typedef struct QueueNode
{struct QueueNode* next;//单链表QDataType data;//放数据
}QNode;typedef struct Queue
{QNode* phead;//头节点QNode* ptail;//尾节点QDataType size; //统计有多少节点
}Queue;
2.初始化存放头节点和尾节点的第二个结构体
void QueueInit(Queue* pq)//初始化
{assert(pq);pq->phead = NULL;pq->ptail = NULL;pq->size = 0;
}
3.销毁函数,把第一个结构体节点地址存入了第二个结构体,再通过第二个结构体所存的地址去销毁第一个结构体
void QueueDestroy(Queue* pq)//销毁
{assert(pq);//第一个结构体QNode* cur = pq->phead;while (cur){QNode* next = cur->next;free(cur);cur = next;//循环更新节点}pq->phead = NULL;pq->ptail = NULL;pq->size = 0;
}
4.插入函数,1.如果是空链表则把创建的节点的地址赋值给头指针和尾指针,2.不是空指针则把新建立的节点链接到尾指针的next上
void QueuePush(Queue* pq, QDataType x)//插入数据
{QNode* newnode = (QNode*)malloc(sizeof(QNode));//扩大的是第一个结构体if (newnode == NULL){perror("malloc");return;}newnode->data = x;newnode->next = NULL;if (pq->phead == NULL){pq->phead = pq->ptail = newnode;}else{pq->ptail->next = newnode;pq->ptail = newnode;}pq->size++;
}
5.队头出数据就是删队头。1.判空:判pq指针的空,再判pq->phead指针的空,2.如果链表只有一个节点就去了 (if语句) 删除第一个节点,3.链表有两个节点的才去(else)语句
void QueuePop(Queue* pq)//队头出数据就是删队头
{assert(pq);assert(!QueueEmpty(pq));//判pq->phead的空if (pq->phead->next == NULL){free(pq->phead);pq->phead = pq->ptail = NULL;}else{QNode* next = pq->phead->next;free(pq->phead);pq->phead = next;}pq->size--;
}
6.返回对头数据,(pq指针)和(pq->phead头指针不能为空)
QDataType QueueFront(Queue* pq)//返回对头数据
{assert(pq);assert(!QueueEmpty(pq));return pq->phead->data;
}
7.返回队尾数据
QDataType QueueBack(Queue* pq)//返回队尾数据
{assert(pq);assert(!QueueEmpty(pq));return pq->ptail->data;
}
8.返回总链表节点的个数
int QueueSize(Queue* pq)//返回总的数据个数
{assert(pq);return pq->size;
}
9.判空函数,是空指针返回真,不是空指针返回假
bool QueueEmpty(Queue* pq)//是空的返回真
{assert(pq);return pq->phead == NULL && pq->ptail == NULL;
}