ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

数据结构之线性关系的C语言实现过程

2021-11-07 21:02:34  阅读:206  来源: 互联网

标签:Status return 线性关系 SqQueue C语言 base front OK 数据结构


线性表

顺序表、链表

顺序栈

声明过程

#include "constants.h"

#define STACK_INIT_SIZE 20 //顺序栈存储空间的初始分配量
#define STACKINCREMENT 5   //顺序栈存储空间的分配增量

typedef int SElemType;

typedef struct
{
    SElemType *base; //栈底指针,始终指向存储空间的基地址
    SElemType *top;  //栈顶指针,指向栈顶元素的下一个位置
    int stacksize;   //数组存储空间的长度
} SqStack;

Status InitStack(SqStack &S); //构造一个空的栈S

Status StackEmpty(SqStack S); //判断栈S是否是空表,若是,则返回TURE,不是,则返回FALSE

Status StackFull(SqStack S); //判断栈S是否是已满,若是则返回TRUE,否则返回FALSE

int StackLength(SqStack &S); //返回栈S的长度

Status GetTop(SqStack S, SElemType &e); //得到栈S的栈顶元素,并且用变量e带回

Status Push(SqStack &S, SElemType e); //把元素e的值进行入栈操作

Status Pop(SqStack &S, SElemType &e); //出栈操作,出栈的元素用变量e来带回

Status ClearStack(SqStack &S); //重置栈S为空栈

Status StackTraverse(SqStack S, Status (*visit)(SElemType)); //依次对栈S中的每个元素调用visit进行访问

Status DestroyStack(SqStack &S); //销毁栈S,可能的话释放其空间

Status visit_read(SElemType e); //访问函数

Status Adjust(SqStack &S); //扩大栈S的最大存储空间

实现过程

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

Status InitStack(SqStack &S)
{
    S.base = (SElemType *)malloc(STACK_INIT_SIZE * sizeof(SElemType));
    //栈的连续空间分配
    if (!S.base)
        exit(OVERFLOW);
    S.top = S.base; //空栈,初始化栈顶指针
    S.stacksize = STACK_INIT_SIZE;
    return OK;
}

Status StackEmpty(SqStack S)
{
    /* return S.top == S.base ? TRUE : FALSE; */
    return S.top == S.base;
}

Status StackFull(SqStack S)
{
    return S.top - S.base == S.stacksize;
}

int StackLength(SqStack &S)
{
    return S.top - S.base;
}

//Attention!!   top指针指向的是栈顶元素的下一个位置
Status GetTop(SqStack S, SElemType &e)
{
    /* if (!StackEmpty(S))
    {
        e = *(S.top - 1);
        return OK;
    }
    else
        return ERROR; */
    if (S.top == S.base)
        return ERROR;
    else
    {
        e = *(S.top - 1);
        return OK;
    }
}

//*和++运算符都是同级的,自右向左。
Status Push(SqStack &S, SElemType e)
{
    if (StackFull(S))
        Adjust(S);
    *S.top++ = e;
    return OK;
}

//不能用*S.top--,而应该用*--S.top。因为top指向栈顶元素的下一个元素
Status Pop(SqStack &S, SElemType &e)
{
    if (StackEmpty(S))
        return ERROR;
    else
    {
        e = *--S.top;
        return OK;
    }
}

Status ClearStack(SqStack &S)
{
    S.top = S.base;
    return OK;
}

Status StackTraverse(SqStack S, Status (*visit)(SElemType))
{
    /* if (StackEmpty(S))
        return ERROR;
    else
    {
        SElemType *p = S.base;
        while (p != S.top)
        {
            if (!visit(*p))
                return ERROR;
            p++;
        }
        return OK;
    } */
    SElemType *p;
    for (p = S.base; p < S.top; p++)
        if (!visit(*p))
            return ERROR;
    return OK;
}

Status DestroyStack(SqStack &S)
{
    if (S.base)
        free(S.base);
    S.base = NULL;
    return OK;
}

Status visit_read(SElemType e)
{
    printf("%d ", e);
    return OK;
}

