栈和队列(基础知识和基本操作)

栈:

1.栈:在表尾进行插入和删除的操作受限的线性表。

2.逻辑结构:线性结构【一对一的关系】

3.存储结构:顺序存储【顺序栈】、链式存储【链栈】

4.栈的特点:先进后出【first in last out FILO表】

后进先出【last in first out LIFO表】

栈空:下标top==-1,栈满:下标top==栈最大长度(MAXSIZE)-1。

栈的删除:头下标的移动,无法实现直接删除下表空间存储的值

链栈:

采用链式存储结构,没有栈满情况,动态申请空间,适用于数据量较大情况

栈和队列(基础知识和基本操作)_第1张图片

 链栈的创建插入删除类似于单向链表的创建插入删除。

队列:

1.队列:在表尾插入,表头删除操作受限的线性表。

2逻辑结构:线性结构【一对一的关系】

3,存储结构:顺序存储【顺序队列、循环队列】、链式存储【链式队列】

4,队列的特点:先进先出【first in first out FIFO表】

后进后出【last in last out LILO表】

顺序队列:

1,线性表长度:数组长度,不变 #define MAXSIZE 8

2, 队头:第一个元素的下表

3,队尾: 最后一个元素后面的下表,原因方便下一个元素的插入

4,队空:队头==队尾

5,队满:rear==MAXSIZE

头定义:

#define MAXSIZE 50
typedef struct
{
    int fornt;//队的头下标
    int rear;//队的尾下标
    int data[MAXSIZE];//元素
}Queue;

循环队列:

队空:front(队头)==rear(队尾)

队满:front(头下标)==(rear(尾下标)+1)%MAXSIZE

栈和队列(基础知识和基本操作)_第2张图片

头定义(类似于顺序队列):

#define MAX_SIZE 50//定义最大存储空间

typedef struct {
    int data[MAX_SIZE];
    int front;
    int rear;
} CircularQueue;

入队:

if(NULL==queue ||queue->front==(queue->rear+1)%MAXSIZE)//队未创建或者队满
    {
    //插入失败
    return -1;
    }
queue->data[queue->rear]=e;
queue->rear=(queue->rear+1)%MAXSIZE;

出队:

int delqueue(QueueList *queue)
{
    if(NULL==queue || queue->front==queue->rear)//判断队列是否创建和是否为空
    {
    //出队失败
    return -1;
    }
    printf("delqueue data is:%d\n",queue->data[queue->front]);
    queue->front=(queue->front+1)%MAXSIZE;//只是下标后移,未进行真正的删除
    return 0;

队列的遍历:

    if(NULL==queue || queue->front==queue->rear)//判断队列是否创建和队列是否为空
    {
        puts("output error");
        return;
    }
    for(int i=queue->front;i!=queue->rear;i=(i+1)%MAXSIZE)//下标从头开始后移逐个输出
    {
        printf("%d\t",queue->data[i]);
    }

 

计算循环队列有几个元素:

int loop_queue_count(QueueList *queue)
{
 return (MAXSIZE-queue->front+queue->rear)%MAXSIZE;
}

链式队列:

先进先出,如果是尾插创建,就需要使用头删删除最先插入的

如果使用头插创建,就需要使用头删删除最先插入的

链式队列的节点创建:

Linklist create_node()
{
    Linklist node=(Linklist)malloc(sizeof(struct Node));
    if(NULL==node)
        return NULL;
    node->data=0;//先定义初值为0
    node->next=NULL;
    return node;//返回地址
}

链式队列的入队:尾插(参考单向不循环链表的尾插)

Linklist insert_rear(datatype e,Linklist L)
{
    //创建你要插入的新节点
    Linklist s=create_node();
    s->data=e;//节点赋初值
    if(L==NULL)
    {
        L=s;
    }
    else
    {
        //rear指向最后一个节点的地址
        Linklist rear=L;
        while(rear->next!=NULL)//循环到最后一个节点
        {
            rear=rear->next;
        }
        rear->next=s;//尾节点指向新建的插入节点,令新建的节点为尾节点,实现尾插
    }
    return L;
}

链式队列的出队:头删(参考单向不循环链表的头删)

Linklist delete_head(Linklist L)
{
    if(NULL==L)//判断链表是否为空
    {
        return L;//为空直接输出空链表
    }
    if(L->next==NULL)//只有一个节点直接释放
    {
        free(L);
        L=NULL;
    }
    else//删除头节点的下一个节点,将值赋给头节点
    {
        Linklist q=L->next;
        L->data=q->data;
        L->next=q->next;
        free(q);
        q=NULL;
    }
    return L;

链式队列的遍历输出:

int link_output(Linklist L)
{
    //判断是否创建
    //判断是否为空
    if(NULL==L)
    {
        return -1;
    }
    while(L!=NULL)
    {
        printf("%d\t",L->data);
        L=L->next;//下标后移
    }
}

你可能感兴趣的:(数据结构,链表,算法,c语言)