线性表的顺序表示和基本操作的实现

本文介绍了一种使用C语言实现顺序表的基本操作方法,包括初始化、插入、删除等,并通过具体示例展示了如何进行这些操作。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

//库函数头文件包含
#include <stdio.h>
#include <malloc.h>
#include <stdlib.h>
#include <string.h>

//函数状态码定义
#define TRUE        1
#define FALSE       0
#define OK          1
#define ERROR       0
#define INFEASIBLE -1
#define OVERFLOW   -2

typedef int  Status;

//顺序表的存储结构定义
#define LIST_INIT_SIZE  100
#define LISTINCREMENT   10

typedef int ElemType;   //假设线性表中的元素均为整型

typedef struct{
    ElemType* elem;     //存储空间基地址
    int length;         //表中元素的个数
    int listsize;       //表容量大小
}SqList;                //顺序表类型定义


//构造一个空的线性表L
Status InitList(SqList &L){
    L.elem = (ElemType *)malloc(LIST_INIT_SIZE * sizeof(ElemType));        //开辟一段空间

    if(!L.elem)
        exit(OVERFLOW);             //储存分配失败

    L.length = 0;                   //空表长度为0
    L.listsize = LIST_INIT_SIZE;    //初始储存容量

    return OK;
}

//向线性表末尾中插入一个元素
Status InsertList(SqList &L, ElemType e){
    if(L.length >= L.listsize){                     //当储存空间已经满了的时候,要重新开辟空间
        L.elem = (ElemType *)realloc(L.elem, (L.listsize + LISTINCREMENT) * sizeof(ElemType));
        if(!L.elem)
            exit(OVERFLOW);
        L.listsize += LISTINCREMENT;
    }

    *(L.elem + L.length) = e;
    ++L.length;
    return OK;
}

//销毁线性表L。
Status DestroyList(SqList &L){
    if(L.elem)
        free(L.elem);               //释放L.elem

    L.elem = NULL;                  //将L.elem赋值为空

    return OK;
}

//将线性表重置为空表
Status ClearList(SqList &L){
    L.length = 0;                   //只需将元素的个数赋值为0就相当于重置为空表不需要关注里面的内容
    return OK;
}

//判断线性表是否为空
Status ListEmpty(SqList L){
    if(L.length = 0)
        return TRUE;                //如果元素个数为0就返回TRUE
    return FALSE;                   //否则返回FALSE
}

//获得L中数据元素个数
int ListLength(SqList L){
    return L.length;                //直接返回元素个数就可以
}


//获得线性表中第i个元素的值
Status GetElem(SqList L, int i, ElemType &e){
    if(i > L.length)                //如果i超出所存值的范围,就找不到第i个值,返回ERROR
        return ERROR;

    e = *(L.elem + i);
    return OK;
}

bool com(ElemType e1, ElemType e2){
    if(e2 > e1)
        return true;
    else
        return false;
}

//返回L中第一个与e满足关系compare()的数据元素的位序。
int LocateElem(SqList L, ElemType e, bool (*compare)(ElemType e1, ElemType e2)){
    int location;
    int flag = 0;
    for(location = 0; location < L.length; ++location){
        if(compare(e, *(L.elem + location))){
            flag = 1;
            break;
        }
    }
    if(flag == 1)
        return location + 1;
    else
        return -2;                      //如果不存在返回一个负值;
}

//若cur_e是L的数据元素,且不是第一个,则用pre_e返回它的前驱,否则操作失败pre_e无定义
Status PriorElem(SqList L, ElemType cur_e, ElemType &pre_e){
    for(int i = 0; i < L.length; ++i){
        if(*(L.elem + i) == cur_e && i != 0){
            pre_e = *(L.elem + i - 1);
            return OK;
        }
    }
    return ERROR;
}


//若cur_e是L的数据元素,且不是最后一个,则用next_e返回它的后继,否则操作失败next_e无定义
Status NextElem(SqList L, ElemType cur_e, ElemType &next_e){
    for(int i = 0; i < L.length; ++i){
        if(*(L.elem + i) == cur_e && i != L.length - 1){
            next_e = *(L.elem + i + 1);
            return OK;
        }
    }
    return ERROR;
}

//在L中第i个位置之前插入一个新的数据元素e,L的长度加1
Status ListInsert(SqList &L, int i, ElemType e){
    if(i < 1 || i > L.length)                       //当输入的i不合法的时候,直接返回ERROR
        return ERROR;

    if(L.length >= L.listsize){                     //当储存空间已经满了的时候,要重新开辟空间
        L.elem = (ElemType *)realloc(L.elem, (L.listsize + LISTINCREMENT) * sizeof(ElemType));
        if(!L.elem)
            exit(OVERFLOW);
        L.listsize += LISTINCREMENT;
    }

    ElemType *p = L.elem + L.length - 1, *q = L.elem + i - 1;

    for(p; p >= q; --p)
        *(p + 1) = *p;

    *q = e;
    ++L.length;
    return OK;
}

//删除L中第i个数据元素,并用e返回其值,L的长度减1
Status ListDelete(SqList &L, int i, ElemType &e){
    if(i < 1 || i > L.length)
        return ERROR;
    ElemType *p = L.elem + i - 1, *q = L.elem + L.length - 1;
    e = *p;
    for(p; p < q; ++p)
        *p = *(p + 1);
    --L.length;
    return OK;
}

Status print(ElemType e){
    printf("%d ", e);
    return OK;
}

//依次对L的每个数据元素调用函数visit()。一旦visit()失败,则操作失败
Status ListTraverse(SqList L, Status (*visit)(ElemType e)){
    ElemType *p = L.elem, *q = L.elem + L.length;
    for(p; p < q; ++p){
        if(visit(*p) != OK)
            return ERROR;
    }
    return OK;
}

//顺序表的就地逆置
void ListReverse_Sq(SqList &L){
    int n = L.length / 2;
    int tp;
    for(int i = 0; i < n; i++){
       tp = *(L.elem + i);
       *(L.elem + i) = *(L.elem + L.length - 1 - i);
       *(L.elem+L.length - 1 - i) = tp;
   }
}


//主函数
int main(){
    int a;
    SqList L;
    InitList(L);

    printf("请输入5个数:\n");
    for(int i = 0; i < 5; ++i){
        scanf("%d", &a);
        InsertList(L, a);
    }

    printf("下面是visit操作结果:\n");
    ListTraverse(L, print);
    putchar('\n');

    printf("下面是ListInsert操作结果:\n");
    ListInsert(L, 2, 5);
    ListTraverse(L, print);
    putchar('\n');

    printf("下面是长度结果:\n");
    printf("%d\n", ListLength(L));

    printf("下面是ListDelete操作结果:\n");
    ListDelete(L, 2, a);
    ListTraverse(L, print);
    putchar('\n');
    printf("%d\n", a);

    printf("下面是NextElem操作结果:\n");
    NextElem(L, 2, a);
    ListTraverse(L, print);
    putchar('\n');
    printf("%d\n", a);

    printf("下面是PriorElem操作结果:\n");
    PriorElem(L, 2, a);
    ListTraverse(L, print);
    putchar('\n');
    printf("%d\n", a);

    printf("下面是LocateElem操作结果:\n");
    a = LocateElem(L, 2, com);
    ListTraverse(L, print);
    putchar('\n');
    printf("%d\n", a);

    printf("下面输出的是逆置后的结果:\n");
    ListReverse_Sq(L);
    ListTraverse(L, print);

    DestroyList(L);
    return 0;
}



下面是对代码的一些测试:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值