顺序表的基本操作集(C语言版)

/*
    顺序的操作集中一些常用的操作
    说明:顺序表的操作可以根据需要灵活的编写,操作接口比较多,这里只写了一些常用的基本接口 

    1、始化顺序表
        Status InitList_Sq(SqList &L, int size, int increment);    
    2、销毁顺序表
        Status DestroyList_Sq(SqList &L);
    3、判断顺序表是否为空
        Status ListEmpty_Sq(SqList L);     
    4、清空顺序表
        Status ClearList_Sq(SqList &L); 
    5、求顺序表的长度
        int ListLength_Sq(SqList L);     
    6、读取顺序表中指定的第 i 个元素
        Status GetElem_Sq(SqList L, int i, ElemType &e);         
    7、顺序表中查找指定元素 e,说明:成功时返回该元素在表中第一次出现的位置,否则返回 -1
        int Search_Sq(SqList L, ElemType e); 
    8、顺序表的第 i 个元素赋值为 e
        PutElem_Sq(SqList &L, int i, ElemType e);    
    9、在表尾添加一个元素
        Status Append_Sq(SqList &L, ElemType e);        
    10、在指定第 i 个元素之前插入元素
        Status ListInsert_Sq(SqList &L, int i, ElemType e);         
    11、删除表尾元素
        Status DeleteLast_Sq(SqList &L,int i, ElemType &e); 
    12、删除指定的第 i 个元素
        Status ListDelete_Sq(SqList &L,int i, ElemType &e); 
    13、遍历顺序表 L,说明:依次对每个元素调用函数 visit()
        Status ListTraverse_Sq(SqList L, Status(*visit)(ElemType e)); 

*/

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

#define TRUE 1
#define FALSE 0
#define OK 1
#define ERROR 0
#define OVERFLOW -1
#define PERROR -2
typedef int Status;

// 数据元素的类型,使用时需根据问题的需求定义。
typedef int ElemType;

//顺序表结构类型定义 
typedef struct {
    ElemType    *elem;    // 存储空间的基址
    int length;         // 表长 
    int size;            // 存储容量 
    int increment;        // 扩容增量
} SqList;

// 1、初始化顺序表 L 
Status InitList_Sq(SqList &L, int size, int inc){
    L.elem = (ElemType *)malloc(size * sizeof(ElemType));
    if (L.elem == NULL) return OVERFLOW;
    L.length = 0;
    L.size = size;
    L.increment = inc;
    return OK;
}

// 2、销毁顺序表 L
Status DestroyList_Sq(SqList &L) {        
    if((L.elem != NULL)&&(L.size == 0))return PERROR;    // 参数合法性检验,防止实参未初始化时就使用的野指针
    if(L.elem == NULL)return PERROR;    // 参数合法性检查,顺序表已销毁则返回,不再执行销毁操作 
    free(L.elem);    // 释放顺序表所占空间 
    L.elem = NULL;    // 避免指针悬挂 
    L.length = 0;
    L.size = 0;
    L.increment = 0;
    return OK;
}

// 3、判断顺序表 L 是否为空表
Status ListEmpty_Sq(SqList L) {
    if((L.elem != NULL)&&(L.size == 0))return PERROR;    // 参数合法性检验,防止实参未初始化时就使用的野指针
    if(L.elem == NULL)return PERROR;    // 参数合法性检查,顺序表已销毁则返回 
    if(L.length == 0) {
        return TRUE;
    }else{
        return FALSE;
    } 
}

// 4、清空顺序表 L
Status ClearList_Sq(SqList &L) {
    if((L.elem != NULL)&&(L.size == 0))return PERROR;    // 参数合法性检验,防止实参未初始化时就使用的野指针
    if(L.elem == NULL)return PERROR;    // 参数合法性检查,顺序表已销毁则返回 
    L.length = 0;
    return OK;
}

