c语言顺序表实现

顺序表作为数据结构的入门,是需要我们掌握的,下面我们就来实现一下静态顺序表。为了方便,这里使用到了c++的引用。

1.首先是这个结构体

typedef struct {
    ElemType data[MaxSize];//静态顺序表
    int length;
}SqList; 

结构体里面有两个元素,一个是数据的静态数组,maxsize和elementtype都是宏定义。已经在代码开始之前声明好了。

注意,这里我们用typedef将其重命名为了Sqlist,方便后续使用。

2.接下来就是插入操作。

//插入操作
bool ListInsert(SqList& L, int i, ElemType e) {
    if (i<1 || i>L.length + 1) {//判断插入位置是否合法
        return false;
    }
    if (L.length > MaxSize) {//数组满了!
        return false;
    }
    for (int j = L.length; j >= i; j--) {//反循环实现指定数组元素向后移动。就是前面的赋值给后面的,所以是j-1.
        L.data[j] = L.data[j - 1];
    }
    L.data[i - 1] = e;//指定位置插入。 
    L.length++;//插入后长度+1.
    return true;
}

这里函数的参数列表里用到了c++的&,即对主函数里的L取别名,在函数里面的修改会直接带回到主函数里面去。当然也可以用指针实现,后续会进行更新。

这个插入是在第 i 位插入 e 这个元素,作用于L顺序表。首先判断插入位置合法性以及判断数组是否已满,这里满了是没办法的,因为是静态数组,想要解决需要通过malloc函数实现动态数组开辟,这个后面会更新,这里先讨论静态顺序表,理解他的思想。

最关键的就是这个循环,他会将指定位置后面的元素全部往后挪一位,我们看一看就是把第i位赋值给i+1位,但是这样是不是有可能丢掉一位?那么就将j-1赋值给第j位。

之后就是常规操作,把目标元素e赋值给L。

最后长度+1.

 

3.接下来是删除操作。

//按位删除
bool ListDelete(SqList& L,int i,ElemType &e) {
    if (i<1 || i>L.length + 1) {//判断删除位置是否合法
        return false;
    }
    if (L.length == 0) {
        return false;
    }
    e = L.data[i - 1];//取得被删除的元素e。
    for (int j = i; j < L.length; j++) {
        L.data[j - 1] = L.data[j];//从i的位置开始,所有元素从后往前移,所以是j赋给j-1.
    }
    L.length--;//删除元素顺序表长度减一。
    return true;
}

 

4.这里是按位删除,传入的参数是顺序表L,位置i,删除的值e。

仍然是常规操作判断删除的位置是否合法,这个不要忘了。

这里将e带回是为了main函数里的操作。之后就是这一位被删除。实际上并不是把他给删了,是把他之后的所有元素全部往后挪一位,然后他后面的就把它给覆盖了,最后长度减一。这个挺有意思。

然后就是查找操作。

/按值查找
int LocateElem(SqList& L, int e) {
    int i;
    for (i = 0; i < L.length; i++) {//遍历顺序表
        if (L.data[i] == e) {
            return i + 1;//加一是为了输出位序。
        }
        else {
            return 0;
        }
    }
}

这里的查找只用了两个参数,顺序表L和e元素。

查找的原理就是遍历,从头到尾遍历一遍,只要找到了就返回这是哪一位。这里加一是返回的位序,返回下标的话就无须加一。

找到就返回这个位序,找不到就返回0.最后进入主函数处理。

 

5.接下来就是主函数。

//主函数
int main() {
    SqList L;
    bool ret;//查看返回值
    ElemType del;//要删除的值
    int element_get = 0;//查找返回的元素位置
    L.data[0] = 0;//初始化
    L.data[1] = 1;
    L.data[2] = 2;
    L.length = 3;//顺序表的长度初始化,理解为组合操作吧。
    
    ret = ListInsert(L,2,60);//往第二个位置插入 60 这个元素。
     if (ret) {
        printf("插入成功,当前顺序表为:\n");
        PrintList(L); 
    }
    else {
        printf("插入失败,当前顺序表为:\n");
    }
    ret = ListDelete(L, 1, del);//删除第一个位置元素,并把元素值输出。
    if (ret) {
        printf("删除成功,当前顺序表为:\n");
        PrintList(L);
    }
    else {
        printf("删除失败,当前顺序表为:\n");
        PrintList(L);
    }
    element_get = LocateElem(L, 1);//获取查找函数的返回值。
    if (element_get == 0) {
        printf("未找到,当前线性表元素为:");
        PrintList(L);
    }
    else{
        printf("已找到,位序为:%d",element_get);
    }
    return 0;
}   

线性表的初始化这里是手动进行的,直接用成员运算符赋值即可。这里的失败和成功都是通过返回值来进行判断的,还请仔细阅读。

其实这里操作的都是我们最开始初始化的这个L,这就是引用&存在的理由,有了它就没有指针那么麻烦的去保证每个函数的修改会落实到主函数这里。

 

posted @ 2022-04-12 20:52  skywxp  阅读(194)  评论(0)    收藏  举报