数据结构3 - 栈与队列

一、内存分区

1、栈区(stack): —由编译器自动分配释放,存放函数的参数值,局部变量的值等。

2、堆区(heap): 一般由程序员分配释放,若程序员不释放,程序结束时由系统释放。

3、全局区(静态区,static): 全局变量和静态变量的存储是放在一块的,初始化的全局变量和静态变量在一块区域,未初始化
的全局变量和未初始化的静态变量在相邻的另一块区域。程序结束后由系统释放。

4、文字常量区: 常量字符串就是放在这里的。程序结束后由系统释放。

5、程序代码区: 存放函数体的二进制代码。

二、栈 - Stack

定义:一种可以实现 先进后出 的数据结构

1. 栈(stack)又名堆栈,它是一种运算受限的线性表。
2. 其限制是仅允许在表的一端进行插入和删除运算。
3. 这一端被称为栈顶,相对地,把另一端称为栈底。
4. 向一个栈插入新元素又称作进栈、入栈或压栈,它是把新元素放到栈顶元素的上面,使之成为新的栈顶元素。
5. 从一个栈删除元素又称作出栈或退栈,它是把栈顶元素删除掉,使其相邻的元素成为新的栈顶元素。

分类:

1. 静态栈
2. 动态栈

操作:

1. push	进栈(入栈,压栈)	
2. pop	出栈					

三、队列 - Queue

定义:一种可以实现 先进先出 的数据结构

操作:

1. enQueue	进栈(入栈,压栈)	
2. outQueue	出栈

以链表为内核实现循环队列:

//
//  main.c
//  循环队列
//
//  Created by zhengbing on 2017/5/2.
//  Copyright © 2017年 zhengbing. All rights reserved.
//

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

// 队列的结构体
struct Queue {
    int * pBase;    // 参考指针
    int * front;      // 前指针
    int * rear;       // 尾指针
};
// 声明
void init(struct Queue *q);
void enQueue(struct Queue * q, int i);
void outQueue(struct Queue * q);
void traverse(struct Queue * q);

int main(int argc, const char * argv[]) {

    // 初始化一个队列
    struct Queue q;
    init(&q);
    // 进队
    enQueue(&q, 1);
    enQueue(&q, 2);
    enQueue(&q, 3);
    enQueue(&q, 4);
    enQueue(&q, 5);
    enQueue(&q, 6);
    enQueue(&q, 7);
    // 出队
    outQueue(&q);
    // 遍历输出队列里面的元素
    traverse(&q);

    // 进队
    enQueue(&q, 8);
    enQueue(&q, 9);
    enQueue(&q, 10);
    // 遍历输出队列里面的元素
    traverse(&q);

    return 0;
}

// 实现
void init(struct Queue *q){
    q->pBase =(int *)malloc(sizeof(int)*6);
    q->front = q->pBase;
    q->rear = q->pBase;
}

// 判断一个队列是否为空
bool isEmpty(struct Queue * q){
    if (q->front == q->rear) {
        return true;
    }else{
        return false;
    }
}
// 判断一个队列是否满了
bool isFull(struct Queue * q){
    if ((q->rear+1 == q->front) || (q->rear - q->front) == 5) {
        return true;
    }else{
        return false;
    }
}

void enQueue(struct Queue * q, int i){
    if (isFull(q)) {
        // 队列已经满了,不能再放入元素了
        printf("队列已经满了,不能再放入元素了\n");
        return;
    }else{
        *q->rear = i; // 进队的时候,
        if (q->rear - q->pBase == 5) {
            q->rear = q->pBase;
        }else{
            q->rear = q->rear + 1;
        }
    }
    printf("q->pBase = %p, q->front = %p, q->rear = %p, 差 = %ld \n", q->pBase, q->front, q->rear,(q->rear-q->pBase));
}
void outQueue(struct Queue * q){
    if (isEmpty(q)) {
        printf("队列是空队列,没有元素可以出队。 \n");
        return;
    }
    printf("出队的元素是:%d \n", *q->front); // 最前面的元素要出队
    if (q->front - q->pBase == 5) {
        q->front = q->pBase;
    }else{
        q->front = q->front + 1;
    }
}
void traverse(struct Queue * q){
    printf("当前队列元素有:\n");
    if (isEmpty(q)) {
        printf("没有元素可以遍历 \n");
        return;
    }
    int *temp = q->front;
    while (temp != q->rear) {
        printf("%d \n", *temp);
        if (temp - q->pBase == 5) {
            temp = q->pBase;
        }else{
            temp = temp + 1;
        }
    }
}

以数组为内核实现循环队列:

//
//  main.c
//  循环队列
//
//  Created by zhengbing on 2017/5/2.
//  Copyright © 2017年 zhengbing. All rights reserved.
//

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

// 队列的结构体
struct Queue {
    int * pBase;    // 参考指针
    int front;      // 队头元素的下标
    int rear;       // 队尾元素的下标
};
// 声明
void init(struct Queue *q);
void enQueue(struct Queue * q, int i);
void outQueue(struct Queue * q);
void traverse(struct Queue * q);

int main(int argc, const char * argv[]) {

    // 初始化一个队列
    struct Queue q;
    init(&q);
    // 进队
    enQueue(&q, 1);
    enQueue(&q, 2);
    enQueue(&q, 3);
    enQueue(&q, 4);
    enQueue(&q, 5);
    enQueue(&q, 6);
    enQueue(&q, 7);
    // 出队
    outQueue(&q);
    // 遍历输出队列里面的元素
    traverse(&q);

    enQueue(&q, 6);
    enQueue(&q, 7);
    traverse(&q);

    return 0;
}

// 实现
void init(struct Queue *q){
    q->pBase =(int *)malloc(sizeof(int)*6);
    q->front = 0;
    q->rear = 0;
}

// 判断一个队列是否为空
bool isEmpty(struct Queue * q){
    if (q->front == q->rear) {
        return true;
    }else{
        return false;
    }
}
// 判断一个队列是否满了
bool isFull(struct Queue * q){
    if ((q->rear + 1)%6 == q->front) {
        return true;
    }else{
        return false;
    }
}

void enQueue(struct Queue * q, int i){
    if (isFull(q)) {
        // 队列已经满了,不能再放入元素了
        return;
    }else{
        q->pBase[q->rear] = i; // 进队的时候,
        q->rear = (q->rear+1)%6; // 尾指向下一个位置
    }
}
void outQueue(struct Queue * q){
    if (isEmpty(q)) {
        printf("队列是空队列,没有元素可以出队。 \n");
        return;
    }
    printf("出队的元素是:%d \n", q->pBase[q->front]); // 最前面的元素要出队
    q->front = (q->front + 1)%6;
}
void traverse(struct Queue * q){
    printf("当前队列元素为:\n");
    if (isEmpty(q)) {
        printf("没有元素可以遍历 \n");
        return;
    }
    int temp = q->front;
    while ((temp)%6 != q->rear) {
        int p = q->pBase[temp];
        printf("%d \n", p);
        temp = (temp + 1)%6;
    }
}

posted @ 2017-04-26 23:05  磨刀石  阅读(252)  评论(0编辑  收藏  举报