数据结构(2)—— 栈和队列

来源:互联网 发布:小区开门软件 编辑:程序博客网 时间:2024/05/21 17:18

1 栈的两种物理结构实现

堆栈基本特征: 先进后出,后进先出(类似垃圾箱)
栈顶指针用来记录最后进入数据的位置。

1.1 栈的顺序结构实现

/*栈练习,顺序存储结构实现*/#include<stdio.h>#include<stdbool.h>int stack[10];int size;//表示栈中有效数据个数//判断是否为空bool is_empty(){    return !size;}//判断是否为满bool is_full(){    return size == 10;}//初始化void init(){}//销毁void destroy(){    size = 0;}//加入数据(压入)void push(int num){    stack[size] = num;    size++;}//拿出数据(弹出)void pop(){    size--;}//获取数据int peak(){    return stack[size - 1];}int main(){    push(1);    push(2);    push(3);    printf("%-3d",peak());    pop();    printf("%-3d",peak());    pop();    push(4);    printf("%-3d",peak());    pop();    printf("%-3d",peak());    pop();    printf(is_empty()?"空\n":"非空\n");    return 0;}

1.2 栈的链式结构实现

/*栈练习,链式存储结构实现*/#include<stdio.h>#include<stdbool.h>#include<stdlib.h>typedef struct node{    int num;    struct node *p_next;}node;void pop();node head;//头结点//判断是否为空bool is_empty(){    return !head.p_next;}//判断是否为满bool is_full(){    return false;}//初始化void init(){}//销毁void destroy(){    while (head.p_next){        pop();    }}//加入数据(压入)void push(int num){    node *p_node = (node *)malloc(sizeof(node));    if (!p_node){        return;    }    p_node->num = num;    p_node->p_next = head.p_next;    head.p_next = p_node;}//拿出数据(弹出)void pop(){    if (head.p_next){        node *p_tmp = head.p_next;        head.p_next = p_tmp->p_next;        free(p_tmp);        p_tmp = NULL;    }}//获取数据int peak(){    if (head.p_next){        return head.p_next->num;    }    else {        return -1;    }}int main(){    push(1);    push(2);    push(3);    printf("%d ",peak());    pop();    printf("%d ",peak());    pop();    push(4);    printf("%d ",peak());    pop();    printf("%d ",peak());    pop();    printf(is_empty()?"空\n":"非空\n");    destroy();//必须释放内存,否则就会造成内存泄漏    return 0;}

2 队列的两种物理结构实现

队列的基本特征:先进先出(FIFO)。
所有数据有两个端点,一端输入数字另一端输出数字。

2.1 队列的顺序结构实现

/*顺序结构实现队列*/#include<stdio.h>#include<stdbool.h>int queue[10];int head,tail;//head记录下一个要拿的数据的下标,tail记录下一个要放的数据的下标bool is_empty(){    return head == tail;}bool is_full(){    return tail > 9;}void init(){    head = 0;    tail = 0;}void destroy(){    head = 0;    tail = 0;}void push(int num){    queue[tail] = num;    tail++;}void pop(){    head++;}int peak(){    return queue[head];}int main(){    int num = 1;    while (!is_full()){        push(num);        num++;    }           while (!is_empty()){        printf("%d ",peak());        pop();    }    printf("\n");    printf(is_full() ? "满\n" : "不满\n");    return 0;}

  这个队列的实现,还存在缺陷,head和tail都只能加,不能减,不能实现现实中的真正的队列,像这里最后明明是空的,但是却判断为满,而不能再用,怎么改一下呢?

/*顺序结构实现循环队列*/#include<stdio.h>#include<stdbool.h>int queue[3];int head,tail,size;//head记录下一个要拿的数据的下标,tail记录下一个要放的数据的下标bool is_empty(){    return !size;}bool is_full(){    return size == 3;}void init(){    head = 0;    tail = 0;    size = 0;}void destroy(){    head = 0;    tail = 0;    size = 0;}void push(int num){    queue[tail] = num;    tail = (tail + 1) % 3;    size++;}void pop(){    head = (head + 1) % 3;    size--;}int peak(){    return queue[head];}int main(){    int num = 1;    while (!is_full()){        push(num);        num++;    }           while (!is_empty()){        printf("%d ",peak());        pop();    }    printf("\n");    printf(is_full() ? "满\n" : "不满\n");    for (num = 1;num <= 3;num++){        push(num);    }    while (!is_empty()){        printf("%d ",peak());        pop();    }    printf("\n");    return 0;}

2.2 队列的链式结构实现

/*队列练习,链式结构实现*/#include<stdio.h>#include<stdbool.h>#include<stdlib.h>typedef struct node{    int num;    struct node *p_next;}node;node head;void pop();bool is_empty(){    return !head.p_next;}bool is_full(){    return false;}void init(){}void destroy(){    while (head.p_next){        pop();    }}void push(int num){    node *p_tmp = &head;    node *p_node = (node *)malloc(sizeof(node));    p_node->num = num;    p_node->p_next = NULL;    while (p_tmp->p_next){        p_tmp = p_tmp->p_next;    }    p_tmp->p_next = p_node;}void pop(){    if (head.p_next){        node *p_tmp = head.p_next;        head.p_next = p_tmp->p_next;        free(p_tmp);        p_tmp = NULL;    }}int peak(){    if (head.p_next){        return head.p_next->num;    }    else {        return -1;    }}int main(){    init();    push(1);    push(2);    push(3);    printf("%d ",peak());    pop();    printf("%d ",peak());    pop();    printf("%d\n",peak());    printf(is_empty() ? "空\n" : "非空\n");    destroy();    return 0;}

  最后,还有个好玩的,就是用堆栈来实现队列,这个怎么做呢?
  我们可以申请两个堆栈,堆栈1用于输入,堆栈2用于输出。压入时只管往堆栈1中push,弹出的时候,就要注意了。在堆栈2为NULL时,倒数据,并把堆栈1中的数据倒空,然后直至弹空后,可再往堆栈2中倒数据。

0 0