数据结构第二章顺序表的基本操作

本文详细介绍了顺序表的概念,它是一种线性表的顺序存储结构,使用连续的内存空间存储元素。文章还给出了顺序表的C语言实现,包括初始化、销毁、清空、判断是否为空、获取表长、按位和按值查找、求前驱和后继元素、插入、删除以及遍历等基本操作。此外,通过示例展示了如何创建并操作顺序表。
摘要由CSDN通过智能技术生成

什么是顺序表? 

     顺序表是线性表的顺序表示,即用一组地址连续的存储单元依次存储线性表的数据元素

顺序表的结构图

 

顺序表的基本操作

定义状态量

#include <stdlib.h>
#include <stdio.h>
#define OK  1
#define ERROR 0
#define OVERFLOW –2
#define TRUE 1
#define FALSE 0
typedef int Status;

定义顺序表的结构体

#define INSTLISTSIZE 10//初始大小
#define INCRESIZE 2//内存不够时,需要增加的大小
typedef int ElemType;//给int型取别名,以至于以后好维护程序
typedef int  ElemType;
typedef struct {
    ElemType *elem;//顺序表主体,可以存储int类型的指针
    int length;//顺序表的大小
    int listsize;//顺序表的容量
}SqList;//顺序表的名字

顺序表的基本操作

//初始化InitList(*L); //构造空线性表L
Status InsitList(SqList *L);
//销毁DestoryList(*L); //销毁线性表L
Status DestoryList(SqList *L);
//清空ClearList(*L); //清空线性表L
Status ClearList(SqList *L);
//判表空ListEmpty(L); //判断线性表是否为空
Status ListEmpty(SqList L);
//求表长Length(L); //求线性表元素个数
Status LengthList(SqList L);
//按位查找GetElem(L,i,*e); //查找位序为i的元素,用e返回
Status GetElem(SqList L,int i,ElemType *e);
//按值查找LocateElem(L,e); //查找元素e,返回第一次出现的位序
Status LocationElem(SqList L,ElemType e);
//求前驱PriorElem(L, cur_e,*pre_e); //用pre_e返回cur_e的前驱
Status PriorElem(SqList L,ElemType cur_e,ElemType *pre_e);
//求后继NextElem(L,cur_e,*next_e);//用next_e返回cur_e的后继
Status NextElem(SqList L,ElemType cur_e,ElemType *next_e);
//插入ListInsert( *L, i, e); //将元素e插入的位置i;
Status ListInsert(SqList *L,int i,ElemType e);
//删除ListDelete(*L, i,*e); //删除位置i的元素,用e返回其值
Status ListDelete(SqList *L,int i,ElemType *e);
//遍历(输出)ListTraverse(L); //遍历访问整个表L
Status ListTraverse(SqList L);

 顺序表基本操作的实现

 顺序表的初始化

//初始化InitList(*L); //构造空线性表L
Status InsitList(SqList *L){
    L->elem = (ElemType*)malloc(INSTLISTSIZE*sizeof(ElemType));
    if (!L->elem) {
        printf("内存分配失败\n");
        return ERROR;
    }
    L->length = 0;
    L->listsize = INSTLISTSIZE;
    return OK;
}

顺序表的销毁

//销毁DestoryList(*L); //销毁线性表L
Status DestoryList(SqList *L){
    if (L->elem) {
        free(L->elem);
    }
    if (L->elem == NULL) {
        printf("销毁成功\n");
    }
    return OK;
}

 顺序表的清空

//清空ClearList(*L); //清空线性表L
Status ClearList(SqList *L){
    L->length = 0;
    printf("清空成功\n");
    return OK;
}

顺序表的判空

//判表空ListEmpty(L); //判断线性表是否为空
Status ListEmpty(SqList L){
    if (L.length != 0) {
        printf("顺序表不为空\n");
        return ERROR;
    }
    printf("顺序表为空\n");
    return OK;
}

顺序表的求表长

//求表长Length(L); //求线性表元素个数
Status LengthList(SqList L){
    printf("顺序表长度为%d\n",L.length);
    return OK;
}

 顺序表的按下标查找