Status Adjust(SqStack &S)
{
    S.base = (SElemType *)realloc(S.base, (S.stacksize + STACKINCREMENT) * sizeof(SElemType));
    if (!S.base)
        exit(OVERFLOW);
    S.top = S.base + S.stacksize;
    S.stacksize += STACKINCREMENT;
    return OK;
}

链栈

声明过程

#include "constants.h"

typedef int SElemType;

typedef struct Snode
{
    SElemType data;
    struct Snode *next;
} SNode, *LinkStack;

Status InitStack(LinkStack &S); //构造一个空的栈S

Status StackEmpty(LinkStack S); //判断栈S是否是空表,若是,则返回TURE,不是,则返回FALSE

int StackLength(LinkStack &S); //返回栈S的长度

Status GetTop(LinkStack S, SElemType &e); //得到栈S的栈顶元素,并且用变量e带回

Status Push(LinkStack &S, SElemType e); //把元素e的值进行入栈操作

Status Pop(LinkStack &S, SElemType &e); //出栈操作,出栈的元素用变量e来带回

Status ClearStack(LinkStack &S); //重置栈S为空栈

Status StackTraverse(LinkStack S, Status (*visit)(SElemType)); //依次对栈S中的每个元素调用visit进行访问

Status DestroyStack(LinkStack &S); //销毁栈S,可能的话释放其空间

Status visit_read(SElemType e); //访问函数

实现过程 

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

//S(linkstack)是头指针(一个S代表一个链栈),它指向栈顶元素所在节点
Status InitStack(LinkStack &S)
{
    S = (LinkStack)malloc(sizeof(SNode *));
    if (!S)
        exit(OVERFLOW);
    S = NULL;
    return OK;
}

Status StackEmpty(LinkStack S)
{
    return S == NULL ? TRUE : FALSE;
}

int StackLength(LinkStack &S)
{
    int len = 0;
    SNode *p = S;
    while (p)
    {
        p = p->next;
        len++;
    }
    return len;
}

Status GetTop(LinkStack S, SElemType &e)
{
    if (!S)
        return ERROR;
    else
    {
        e = S->data;
        return OK;
    }
}

Status Push(LinkStack &S, SElemType e)
{
    SNode *p = (SNode *)malloc(sizeof(SNode));
    if (!p)
        exit(OVERFLOW);
    p->data = e;
    p->next = S;
    S = p;
    return OK;
}

Status Pop(LinkStack &S, SElemType &e)
{
    if (!S)
        return ERROR;
    else
    {
        SNode *p = S;
        e = p->data;
        S = p->next;
        free(p);
        return OK;
    }
}

Status ClearStack(LinkStack &S)
{
    while (S)
    {
        SNode *p = S;
        S = p->next;
        free(p);
    }
    return OK;
}

Status StackTraverse(LinkStack S, Status (*visit)(SElemType))
{
    SNode *p = S;
    while (p)
    {
        if (!visit(p->data))
            return ERROR;
        p = p->next;
    }
    return OK;
}

Status DestroyStack(LinkStack &S)
{
    ClearStack(S);
    free(S);
    return OK;
}

Status visit_read(SElemType e)
{
    printf("%d ", e);
    return OK;
}

顺序队列

声明过程

#include "constants.h"

#define MAXQSIZE 100

typedef int QElemType;

typedef struct
{
    QElemType *base; //存储空间基地址
    int front;       //队头指针,指向队头元素
    int rear;        //队尾指针,指向队尾元素的下一个位置
} SqQueue;

Status InitQueue(SqQueue &Q);//初始化一个顺序空队列

Status QueueEmpty(SqQueue Q);//判断该顺序队列是否为空

int QueueLength(SqQueue Q);//返回顺序队列的长度

Status GetHead(SqQueue Q, QElemType &e);//得到队头元素,并用e带回

Status EnQueue(SqQueue &Q, QElemType e);//入队

Status DeQueue(SqQueue &Q, QElemType &e);//出队

Status ClearQueue(SqQueue &Q);//清空队列

Status QueueTraverse(SqQueue Q, Status (*Visit)(QElemType));//遍历队列

Status DestroyQueue(SqQueue &Q);//销毁队列

Status Visit(QElemType e);

实现过程

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