// 5、求顺序表的长度
int ListLength_Sq(SqList L) {
    if((L.elem != NULL)&&(L.size == 0))return PERROR;    // 参数合法性检验,防止实参未初始化时就使用的野指针
    if(L.elem == NULL)return PERROR;    // 参数合法性检查,顺序表已销毁则返回 
    return L.length;
}
 
// 6、读取顺序表中指定的第 i 个元素
Status GetElem_Sq(SqList L, int i, ElemType &e) {
    if((L.elem != NULL)&&(L.size == 0))return PERROR;    // 参数合法性检验,防止实参未初始化时就使用的野指针
    if(L.elem == NULL)return PERROR;    // 参数合法性检查,顺序表已销毁则返回 
    if(i<1 || i>L.length) return PERROR;    // 参数合法性检查,非法则返回
    e = L.elem[i-1];
    return OK;
}


// 7、在顺序表 L 顺序查找元素e
// 成功时返回该元素在表中第一次出现的位置,否则返回 -1
int Search_Sq(SqList L, ElemType e) {
    if((L.elem != NULL)&&(L.size == 0))return PERROR;    // 参数合法性检验,防止实参未初始化时就使用的野指针
    if(L.elem == NULL)return PERROR;    // 参数合法性检查,顺序表已销毁则返回 
    int i = 0;
    while (i < L.length && L.elem[i] != e){
        i++;
    }
    if (i < L.length){
        return i;
    }else{
        return -1;
    }
}

// 8、把顺序表的第 i 个元素赋值为 e
Status PutElem_Sq(SqList &L, int i, ElemType e) {
    if((L.elem != NULL)&&(L.size == 0))return PERROR;    // 参数合法性检验,防止实参未初始化时就使用的野指针
    if(L.elem == NULL)return PERROR;    // 参数合法性检查,顺序表已销毁则返回 
    if(i<1 || i>L.length) return PERROR;    // 参数合法性检查,非法则返回
    L.elem[i-1] = e; 
    return OK;
}

// 9、在顺序表 L 的表尾添加元素 e
Status Append_Sq(SqList &L, ElemType e) {
    ElemType *newbase;
    if((L.elem != NULL)&&(L.size == 0))return PERROR;    // 参数合法性检验,防止实参未初始化时就使用的野指针
    if(L.elem == NULL)return PERROR;    // 参数合法性检查,顺序表已销毁则返回 
    if (L.length >= L.size){                // 满了需要扩容 
        newbase =  (ElemType*)realloc(L.elem, (L.size + L.increment)*sizeof(ElemType));
        if(newbase==NULL) return OVERFLOW;
        L.elem = newbase; 
        L.size += L.increment;
    }
    L.elem[L.length] = e;
    L.length++;
    return OK;
}

// 10、在顺序表 L 的指定第 i 个元素之前插入元素
Status ListInsert_Sq(SqList &L, int i, ElemType e){
    ElemType *newbase;
    int l,r;
    if((L.elem != NULL)&&(L.size == 0))return PERROR;    // 参数合法性检验,防止实参未初始化时就使用的野指针
    if(L.elem == NULL)return PERROR;    // 参数合法性检查,顺序表已销毁则返回 
    if(i < 1 || i > L.length) return PERROR;    // 数合法性检查,非法则返回
    if (L.length >= L.size){                    // 满了需要扩容 
        newbase =  (ElemType*)realloc(L.elem, (L.size + L.increment)*sizeof(ElemType));
        if(newbase==NULL) return OVERFLOW;
        L.elem = newbase; 
        L.size += L.increment;
    }
    l = i-1;                                     // l为插入位置
    for(r = L.length-1; r >= l; r--){
        L.elem[r+1] = L.elem[r];                 //插入位置及之后的元素后移
    }
    L.elem[l] = e;                                 //插入e
    L.length++;                                    //表长加 1
    return OK;
}
// 11、删除表尾元素
Status DeleteLast_Sq(SqList &L, ElemType &e) {
    if((L.elem != NULL)&&(L.size == 0))return PERROR;    // 参数合法性检验,防止实参未初始化时就使用的野指针
    if(L.elem == NULL)return PERROR;    // 参数合法性检查,顺序表已销毁则返回 
    if(L.length == 0) return ERROR;            // 空表,无法删除 
    e = L.elem[L.length - 1];
    L.length--;
    return OK;
}

