2024/10/14日 日志 --》关于用栈和队列解决回文问题解析。

回文是指正读和反读一样。
接下来我们将以回文数为例,回文数是指正读和反读都一样的数,例如 121、12321 等
首先,让我们明析栈和队列的特点。
栈是一种后进先出(LIFO)的数据结构,我们可以使用栈来反转数字,然后比较反转前后的数字是否相同。
根据栈的特点,我们可以使用双数栈来解决回文数问题。 下面我们使用链栈,进行代码书写:

点击查看代码
#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

// 栈的节点定义
typedef struct StackNode {
    int data;
    struct StackNode* next;
} StackNode;

// 栈的定义
typedef struct {
    StackNode* top;
} Stack;

// 初始化栈
void initStack(Stack* s) {
    s->top = NULL;
}

// 入栈操作
void push(Stack* s, int value) {
    StackNode* newNode = (StackNode*)malloc(sizeof(StackNode));
    newNode->data = value;
    newNode->next = s->top;
    s->top = newNode;
}

// 出栈操作
int pop(Stack* s) {
    if (s->top == NULL) {
        return -1;
    }
    StackNode* temp = s->top;
    int value = temp->data;
    s->top = s->top->next;
    free(temp);
    return value;
}

// 检查回文数
int isPalindrome(int num) {
    int originalNum = num;
    Stack s1,s2;
    initStack(&s1);
    initStack(&s2);

    // 将数字压入栈中
    while (num > 0) {
        push(&s1, num % 10);
        num /= 10;
    }

    // 弹出栈中的数字并重建数字
    int reversedNum = 0;
    while (s1.top != NULL) {
        push(&s2, pop(&s1));
    }
    while (s2.top != NULL) {
        reversedNum = reversedNum * 10 + pop(&s2);
    }
    printf("%d\n", originalNum);
    printf("%d\n", reversedNum);

    // 比较原始数字和反转后的数字
    return originalNum == reversedNum;
}

int main() {
    int num;
    printf("Enter a number: ");
    scanf("%d", &num);

    if (isPalindrome(num)) {
        printf("%d is a palindrome.\n", num);
    }
    else {
        printf("%d is not a palindrome.\n", num);
    }

    return 0;
}

队与栈有些不同。
首先让我们明析队列的特点:
队列是一种先进先出(FIFO)的数据结构,我们可以使用队列来反转数字,然后比较反转前后的数字是否相同。
因此,我们可以这样来利用链队列队列解决回文数问题:

点击查看代码
#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

// 队列的节点定义
typedef struct QueueNode {
    int data;
    struct QueueNode* next;
} QueueNode;

// 队列的定义
typedef struct {
    QueueNode* front;
    QueueNode* rear;
} Queue;

// 初始化队列
void initQueue(Queue* q) {
    q->front = q->rear = NULL;
}

// 入队操作
void enqueue(Queue* q, int value) {
    QueueNode* newNode = (QueueNode*)malloc(sizeof(QueueNode));
    newNode->data = value;
    newNode->next = NULL;
    if (q->rear == NULL) {
        q->front = q->rear = newNode;
        return;
    }
    q->rear->next = newNode;
    q->rear = newNode;
}

// 出队操作
int dequeue(Queue* q) {
    if (q->front == NULL) {
        return -1;
    }
    QueueNode* temp = q->front;
    int value = temp->data;
    q->front = q->front->next;
    if (q->front == NULL) {
        q->rear = NULL;
    }
    free(temp);
    return value;
}

// 检查回文数
int isPalindrome(int num) {
    int originalNum = num;
    Queue q;
    initQueue(&q);

    // 将数字入队
    while (num > 0) {
        enqueue(&q, num % 10);
        num /= 10;
    }

    // 出队并重建数字
    int reversedNum = 0;
    while (q.front != NULL) {
        reversedNum = reversedNum * 10 + dequeue(&q);
    }
    // 比较原始数字和反转后的数字
    return originalNum == reversedNum;
}

int main() {
    int num;
    printf("Enter a number: ");
    scanf("%d", &num);

    if (isPalindrome(num)) {
        printf("%d is a palindrome.\n", num);
    }
    else {
        printf("%d is not a palindrome.\n", num);
    }

    return 0;
}

此外,我们还可以用队列的另一种形式,循环队列来解决回文数问题。
循环队列是一种特殊的队列,它将队列的最后一个位置连接到第一个位置,形成一个圆环。这样可以避免在队列末尾添加或删除元素时的数组移动,提高效率。
下面是简单的示例:

点击查看代码
#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
#include <stdlib.h>

#define MAXSIZE 100 // 循环队列的最大长度

// 循环队列的结构定义
typedef struct {
    int data[MAXSIZE];
    int front; // 队头指针
    int rear;  // 队尾指针
} CircularQueue;

// 初始化循环队列
void initQueue(CircularQueue* q) {
    q->front = q->rear = 0;
}

// 判断循环队列是否为空
int isEmpty(CircularQueue* q) {
    return q->front == q->rear;
}

// 判断循环队列是否已满
int isFull(CircularQueue* q) {
    return (q->rear + 1) % MAXSIZE == q->front;
}

// 入队操作
void enqueue(CircularQueue* q, int value) {
    if (isFull(q)) {
        printf("Queue is full.\n");
        return;
    }
    q->data[q->rear] = value;
    q->rear = (q->rear + 1) % MAXSIZE;
}

// 出队操作
int dequeue(CircularQueue* q) {
    if (isEmpty(q)) {
        printf("Queue is empty.\n");
        return -1;
    }
    int value = q->data[q->front];
    q->front = (q->front + 1) % MAXSIZE;
    return value;
}

// 检查回文数
int isPalindrome(int num) {
    CircularQueue q;
    initQueue(&q);

    // 将数字的每一位入队
    while (num > 0) {
        enqueue(&q, num % 10);
        num /= 10;
    }

    // 出队并重建数字
    int reversedNum = 0;
    while (!isEmpty(&q)) {
        reversedNum = reversedNum * 10 + dequeue(&q);
    }

    // 比较原始数字和反转后的数字
    return q.front == q.rear && q.data[q.front] == 0;
}

int main() {
    int num;
    printf("Enter a number: ");
    scanf("%d", &num);

    if (isPalindrome(num)) {
        printf("%d is a palindrome.\n", num);
    }
    else {
        printf("%d is not a palindrome.\n", num);
    }

    return 0;
}
                                                                                                                                    -------------------Moonbeams.
posted @   Moonbeamsc  阅读(28)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 分享4款.NET开源、免费、实用的商城系统
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
· 上周热点回顾(2.24-3.2)
返回顶端
点击右上角即可分享
微信分享提示