写链式队列,实现入队出队

#include<stdio.h> // 引入标准输入输出库
#include<string.h> // 引入字符串处理库
#include<stdlib.h> // 引入标准库,包含一些常用的函数,如内存分配、随机数生成等

// 定义一个结构体,表示一个人的信息
typedef struct Statck {
    char name[20]; // 姓名,长度为20的字符数组
    int age; // 年龄
}data;

// 定义一个结构体,表示一个节点,包含一个个人信息结构和一个指向下一个节点的指针
typedef struct node {
    struct Statck st; // 个人信息结构
    struct node* next; // 指向下一个节点的指针
}Node;

// 定义一个结构体,表示一个队列,包含一个指向队头和队尾的指针
typedef struct tagQUEUE {
    struct node* front; // 指向队头的指针
    struct node* rear; // 指向队尾的指针
}tagQueue;

// 初始化一个节点,分配内存,将next设置为NULL,将个人信息结构清零
Node* Init()
{
    Node* node;
    node = (Node*)malloc(sizeof(Node));
    node->next = NULL;
    memset(&node->st, 0, sizeof(data));
    return node;
}

// 创建一个队列,初始化一个节点,设置队头和队尾的指针,返回队列的指针
tagQueue* CreateQueue()
{
    tagQueue* s;
    Node* node;
    node = Init();
    s = (tagQueue*)malloc(sizeof(tagQueue));
    s->front = s->rear = node;
    return s;
}

// 将一个元素入队,首先初始化一个新的节点,然后将个人信息结构赋值给新节点的个人信息结构,将新节点添加到队尾,打印队尾元素的个人信息和年龄
void PushQueue(tagQueue* pHead, data num)
{
    Node* newNode = Init();
    newNode->st = num;
    pHead->rear->next=newNode;
    pHead->rear = newNode;
    printf("%s\t%d入队列!\n", pHead->rear->st.name, pHead->rear->st.age);
}

// 将队头元素出队,如果队头元素为空,打印"队列空",否则打印队头元素的个人信息和年龄,将队头元素指向下一个元素
void PopStack(tagQueue* pHead)
{

    if (pHead->front == pHead->rear)
    {
        printf("队列空\n");
        return;
    }
    else {
        Node* node;
        node = pHead->front->next;
        printf("%s\t%d出队列!\n", node->st.name, node->st.age);
        if (pHead->front->next == pHead->rear)
        {
            pHead->rear = pHead->front;
        }
        else {
            pHead->front->next = node->next;
        }
        free(node);
    }
}