Status InitQueue(SqQueue &Q)
{
    Q.base = (QElemType *)malloc(MAXQSIZE * sizeof(QElemType));
    if (!Q.base)
        exit(OVERFLOW);
    Q.front = Q.rear = 0;
    return OK;
}

Status QueueEmpty(SqQueue Q)
{
    return Q.rear == Q.front;
}

int QueueLength(SqQueue Q)
{
    return Q.rear - Q.front;
}

Status GetHead(SqQueue Q, QElemType &e)
{
    e = Q.base[Q.front];
    return OK;
}

Status EnQueue(SqQueue &Q, QElemType e)
{
    Q.base[Q.rear++] = e;
    return OK;
}

Status DeQueue(SqQueue &Q, QElemType &e)
{
    e = Q.base[Q.front++];
    return OK;
}

Status ClearQueue(SqQueue &Q)
{
    Q.front = Q.rear = 0;
    return OK;
}

Status QueueTraverse(SqQueue Q, Status (*Visit)(QElemType))
{
    int i;
    for (i = Q.front; i < Q.rear; i++)
        if (!Visit(Q.base[i]))
            return ERROR;
    return OK;
}

Status DestroyQueue(SqQueue &Q)
{
    free(Q.base);
    return OK;
}

Status Visit(QElemType e)
{
    printf("%d ", e);
    return OK;
}

循环队列

假若循环队列的实现与顺序队列相同的话,那么在队列判空和判满时,条件相同,出现矛盾。为了解决这个问题,共有三种方案。

声明过程 

#include "constants.h"

#define MAXQSIZE 100

typedef int QElemType;

typedef struct
{
    QElemType *base; //存储空间基地址
    int front;       //队头指针,指向队头元素
    int rear;        //队尾指针,指向队尾元素的下一个位置
} SqQueue;

Status InitQueue(SqQueue &Q);//初始化一个顺序空队列

Status QueueEmpty1(SqQueue Q);//判断该顺序队列是否为空

int QueueLength(SqQueue Q);//返回顺序队列的长度

Status GetHead(SqQueue Q, QElemType &e);//得到队头元素,并用e带回

Status EnQueue(SqQueue &Q, QElemType e);//入队

Status DeQueue(SqQueue &Q, QElemType &e);//出队

Status ClearQueue(SqQueue &Q);//清空队列

Status QueueTraverse(SqQueue Q, Status (*Visit)(QElemType));//遍历队列

Status DestroyQueue(SqQueue &Q);//销毁队列

Status Visit(QElemType e);

Status QueueFull(SqQueue Q);//判断队列是否已满

实现过程

//方案一
#include "CSqQueue.h"
#include <stdio.h>
#include <stdlib.h>

Status InitQueue(SqQueue &Q)
{
    Q.base = (QElemType *)malloc(MAXQSIZE * sizeof(QElemType));
    if (!Q.base)
        exit(OVERFLOW);
    Q.front = Q.rear = 0;
    return OK;
}

int QueueLength(SqQueue Q)
{
    return (Q.rear + MAXQSIZE - Q.front) % MAXQSIZE;
}

//基地址所指向的空间不存储数据
Status QueueEmpty1(SqQueue Q)
{
    return Q.front == Q.rear;
}

Status GetHead(SqQueue Q, QElemType &e)
{
    if (QueueEmpty1(Q))
        return ERROR;
    else
    {
        e = Q.base[Q.front];
        return OK;
    }
}

Status EnQueue(SqQueue &Q, QElemType e)
{
    if (QueueFull(Q))
        return ERROR;
    else
    {
        Q.base[Q.rear] = e;
        Q.rear = (Q.rear + 1) % MAXQSIZE;
        return OK;
    }
}

Status DeQueue(SqQueue &Q, QElemType &e)
{
    if (QueueEmpty1(Q))
        return ERROR;
    else
    {
        e = Q.base[Q.front];
        Q.front = (Q.front + 1) % MAXQSIZE;
        return OK;
    }
}

Status ClearQueue(SqQueue &Q)
{
    Q.front = Q.rear;
    return OK;
}

Status QueueTraverse(SqQueue Q, Status (*Visit)(QElemType))
{
    int i = Q.front;
    while (i != Q.rear)
    {
        if (Visit(Q.base[i]))
            i = (i + 1) % MAXQSIZE;
        else
            return ERROR;
    }
    return OK;
}

