【算法与数据结构】 用栈实现队列、用队列实现栈

用栈实现队列效果(需要两个栈)

思路:
栈1负责进数据,每次要实现出队效果的时候,借助栈2颠倒顺序后出栈即可。元素出队后可以有两种方式:

  • 把出队后栈2中的数据再依次放入栈1。效率低。
  • 出队后,栈2中的数据不需要动,此时仍然用栈1入栈,栈2出栈,只有在栈2空的时候,再把栈1中的所有数据搬入栈1。高效。
#include <stdio.h>
#include <stdlib.h>

typedef struct NodeStruct {
    int data;
    struct NodeStruct* next;
} Node, *Position, *Stack;

void initStack(Stack *s) {
    *s = malloc(sizeof(Node));
    (*s)->next = NULL;
}

void push(Stack s, int v) {
    Position tmp = malloc(sizeof(Node));
    tmp->next = s->next;
    tmp->data = v;
    s->next = tmp;
}

int pop(Stack s, int *v) {
    Position tmp = s->next;
    if (s->next == NULL) {
        return -1;
    }
    *v = tmp->data;
    free(tmp);
    s->next = s->next->next;
    return 0;
}

int peek(Stack s, int *v) {
    Position tmp = s->next;
    if (s->next == NULL) {
        return -1;
    }
    *v = tmp->data;
    return 0;
}

void printStack(Stack s) {
    Position tmp = s->next;
    while( tmp !=  NULL) {
        printf("%4d", tmp->data);
        tmp = tmp->next;
    }
    printf("\n");
}

// 用两个栈模拟队列 - 低效
// void enQueue(Stack s1, Stack s2, int v) {
//     push(s1, v);
// }
// int deQueue(Stack s1, Stack s2, int *v) {
//     int ret;
//     int status;
//     status = peek(s1, &ret);
//     if (status == -1) {
//         return -1;
//     }
//     while(pop(s1, &ret) != -1) {
//         push(s2, ret);
//     }
//     pop(s2, &ret);
//     *v = ret;
//     while(pop(s2, &ret) != -1) {
//         push(s1, ret);
//     }
//     return 0;
// }
// 用两个栈模拟队列 - 高效
void enQueue(Stack s1, Stack s2, int v) {
    push(s1, v);
}
int deQueue(Stack s1, Stack s2, int *v) {
    int ret;
    int status;
    status = peek(s2, &ret);
    if (status == -1) {
        status = peek(s1, &ret);
        if (status == -1) {
            return -1;
        }
        while(pop(s1, &ret) != -1) {
            push(s2, ret);
        }
    }
    pop(s2, &ret);
    *v = ret;
    return 0;
}

int main(void) {
    Stack s;
    Stack s2;
    int ret;
    
    initStack(&s);
    initStack(&s2);
    push(s, 3);
    push(s, 8);
    push(s, 2);
    printStack(s);
    
    pop(s, &ret);
    printf("%d\n", ret);
    pop(s, &ret);
    printf("%d\n", ret);
    pop(s, &ret);
    printf("%d\n", ret);
    
    enQueue(s, s2, 33);
    enQueue(s, s2, 22);
    enQueue(s, s2, 66);
    printStack(s);
    
    deQueue(s, s2, &ret);
    printf("%d\n", ret);
    deQueue(s, s2, &ret);
    printf("%d\n", ret);
    deQueue(s, s2, &ret);
    printf("%d\n", ret);

    return 0;
}

用队列实现栈

思路:队列1用于入栈,出栈时把所有元素减一搬入队列2,并把最后一个元素出队,然后再把所有元素放入队列1。

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

typedef struct NodeStruct {
    int data;
    struct NodeStruct* next;
} Node, *Position, *Queue;

void initQueue(Queue *q) {
    *q = malloc(sizeof(Node));
    (*q)->next = NULL;
}

void enQueue(Queue q, int v) {
    Position tmp = malloc(sizeof(Node));
    tmp->next = q->next;
    tmp->data = v;
    q->next = tmp;
}

int deQueue(Queue q, int *v) {
    Position prev = q;
    Position tmp = q->next;
    if (tmp == NULL) {
        return -1;
    }
    while (tmp->next != NULL) {
        prev = prev->next;
        tmp = prev->next;
    }
    *v = tmp->data;
    free(tmp);
    prev->next = NULL;
    return 0;
}

int peek(Queue q, int *v) {
    Position tmp = q->next;
    if (tmp == NULL) {
        return -1;
    }
    while (tmp->next != NULL) {
        tmp = tmp->next;
    }
    *v = tmp->data;
    return 0;
}

void printQueue(Queue q) {
    Position tmp = q->next;
    while (tmp != NULL) {
        printf("%4d", tmp->data);
        tmp = tmp->next;
    }
    printf("\n");
}

// 用两个队列模拟栈的效果
void push(Queue q1, Queue q2, int v) {
    enQueue(q1, v);
}
int pop(Queue q1, Queue q2, int *v) {
    Position tmp;
    int i, ret, count = 0;
    if (tmp == NULL) {
        return -1;
    }
    while (deQueue(q1, &ret) != -1) {
        count++;
        enQueue(q2, ret);
    }
    for (i = 0; i < count - 1; i++) {
        deQueue(q2, &ret);
        enQueue(q1, ret);
    }
    deQueue(q2, &ret);
    *v = ret;
    
    return 0;
}

int main(void) {
    Queue q, q2;
    int ret, status;
    
    initQueue(&q);
    initQueue(&q2);
    enQueue(q, 3);
    enQueue(q, 9);
    enQueue(q, 2);
    printQueue(q);
    
    deQueue(q, &ret);
    printf("%d\n", ret);
    deQueue(q, &ret);
    printf("%d\n", ret);
    deQueue(q, &ret);
    printf("%d\n", ret);
    
    push(q, q2, 3);
    push(q, q2, 9);
    push(q, q2, 2);
    printQueue(q);
    pop(q, q2, &ret);
    printf("%d\n", ret);
    pop(q, q2, &ret);
    printf("%d\n", ret);
    pop(q, q2, &ret);
    printf("%d\n", ret);

    return 0;
}
发布了295 篇原创文章 · 获赞 158 · 访问量 101万+

猜你喜欢

转载自blog.csdn.net/kikajack/article/details/99887730