// 12、在顺序表 L 中删除指定的第 i 个元素,并用 e 将其返回
Status ListDelete_Sq(SqList &L, int i, ElemType &e)
{
    int r;        // 后面的元素移位迭代用变量 
    if((L.elem != NULL)&&(L.size == 0))return PERROR;    // 参数合法性检验,防止实参未初始化时就使用的野指针
    if(L.elem == NULL)return PERROR;    // 参数合法性检查,顺序表已销毁则返回 
    if(i < 1 || i > L.length) return ERROR;        // 参数合法性检查,非法则返回
    e = L.elem[i-1];                            // 将第 i 个元素交给 e 
    for(r = i;r < L.length;r--){
        L.elem[r-1] = L.elem[r];                // 将删除位置之后的元素依次前移
    } 
    L.length--;                    //表长减一
    return OK;
}

// 13、遍历顺序表 L ,依次对每个元素调用函数 visit()
Status ListTraverse_Sq(SqList L, Status(*visit)(ElemType e)) {
    if((L.elem != NULL)&&(L.size == 0))return PERROR;    // 参数合法性检验,防止实参未初始化时就使用的野指针
    if(L.elem == NULL)return PERROR;    // 参数合法性检查,顺序表已销毁则返回 
    if (L.length == 0) return ERROR;    // 空表不再遍历访问 
    for (int i = 0; i < L.length; i++) {
        visit(L.elem[i]);
    }
    return OK;
}

// 测试用函数:打印顺序表的全部元素 
Status PrintList(ElemType e) {
    printf("%d\t",e);
    return OK;
}