/* free函数与malloc函数配对使用,释放malloc函数申请的动态内存。
对于free(p)这句语句,如果p时空指针,那么free对p无论操作多少次都不会出问题;
如果p不是NULL指针,那么free对p连续操作两次就会导致程序运行错误。 */
Status DestroyQueue(SqQueue &Q)
{
    if (Q.base)
        free(Q.base);
    Q.base = NULL;
    return OK;
}

Status Visit(QElemType e)
{
    printf("%d ", e);
    return OK;
}

Status QueueFull(SqQueue Q)
{
    return Q.front == (Q.rear + 1) % MAXQSIZE;
}
//方案二
#include "CSqQueue.h"
#include <stdlib.h>
#include <stdio.h>

Status InitQueue(SqQueue &Q)
{
    Q.base = (QElemType *)malloc(MAXQSIZE * sizeof(QElemType));
    if (!Q.base)
        exit(OVERFLOW);
    Q.front = Q.rear = 0;
    Q.tag = 0;
    return OK;
}

Status QueueEmpty2(SqQueue Q)
{
    return Q.front == Q.rear && Q.tag == 0;
}

int QueueLength(SqQueue Q)
{
    return (Q.rear + MAXQSIZE - Q.front) % MAXQSIZE;
}

Status GetHead(SqQueue Q, QElemType &e)
{
    if (QueueEmpty2(Q))
        return ERROR;
    e = Q.base[Q.front];
    return OK;
}

Status EnQueue(SqQueue &Q, QElemType e)
{
    if (QueueFull(Q))
        return ERROR;
    Q.base[Q.rear] = e;
    Q.rear = (Q.rear + 1) % MAXQSIZE;
    Q.tag = 1;
    return OK;
}

Status DeQueue(SqQueue &Q, QElemType &e)
{
    if (QueueEmpty2(Q))
        return ERROR;
    e = Q.base[Q.front];
    Q.front = (Q.front + 1) % MAXQSIZE;
    Q.tag = 0;
    return OK;
}

Status ClearQueue(SqQueue &Q)
{
    Q.rear = Q.front;
    return OK;
}

Status QueueTraverse(SqQueue Q, Status (*Visit)(QElemType))
{
    int i = Q.front;
    while (i != Q.rear)
    {
        if (Visit(Q.base[i]))
            i = (i + 1) % MAXQSIZE;
        else
            return ERROR;
    }
    return OK;
}

Status DestroyQueue(SqQueue &Q)
{
    if (!Q.base)
        free(Q.base);
    Q.base = NULL;
    return OK;
}

Status Visit(QElemType e)
{
    printf("%d ", e);
    return OK;
}

Status QueueFull(SqQueue Q)
{
    return Q.front == Q.rear && Q.tag == 1;
}
//方案三
#include "CSqQueue.h"
#include <stdio.h>
#include <stdlib.h>

Status InitQueue(SqQueue &Q)
{
    Q.base = (QElemType *)malloc(MAXQSIZE * sizeof(QElemType));
    if (!Q.base)
        exit(OVERFLOW);
    Q.front = 0;
    Q.length = 0;
    return OK;
}

Status QueueEmpty3(SqQueue Q)
{
    return Q.length == 0;
}

int QueueLength(SqQueue Q)
{
    return Q.length;
}

Status GetHead(SqQueue Q, QElemType &e)
{
    if (QueueEmpty3(Q))
        return ERROR;
    e = Q.base[Q.front];
    return OK;
}

Status EnQueue(SqQueue &Q, QElemType e)
{
    if (QueueFull(Q))
        return ERROR;
    Q.base[Q.front] = e;
    Q.front = (Q.front + 1) % MAXQSIZE;
    Q.length++;
    return OK;
}

Status DeQueue(SqQueue &Q, QElemType &e)
{
    if (QueueEmpty3(Q))
        return ERROR;
    e = Q.base[Q.front + Q.length - 1];
    Q.length--;
    return OK;
}

Status ClearQueue(SqQueue &Q)
{
    Q.length = 0;
    return OK;
}

