G
N
I
D
A
O
L

【数据结构-队列】队列的基本操作

1 顺序表实现队列(循环队列)

实现方式:

  • 队尾指针指向队尾元素
  • 队尾指针指向队尾元素的下一位置(队头指针在队尾指针的下一个位置作为队满标志

1.1 定义

  • 队尾指针指向队尾元素:
# define MAX 50 // 队列的容量

typedef struct Queue{
    int data[MAX];
    int size; // 增设记录队列当前元素的个数
    int front, rear;
} Queue;
  • 队尾指针指向队尾元素的下一位置:
# define MAX 50 // 队列的容量

typedef struct Queue{
    int data[MAX];
    int front, rear;
} Queue;

1.2 初始化

  • 队尾指针指向队尾元素:
void InitQueue (Queue &Q){
    Q.front = 0;
    Q.rear = MAX-1;
    Q.size = 0;
}
  • 队尾指针指向队尾元素的下一位置:
void InitQueue (Queue &Q){
    Q.front = 0;
    Q.rear = 0;
}

1.3 判队空

  • 队尾指针指向队尾元素:
bool EmptyQueue (Queue &Q){
    if (Q.size == 0)
        return true;
    else
        return false;
}
  • 队尾指针指向队尾元素的下一位置:
bool EmptyQueue (Queue &Q){
    if (Q.front == Q.rear)
        return true;
    else
        return false;
}

1.4 判队满

  • 队尾指针指向队尾元素:
bool FullQueue (Queue &Q){
    if (Q.size == MAX)
        return true;
    else
        return false;
}
  • 队尾指针指向队尾元素的下一位置:
bool FullQueue (Queue &Q){
    if ((Q.rear+1) % MAX == Q.front)
        return true;
    else
        return false;
}

1.5 出队

  • 队尾指针指向队尾元素:
bool DeQueue (Queue &Q, int &x){
    if (Q.size == 0)
        return false;
    
    x = Q.data[Q.front]; // 获得出队元素
    Q.front = (Q.front+1) % MAX; // 队头指针加 1
    return true;
}
  • 队尾指针指向队尾元素的下一位置:
bool DeQueue (Queue &Q, int &x){
    if (Q.front == Q.rear)
        return false;
    
    x = Q.data[Q.front]; // 获得出队元素
    Q.front = (Q.front+1) % MAX; // 队头指针加 1
    return true;
}

1.6 入队

  • 队尾指针指向队尾元素:
bool EnQueue (Queue &Q, const int x){
    if (Q.size == MAX)
        return false;
    
    Q.rear = (Q.rear+1) % MAX; // 队尾指针加 1
    Q.data[Q.rear] = x; // 入队
    return true;
}
  • 队尾指针指向队尾元素的下一位置:
bool EnQueue (Queue &Q, const int x){
    if ((Q.rear+1) % MAX == Q.front)
        return false;
    
    Q.data[Q.rear] = x; // 入队
    Q.rear = (Q.rear+1) % MAX; // 队尾指针指向下一个位置
    return true;
}

1.7 队长

int LenQueue (Queue &Q){
    return (Q.rear - Q.front + MAX) % MAX;
}

2 单向链表实现队列

单向链表实现队列:链表头出队,链表尾入队。

实现方式:

  • 不带头结点
  • 带头结点(头结点可存储当前队列的元素个数

2.1 定义

  • 不带头结点:
#define MAX 50 // 队列的容量

typedef struct LinkNode{
    int data;
    struct LinkNode *next;
}LinkNode;

typedef struct Queue{
    int size; // 增设记录队列当前元素的个数
    struct LinkNode *front;
    struct LinkNode *rear;
}LinkQueue;
  • 带头结点:
#define MAX 50 // 队列的容量

typedef struct LinkNode{
    int data;
    struct LinkNode *next;
}LinkNode;

typedef struct Queue{
    // struct LinkNode *front; // 队头指针可由头结点指针充当实现
    struct LinkNode *rear;
    struct LinkNode *head; // 头结点指针
}LinkQueue;

2.2 初始化

  • 不带头结点:
void InitQueue (LinkQueue &Q){
    Q.front = NULL;
    Q.rear = NULL;
    Q.size = 0;
}
  • 带头结点:
void InitQueue (LinkQueue &Q){
    Q.head = (LinkNode *) malloc(sizeof(LinkNode)); // 创建头结点
    Q.rear = Q.head; // 初始时,队头指针和队尾指针指向头结点
    Q.head->data = 0; // 记录队列当前元素个数
    Q.head->next = NULL;
}

2.3 判队空

  • 不带头结点:
bool EmptyQueue (LinkQueue &Q){
    if ((Q.front == NULL) || (Q.rear == NULL))
        return true;
    else
        return false;
}

bool EmptyQueue (LinkQueue &Q){
    if (Q.size == 0)
        return true;
    else
        return false;
}
  • 带头结点:
bool EmptyQueue (LinkQueue &Q){
    if (Q.head->data == 0)
        return true;
    else
        return false;
}

bool EmptyQueue (LinkQueue &Q){
    if (Q.head == Q.rear)
        return true;
    else
        return false;
}

2.4 判队满

  • 不带头结点:
bool FullQueue (LinkQueue &Q){
    if (Q.size == MAX)
        return true;
    else
        return false;
}
  • 带头结点:
bool FullQueue (LinkQueue &Q){
    if (Q.head->data == MAX)
        return true;
    else
        return false;
}

2.5 出队

  • 不带头结点:
bool DeQueue (LinkQueue &Q, int &x){
    LinkNode *frontNext; // 记录队头指针的下一个结点

    if ((Q.front == NULL) || (Q.rear == NULL)) // 判空,或:Q.size == 0
        return false;
        
    x = Q.front->data;
    
    if (Q.front == Q.rear){ // 若队列只有一个结点
        free(Q.front);
        Q.front = NULL;
        Q.rear = NULL;
    }
    else{ 
        frontNext = Q.front->next; // 记录队头指针的下一个结点
        free(Q.front);
        Q.front = frontNext; // 更新队头指针
    }
    
    Q.size--; // 出队,减少一个元素
    return true;
}
  • 带头结点:
bool DeQueue (LinkQueue &Q, int &x){
    LinkNode *front = Q.head->next; // 队头指针

    if (Q.head == Q.rear) // 判空,或:Q.head->data == 0
        return false;
        
    x = front->data;
    
    Q.head->data--; // 出队,减少一个元素
    Q.head->next = front->next; // 头结点的指针域指向队头结点的下一个结点
    if (front == Q.rear) // 若队列只有一个结点,出队后只剩头结点
        Q.rear = Q.head; // 队尾指针指向头结点
    free(front);
    return true;
}

2.6 入队

  • 不带头结点:
bool EnQueue (LinkQueue &Q, const int x){
    LinkNode *newNode;

    if (Q.size == NUM) // 判满
        return false;
        
    newNode = (LinkNode *) malloc(sizeof(LinkNode));
    newNode->data = x;
    newNode->next = NULL;
    
    if ((Q.front == NULL) || (Q.rear == NULL)){ // 如果队列为空 // 或:Q.size == 0
        Q.front = newNode;
        Q.rear = newNode;
    }
    else{
        Q.rear->next = newNode; // 队尾指针的指针域指向新结点
        Q.rear = newNode; // 队尾指针指向新结点
    }
    
    Q.size++; // 入队,增加一个元素
    return true;
}
  • 带头结点:
bool EnQueue (LinkQueue &Q, const int x){
    LinkNode *newNode;

    if (Q.head->data == NUM) // 判满
        return false;
        
    newNode = (LinkNode *) malloc(sizeof(LinkNode));
    newNode->data = x;
    newNode->next = NULL;
    
    Q.head->data++; // 入队,增加一个元素
    Q.rear->next = newNode; // 队尾指针的指针域指向新结点
    Q.rear = newNode; // 队尾指针指向新结点
    return true;
}
posted @ 2022-10-24 23:11  漫舞八月(Mount256)  阅读(134)  评论(0编辑  收藏  举报