//按位查找GetElem(L,i,*e); //查找位序为i的元素,用e返回
Status GetElem(SqList L,int i,ElemType *e){
    //判断i是否合法
    if (i < 1 || i > L.length) {
        printf("i值不合法\n");
        return ERROR;
    }
    //判空
    if (L.length == 0) {
        printf("顺序表为空\n");
        return ERROR;
    }
    //查找
    *e = L.elem[i - 1];
    return OK;
}

顺序表的按值查找

//按值查找LocateElem(L,e); //查找元素e,返回第一次出现的位序
Status LocateElem(SqList L,ElemType e){
    for (int i = 0; i < L.length; i++) {
        if (L.elem[i] == e) {
            printf("该元素的下标为%d\n",i);
            return OK;
        }
    }
    printf("查询无果\n");
    return ERROR;
}

顺序表的当前节点的前驱节点

//求前驱PriorElem(L, cur_e,*pre_e); //用pre_e返回cur_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) {
            *pre_e = L.elem[i - 1];
            return OK;
        }
    }
    printf("查询无果\n");
    return ERROR;
}

顺序表的当前节点的后继节点

//求后继NextElem(L,cur_e,*next_e);//用next_e返回cur_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) {
            *next_e = L.elem[i + 1];
            return OK;
        }
    }
    printf("查询无果\n");
    return ERROR;
}

顺序表的插入(重点掌握)

//插入ListInsert( *L, i, e); //将元素e插入的位置i;
Status ListInsert(SqList *L,int i,ElemType e){
    ElemType *p, *q;                                               //i的合法值为1<=i<=ListLength_Sq(L)+1
        if (i<1 || i>L->length + 1) return ERROR;       //i值不合法
        if (L->length >= L->listsize) {                         //当前储存空间已满,增加分配
            ElemType *newbase = (ElemType *)realloc(L->elem,
                (L->listsize + INCRESIZE) * sizeof(ElemType));
            if (!newbase)
                return  ERROR;                   //储存分配失败
            L->elem = newbase;                                         //新基址
            L->listsize += INCRESIZE;                      //增加存储容量
        }
        q = &(L->elem[i - 1]);                                           //q为插入位置
        for (p = &(L->elem[L->length - 1]);
             p >= q; --p) *(p + 1) = *p;  //插入位置及之后的元素右移
        *q = e;                                                                      //插入e
        ++L->length;                                                          //表长增1
        return OK;

}

顺序表节点的删除

//删除ListDelete(*L, i,*e); //删除位置i的元素,用e返回其值
Status ListDelete(SqList *L,int i,ElemType *e){
    //判断i值是否合法
    if (i < 1 || i > L->length) {
        printf("i值不合法\n");
        return ERROR;
    }
    *e = L->elem[i - 1];
    for(int j=i-1;j<L->length;j++){
        L->elem[j]=L->elem[j+1];
    }
            L->length--;
    return OK;
}

顺序表的遍历

//遍历(输出)ListTraverse(L); //遍历访问整个表L
Status ListTraverse(SqList L){
    //判空
    if (L.length == 0) {
        printf("顺序表为空\n");
        return ERROR;
    }
    printf("顺序表:");
    for (int i = 0; i < L.length; i++) {
        printf("\t%d",L.elem[i]);
    }
    printf("\n");
    return OK;
}

测试顺序表

int main(void){
    SqList L;//顺序表
    ElemType e,pre_e,next_e;//元素e,前驱pre_e,后驱next_e
    InsitList(&L);//初始化链表
    //插入元素
    for (int i = 1; i <= 8; i++) {
        ListInsert(&L, i, i);
    }
    //判空
    ListEmpty(L);
    //求表长
    LengthList(L);
    //遍历
    ListTraverse(L);
    //删除
    ListDelete(&L, 3, &e);
    printf("删除的元素为%d\n",e);
    //求表长
    LengthList(L);
    //遍历
    ListTraverse(L);
    //求前驱元素
    PriorElem(L, 5, &pre_e);
    printf("元素5的前驱%d\n",pre_e);
    //求后驱元素
    NextElem(L, 5, &next_e);
    printf("元素5的后驱%d\n",next_e);
    //按下标查找
    GetElem(L, 6, &e);
    printf("第6个元素%d\n",e);
    //按值查找,返回下标
    LocationElem(L, 4);
    //清空
    ClearList(&L);
    //求表长
    LengthList(L);
    //销毁
    DestoryList(&L);
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

所以我需要学这个吗?

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值