Status QueueTraverse(SqQueue Q, Status (*Visit)(QElemType))
{
    int sign = Q.front;
    for (int i = 0; i < Q.length; i++)
    {
        if (Visit(Q.base[sign]))
            sign = (sign + 1) % MAXQSIZE;
        else
            return ERROR;
    }
    return OK;
}

Status DestroyQueue(SqQueue &Q)
{
    if (!Q.base)
        free(Q.base);
    Q.base = NULL;
    return OK;
}

Status Visit(QElemType e)
{
    printf("%d ", e);
    return OK;
}

Status QueueFull(SqQueue Q)
{
    return Q.length == MAXQSIZE;
}

链式队列

声明过程

//若无法估计所使用队列的长度,则使用链队列
#include "constants.h"

typedef int QElemType;

typedef struct QNode
{
    QElemType data;
    struct QNode *next;
} QNode, *QueuePtr;

typedef struct
{
    QueuePtr front;//指向链式队列的头结点(链式队列的头结点的指针域指向队头结点)
    QueuePtr rear;//指向链式队列的尾结点
} LinkQueue;

Status InitQueue(LinkQueue &Q);//初始化一个空链队列

Status QueueEmpty(LinkQueue Q);//判断链队列是否为空

int QueueLength(LinkQueue Q);//返回链队列的长度

Status GetHead(LinkQueue Q, QElemType &e);//得到链队列的队头元素,并且用e来返回

Status EnQueue(LinkQueue &Q, QElemType e);//入队

Status DeQueue(LinkQueue &Q, QElemType &e);//出队

Status ClearQueue(LinkQueue &Q);//清空链队列

Status QueueTraverse(LinkQueue Q, Status (*Visit)(QElemType));//遍历链队列

Status DestroyQueue(LinkQueue &Q);//销毁链队列

Status visit(QElemType e);//读取函数

实现过程

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

Status InitQueue(LinkQueue &Q)
{
    Q.front = Q.rear = (QueuePtr)malloc(sizeof(QNode));
    if (!Q.front)
        exit(OVERFLOW);
    Q.front->next = NULL;
    return OK;
}

Status QueueEmpty(LinkQueue Q)
{
    return Q.front == Q.rear;
}

int QueueLength(LinkQueue Q)
{
    int len = 0;
    QueuePtr p = Q.front->next;
    while (p)
    {
        len++;
        p = p->next;
    }
    return len;
}

Status GetHead(LinkQueue Q, QElemType &e)
{
    if (QueueEmpty(Q))
        return ERROR;
    e = Q.front->next->data;
    return OK;
}

//当链式队列中有新结点加入时,我们要记得更新队列尾结点指针
Status EnQueue(LinkQueue &Q, QElemType e)
{
    QueuePtr p = (QueuePtr)malloc(sizeof(QNode));
    if (!p)
        exit(OVERFLOW);
    p->data = e;
    p->next = NULL;
    Q.rear->next = p;
    Q.rear = p;
    return OK;
}

//如果出队的结点是队尾结点,那么在出队操作前,需要更新队尾指针,让其等于队头指针,即均指向头结点
Status DeQueue(LinkQueue &Q, QElemType &e)
{
    if (QueueEmpty(Q))
        return ERROR;
    QueuePtr p = Q.front->next->next;
    e = Q.front->next->data;
    if (Q.front->next == Q.rear)
        Q.rear = Q.front;
    free(Q.front->next);
    Q.front->next = p;
    return OK;
}

Status ClearQueue(LinkQueue &Q)
{
    Q.front = Q.rear;
    return OK;
}

Status QueueTraverse(LinkQueue Q, Status (*Visit)(QElemType))
{
    QueuePtr p = Q.front->next;
    while (p)
    {
        Visit(p->data);
        p = p->next;
    }
    return OK;
}

Status DestroyQueue(LinkQueue &Q)
{
    if (Q.front)
        free(Q.front);
    Q.front = NULL;
    return OK;
}

Status visit(QElemType e)
{
    printf("%d ", e);
    return OK;
}

标签:Status,return,线性关系,SqQueue,C语言,base,front,OK,数据结构
来源: https://blog.csdn.net/peanutpeanuta/article/details/121196661

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有