队列-链表实现

队列的链表实现和队列的数组实现相比区别还是很大的.
首先我们需要2个指针frontrear, 分别指向头节点和尾节点.
这两个指针不属于节点本身的数据, 因此我们把这个两个指针单独定义成一个结构体.
因此, 队列的链表实现一共需要2个结构体, 一个存储队列数据本身, 一个存储头和尾指针.

createQueue()初始化函数中, 让front指针指向NULL, 通过front指针已经足够
判断队列为空的情况, 注意这里不能初始化rear指针也等于NULL, 否则再指向入队操作
时就会出现问题.

在入队函数add()中, 首先根据front指针是否等于NULL来判断队列是否是初次插入元素.

在出队函数del()中, 先判断队列是否为空.

C语言完整代码实现如下:

#include <stdio.h>
#include <stdlib.h>

struct queue {
    int data;
    struct queue* next;
};
struct queuePointer {
    struct queue* front;
    struct queue* rear;
};
typedef struct queue node;
typedef struct queue* link;
typedef struct queuePointer pnode;
typedef struct queuePointer* pointer;

// 函数声明
pointer createQueue (pointer p);
void add (pointer p, int x);
int del (pointer p);
void print (pointer p);

int main () {

    /* 简单测试开始 */
    pointer qptr = createQueue(qptr);
    add(qptr, 100);
    add(qptr, 200);
    add(qptr, 300);
    printf("%d\n", qptr->front->data); // 100
    printf("%d\n", qptr->rear->data);  // 300
    printf("%d\n", del(qptr)); // 100
    printf("%d\n", qptr->rear->data); // 300
    printf("\n");
    /* 简单测试结束 */

    /*复杂测试开始*/
    int i;
    pointer qptr2 = createQueue(qptr);
    for (i=2; i<=20; i+=2) {
        add(qptr2, i);
    }
    print(qptr2);

    del(qptr2);
    del(qptr2);
    del(qptr2);
    print(qptr2);
    /*复杂测试结束*/

    /* 对头队尾指向同一个节点测试开始 */
    pointer qptr3 = createQueue(qptr);
    add(qptr3, 666);
    del(qptr3);
    add(qptr3, 999);
    print(qptr3);
    /* 对头队尾指向同一个节点测试结束 */
    return 0;
}

// 创建空队列
pointer createQueue (pointer p) {
    p = (pnode*)malloc(sizeof(pnode)); // 这步非常关键, 注意我们使用了嵌套结构体
    p->front = (node*)malloc(sizeof(node));
    p->rear = (node*)malloc(sizeof(node));
    p->front = NULL;
    return p;
}

// 入队
void add (pointer p, int x) {
    link tmp = (node*)malloc(sizeof(node));
    tmp->data = x;
    tmp->next = NULL;

    // 如果这时队列中只有一个元素
    if (p->front == NULL) {
        p->front = tmp;
    }

    p->rear->next = tmp;
    p->rear = tmp;
}

// 出队
// 返回头结点元素的值
int del (pointer p) {
    if (p->front == NULL) {
        printf("队列元素为空, 无法出队\n");
        return 0; // 0表示错误信息
    }
    link tmp = p->front;
    int tmpValue = p->front->data;
    p->front = p->front->next;
    free(tmp);
    return tmpValue;
}

// 打印
void print (pointer p) {
    int length = 0;
    link head = p->front; // 不能直接修改p->front来遍历
    if (head == NULL) {
        printf("当前队列信息为空\n");
    } else {
        printf("当前队列的信息如下: \n");
        while (head) {
            printf("%d\n", head->data);
            head = head->next;
            length++;
        }
        printf("p->front->data = %d\n", p->front->data);
        printf("p->rear->data = %d\n", p->rear->data);
        printf("队列的总长度为: %d\n", length);
    }
    printf("\n\n");
}

posted @ 2017-10-01 12:05  阿胜4K  阅读(186)  评论(0编辑  收藏  举报