本文实现了链队。欢迎关注个人博客:https://guotianyu-2020.github.io。
1.代码部分
链队结构体的定义
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-wq8UGPUN-1627869027031)(链队的C语言实现/image-20210802093204287-16278679262101.png)]
typedef struct Qnode {
int data;
struct Qnode* next;
}*QueuePtr; //QueuePtr is a struct pointer.
typedef struct {
QueuePtr front; // Pointer front points at headnode, which keeps nothing but next 'real' node.
QueuePtr rear;
}LinkQueue;
初始化函数:
LinkQueue* InitQueue(LinkQueue* lq)
{
lq->front = lq->rear = (QueuePtr)malloc(sizeof(QueuePtr));
if (!lq->front) { printf("OVERFLOW"); }
else {
lq->front->next = NULL;
}
printf("Initialized.\n");
return lq;
}
入队出队函数:
void EnQueue(LinkQueue* lq)
{
int e;
QueuePtr p = (QueuePtr)malloc(sizeof(QueuePtr)); // Pay attention to the difference of assigning and pointing.
if (!p) { printf("OVERFLOW!"); }
else
{
printf("Input the number you want to insert:\n");
scanf_s("%d", &e);
p->data = e;
p->next = NULL;
lq->rear->next = p;
lq->rear = p;
printf("Insert successfully.\n");
}
}
void DeQueue(LinkQueue* lq)
{
int e;
QueuePtr p;
if (lq->front == lq->rear) {
printf("ERROR");
}
p = lq->front->next;
e = p->data;
lq->front->next = p->next;
printf("%d is deleted.\n", e);
if (p == lq->rear)
{
lq->rear = lq->front; // Change pointer rear when rear is deleted.
}
}
自定义show函数方便观察与调试:
void ShowQueue(LinkQueue* lq)
{
QueuePtr p;
if (lq->front == lq->rear) {
printf("Queue is empty.\n");
}
else {
p = lq->front->next;
while (p->next)
{
printf("Order: %d\n", p->data);
p = p->next;
}
printf("Order: %d\n", p->data);
}
}
销毁函数:(在这里关于无法free花费了大量的时间,解决的方法与思考放在第二部分)
void DestoryQueue(LinkQueue* lq)
{
QueuePtr p; // Q3: When should I spare space for it? A3: When it has something spared to assign.
p = lq->front->next;
while (p)
{
QueuePtr q; // Here p and q are oringinally in form of "()malloc(size())", but they actually don't have to.
q = p;
p = q->next;
free(q);
}
printf("Destoried.\n");
}
主函数:
int main()
{
LinkQueue* Lin = (LinkQueue*)malloc(sizeof(LinkQueue));
Lin = InitQueue(Lin);
EnQueue(Lin);
EnQueue(Lin);
EnQueue(Lin);
ShowQueue(Lin);
DeQueue(Lin);
DeQueue(Lin);
EnQueue(Lin);
ShowQueue(Lin);
DeQueue(Lin);
DeQueue(Lin);
ShowQueue(Lin);
DestoryQueue(Lin);
return 0;
}
调试成功!
2.反思与改进
-
关于内存分配的尝试产生了疑问,为什么p的空间不是80。还有待进一步学习。
//Process of trying. QueuePtr q = (QueuePtr)malloc(sizeof(QueuePtr)); QueuePtr p = (QueuePtr)malloc(sizeof(QueuePtr) * 20); // Q1: Why p can't be distributed with 80 memory? A1: Don't know why. printf("size:%d", sizeof(p)); //size:4 printf("size:%d", sizeof(q)); //size:4
-
关于什么时候malloc。
当初次使用结构体或者在函数内部需要对结构体内部成员进行赋值时要现malloc,当这个新结构体只是用来承载已存在的结构体的内容时(如直接指向同一内容:p = q)不需要malloc