// 主函数
int main()
{
    // 创建一个队列
    tagQueue* head = CreateQueue();
    // 循环2次,每次都将一个新元素入队
    for (int i = 0; i < 2; i++)
    {
        data s{}; // 创建一个数据结构,用于存储个人信息
        scanf("%s%d", s.name, &s.age); // 读取用户输入的姓名和年龄
        PushQueue(head, s); // 将新元素入队
    }
    // 将队头元素出队四次
    PopStack(head);
    PopStack(head);
    PopStack(head);
    PopStack(head);
    return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
### 回答1: 链式队列实现可以使用链表来完成,每个节点存储一个元素,以及指向下一个节点的指针。具体实现如下: 1. 定义节点结构体 ``` struct Node { int data; Node* next; }; ``` 2. 定义队列结构体 ``` struct Queue { Node* front; // 队头指针 Node* rear; // 队尾指针 }; ``` 3. 初始化队列 ``` void initQueue(Queue& q) { q.front = q.rear = new Node; q.front->next = nullptr; } ``` 4. 入队操作 ``` void enQueue(Queue& q, int x) { Node* p = new Node; p->data = x; p->next = nullptr; q.rear->next = p; q.rear = p; } ``` 5. 出队操作 ``` void deQueue(Queue& q) { if (q.front == q.rear) { cout << "队列为空,无法出队!" << endl; return; } Node* p = q.front->next; cout << "出队元素为:" << p->data << endl; q.front->next = p->next; if (q.rear == p) { q.rear = q.front; } delete p; } ``` 6. 主函数 ``` int main() { Queue q; initQueue(q); while (true) { cout << "请输入一个数字入队,或者输入一个字符出队:" << endl; char c; cin >> c; if (isdigit(c)) { int x = c - '0'; enQueue(q, x); } else { deQueue(q); } } return 0; } ``` 这样就实现了一个简单的链式队列,可以输入数字入队输入字符出队。 ### 回答2: 链式队列是一种基于链表实现的队列,它采用队尾入队、队头出队的方式来进行操作。链式队列的特点是没有大小限制,可以动态地进行扩容。对于大多数应用场景,链式队列都是一种非常高效和方便的数据结构。 根据题目要求,实现链式队列应该具有以下功能: 1. 入队输入数字时将其插入队尾 2. 出队输入字符时将队头元素出队 我们可以定义一个链式队列的节点类,包含数据域和指向下一个节点的指针域。同时还需要定义一个队列类,包含头尾指针。 以下是链式队列代码实现: ```python class Node: def __init__(self, data): self.data = data self.next = None class Queue: def __init__(self): self.head = None self.tail = None def is_empty(self): return self.head is None def enqueue(self, data): new_node = Node(data) if self.tail is None: self.head = new_node self.tail = new_node else: self.tail.next = new_node self.tail = new_node def dequeue(self): if self.is_empty(): return None data = self.head.data self.head = self.head.next if self.head is None: self.tail = None return data if __name__ == '__main__': q = Queue() while True: value = input("请输入数字字符:") if value.isdigit(): q.enqueue(int(value)) else: data = q.dequeue() if data is None: print("队列为空") else: print("队头元素为:", data) ``` 在上面的代码中,我们首先定义了一个节点类 `Node`,包含数据域和指针域,链式队列的每个节点就是一个 `Node` 的实例。然后定义了队列类 `Queue`,其中包含头指针和尾指针。 `is_empty()` 方法判断队列是否为空, `enqueue()` 方法用于入队操作, `dequeue()` 方法用于出队操作。在 `main` 函数中,我们不断地输入数字字符,如果是数字则将其入队,如果是字符则将队头元素出队并打印出来。 总之,链式队列是一种非常高效和方便的数据结构,它可以动态地进行扩容,适用于大多数应用场景。代码实现也相对简单,只需要利用链表的基本操作实现入队出队即可。 ### 回答3: 链式队列是一种特殊的队列,它借助链表实现队列的功能。相对于顺序队列,它的队列长度不受限制,能够更加灵活地处理队列中的元素。 我们可以通过定义一个链式结构体来实现链式队列。对于每个队列节点,它会包含一个值(数字字符)和一个指向下一个节点的指针。这里我们定义一个名为 `Node` 的结构体,并使用 `Option` 类型来表示队列的头节点和尾节点。代码如下: ```rust struct Node { value: Option<i32>, // 存储值 next: Option<Box<Node>>, // 指向下一个节点的指针 } struct Queue { head: Option<Box<Node>>, // 指向队列头的指针 tail: Option<Box<Node>>, // 指向队列尾的指针 } ``` 这里使用 `Option<Box<T>>` 来表示一个可选的指向类型为 `T` 的堆上分配的指针。这是为了避免处理空指针时出现 nullptr 异常。接下来我们可以定义 `Queue` 类型的方法,来实现入队出队的操作: ```rust impl Queue { fn new() -> Self { Queue { head: None, tail: None } } fn enqueue(&mut self, val: i32) { let new_node = Box::new(Node { value: Some(val), next: None }); match self.tail.take() { Some(old_tail) => old_tail.next = Some(new_node), None => self.head = Some(new_node), } self.tail = Some(new_node); } fn dequeue(&mut self) -> Option<char> { self.head.take().map(|old_head| { let val = old_head.value.unwrap(); self.head = old_head.next; if self.head.is_none() { self.tail = None; } val as u8 as char // 将数字转换为 ASCII 字符 }) } } ``` 在 `enqueue` 方法中,我们使用 `take` 函数来获取 `tail` 字段的所有权,并将其设置为新插入节点的前一个节点。如果原本的队列为空,则将头节点指向新节点。最后,我们更新 `tail` 指向新节点。 在 `dequeue` 方法中,我们取出头节点并将其 `value` 字段进行取值。接着,我们更新 `head` 指针,并检查队列是否为空。如果队列为空,我们同时将 `tail` 指针设为 `None`。最后,我们将取出的数字转换为 ASCII 字符并返回。 为了能够让用户输入不同的元素类型(数字字符),我们可以将 `enqueue` 方法的参数类型定义为泛型 `T`,并将节点的 `value` 字段也设为泛型类型。在 `dequeue` 方法中,我们返回的类型为 `Option<T>`。这样做的好处是可以提高代码的灵活性。最终代码如下: ```rust struct Node<T> { value: Option<T>, next: Option<Box<Node<T>>>, } struct Queue<T> { head: Option<Box<Node<T>>>, tail: Option<Box<Node<T>>>, } impl<T> Queue<T> { fn new() -> Self { Queue { head: None, tail: None } } fn enqueue(&mut self, val: T) { let new_node = Box::new(Node { value: Some(val), next: None }); match self.tail.take() { Some(old_tail) => old_tail.next = Some(new_node), None => self.head = Some(new_node), } self.tail = Some(new_node); } fn dequeue(&mut self) -> Option<T> { self.head.take().map(|old_head| { let val = old_head.value.unwrap(); self.head = old_head.next; if self.head.is_none() { self.tail = None; } val }) } } fn main() { let mut queue = Queue::new(); queue.enqueue(1); queue.enqueue(2); queue.enqueue(3); assert_eq!(queue.dequeue(), Some(1)); assert_eq!(queue.dequeue(), Some(2)); assert_eq!(queue.dequeue(), Some(3)); queue.enqueue('a'); queue.enqueue('b'); queue.enqueue('c'); assert_eq!(queue.dequeue(), Some('a')); assert_eq!(queue.dequeue(), Some('b')); assert_eq!(queue.dequeue(), Some('c')); } ```

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值