int main(){
    int i, e, state;
    SqList L;
    printf("1.初始化顺序表\n");
    printf("2.销毁顺序表\n");
    printf("3.判断顺序表是否为空\n");
    printf("4.清空顺序表\n");
    printf("5.求顺序表的长度\n");
    printf("6.读取顺序表中指定的第 i 个元素\n");
    printf("7.在顺序表中查找指定元素\n");
    printf("8.将顺序表的第 i 个元素赋值为 e\n");
    printf("9.在顺序表中的表尾添加一个元素\n");
    printf("10.在指定第 i 个元素之前插入元素\n");
    printf("11.删除表尾元素\n");
    printf("12.删除指定的第 i 个元素\n");
    printf("13.打印顺序表中的全部元素\n");
    do{
        printf("请输入你要进行的操作:\n");
        scanf("%d",&i);
        switch(i){
            case 1 :
                    state = InitList_Sq(L, 10, 5); 
                    if(state == OK){
                        printf("顺序表初始化成功。\n");
                    }else{
                        printf("顺序表初始化失败!\n"); 
                    }
                    break;
            case 2 :
                    state = DestroyList_Sq(L);
                    if(state == PERROR){
                        printf("请确认参数合法化或者先执行顺序表的初始化操作!\n"); 
                    }else{
                        printf("顺序表销毁成功。\n"); 
                    }
                    break;
            case 3 :
                    state = ListEmpty_Sq(L);
                    if(state == PERROR){
                        printf("请确认参数合法化或者先执行顺序表的初始化操作!\n"); 
                    }else if(state == TRUE){
                        printf("队列为空!\n"); 
                    }else if(state == FALSE){
                        printf("队列不为空!\n"); 
                    }
                    break;
            case 4 :
                    state = ClearList_Sq(L);
                    if(state == PERROR){
                        printf("请确认参数合法化或者先执行顺序表的初始化操作!\n"); 
                    }else{
                        printf("已为您清空队列。\n");
                    }
                    break;
            case 5 :
                    state =  ListLength_Sq(L);
                    if(state == PERROR){
                        printf("请确认参数合法化或者先执行顺序表的初始化操作!\n"); 
                    }else{
                        printf("当前顺序表中共有 %d 个元素!\n",state); 
                    }
                    break; 
            case 6 :
                    printf("请输入将需要读取的是第几个元素:\n");
                    scanf("%d",&i);
                    state = GetElem_Sq(L, i, e);
                    if(state == PERROR){
                        printf("请确认参数合法化或者先执行顺序表的初始化操作!\n"); 
                    }else{
                        printf("顺序表中第 %d 个元素是: %d \n",i,e); 
                    }
                    break;
            case 7 :
                    printf("请输入将想要查找的元素:\n");
                    scanf("%d",&e);
                    state = Search_Sq(L, e);
                    if(state == PERROR){
                        printf("请确认参数合法化或者先执行顺序表的初始化操作!\n"); 
                    }else if(state == -1){
                        printf("顺序表没有这个元素!\n"); 
                    }else{
                        printf("查找成功:您要找的元素是顺序表的第 %d 个元素。\n",state); 
                    }
                    break;
            case 8 :
                    printf("请输入更换的元素的位置:\n");
                    scanf("%d",&i);
                    printf("请输入您想将元素更换为:\n");
                    scanf("%d",&e);
                    state = PutElem_Sq(L, i, e);
                    if(state == PERROR){
                        printf("请确认参数合法化或者先执行顺序表的初始化操作!\n"); 
                    }else{
                        printf("元素更换成功。\n"); 
                    }
                    break;
            case 9 :
                    printf("请输入您想在表尾追加的元素为:\n");
                    scanf("%d",&e);
                    state = Append_Sq(L, e);
                    if(state == PERROR){
                        printf("请确认参数合法化或者先执行顺序表的初始化操作!\n"); 
                    }else if(state == OK){
                        printf("元素 %d 追加成功。\n",e); 
                    }else{
                        printf("元素 %d 追加失败!\n",e); 
                    }
                    break;
            case 10 :
                    printf("请输入您想在第几个元素前插入元素:\n");
                    scanf("%d",&i);
                    printf("请输入您想插入的元素为:\n");
                    scanf("%d",&e);
                    state = ListInsert_Sq(L, i, e);
                    if(state == PERROR){
                        printf("请确认参数合法化或者先执行顺序表的初始化操作!\n"); 
                    }else if(state == OK){
                        printf("元素 %d 追加成功。\n",e); 
                    }else{
                        printf("元素 %d 追加失败!\n",e); 
                    }
                    break; 
            case 11 :
                    state = DeleteLast_Sq(L, e);
                    if(state == PERROR){
                        printf("请确认参数合法化或者先执行顺序表的初始化操作!\n"); 
                    }else if(state == OK){
                        printf("顺序表表尾元素已成功删除。\n"); 
                    }else{
                        printf("顺序表内没有元素,不能执行删除表尾元素操作!\n");
                    }
                    break;
            case 12 :
                    printf("请输入您删除的是顺序表中的第几个元素:\n");
                    scanf("%d",&i);
                    state = ListDelete_Sq(L, i, e);
                    if(state == PERROR){
                        printf("请确认参数合法化或者先执行顺序表的初始化操作!\n"); 
                    }else if(state == OK){
                        printf("指定的元素已成功删除。\n"); 
                    }else{
                        printf("顺序表内没有元素,不能执行删除表尾元素操作!\n");
                    }
                    break;
            case 13 :
                    state = ListTraverse_Sq(L, PrintList);
                    if(state == PERROR){
                        printf("请确认参数合法化或者先执行顺序表的初始化操作!\n"); 
                    }else if(state == ERROR){
                        printf("当前的顺序表为空表。\n"); 
                    }else{
                        printf("\n"); 
                    }
                    break;
        }
    }while(i>=1&&i<=13);
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

tangguofeng

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

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

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

打赏作者

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

抵扣说明:

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

余额充值