顺序表实现增,删,查与合并操作

Posted yanghuabin

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了顺序表实现增,删,查与合并操作相关的知识,希望对你有一定的参考价值。

C语言实现顺序表的的基本操作

1.顺序表实现按照位置查找

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

#define MAX_SIZE 20

// 需求:
// 线性表查找之:按序号查找。
// 表中的元素是顺序存放的,故核心语句应该是l.elem[i-1]


// 定义一个顺序表
// 应该定义在外面,否则函数头声明访问不到
typedef struct{
    int elem[MAX_SIZE];
    int last;
} SeqList;


// 函数头声明
int getData(SeqList sl,int i);

void main(){

    int i;
    printf("请输入要查询元素的下标:");
    scanf("%d",&i);

    // 初始化并赋值
    SeqList sl = {{1,2,3,4,5},4};

    // 按照序号查找数组中的元素
    int a = getData(sl,i);
    printf("第%d个元素是:%d
",i,a);
}

// 按照序号进行查找:getData(l,i),查找线性表中的第i个元素.
int getData(SeqList sl,int i){
    // 应该对数组是否越剧进行判断
    if(i<=0 || i>sl.last){
        printf("顺序表越界!
");
        exit(0);
    }

    return sl.elem[i-1];
}

2.顺序表实现按照元素查找

#include <stdio.h>

// 需求:
// 按照内容查找,要求查找顺序表L中给定的值e相等的元素

# define MAX_SIZE 10

// 定义一个顺序表
typedef struct{
    int elem[MAX_SIZE];
    int last;
} SeqList;

// 声明函数头
int locate(SeqList sl,int e);

void main(){
    int index,e;
    printf("请输入要查找的元素:");
    scanf("%d",&e);
    // 初始化顺序表
    SeqList sl = {{9,8,7,6,5,4},5};
    index = locate(sl,e);
    printf("你查找的元素%d在第%d的位置。
",e,index);
}

// 算法思想:从第一个元素开始,一次将表中的元素与e相比较,若相等,则返回元素在表中的序号;
// 若找不到,返回-1
int locate(SeqList sl,int e){
    int i=0;
    // 逐个遍历数组,如果没有到末尾或者没有找到,就一直遍历
    while( i<=sl.last && sl.elem[i]!=e ){
        i++;
    }
    // 没有到末尾,且找到元素,就返回所在的位置
    if( i<sl.last && sl.elem[i]==e ){
        return i+1;
    }
    // 没有找到就返回-1
    return -1;
}

3.顺序表实现删除元素

#include <stdio.h>

// 删除元素
// 这里给出的是根据元素进行删除
// 算法思想:判断当前是否是要删除的元,是就将下一个覆盖当前的,不是就当前的覆盖当前的


#define MAX_SIZE 20
#define OK 1
#define ERR 0

typedef struct {
    int elem[MAX_SIZE];
    int last;
} SeqList;

// 函数头
int deleteList(SeqList *sl, int e);

void foreach(SeqList sl);

int deleteList2(SeqList *sl, int e);

void main() {
    SeqList sl = {{2, 3, 4, 5, 6}, 5};
    // deleteList(&sl, 3);
    deleteList2(&sl, 3);
    foreach(sl);
}

// 这个是错误的,因为只能删除一次
// 算法思路:遍历数组,找到要删除的地方,然后删除之。删除后将数组后面的数据往前移动一个单位
int deleteList(SeqList *sl, int e) {
    for (int i = 0; i < sl->last; i++) {

        if (e == sl->elem[i]) {
            for (i; i < sl->last - 1; i++) {
                sl->elem[i] = sl->elem[i + 1];
            }
            sl->last = sl->last - 1;
            return OK;
        }
    }
    printf("元素%d不存在!", e);
    return ERR;
}

// 正确的删除思路,可以一次删除多个
// 不管有多少个都会被干掉
// 循环遍历数组,如果当前位置不是要删除的元素,就自己覆盖自己
// 如果是要删除的元素,就用下一个元素,覆盖当前元素
int deleteList2(SeqList *sl, int e) {
    int j = 0;
    int oldLast = sl->last;

    for (int i = 0; i < oldLast; i++) {
        // 只要不相等就覆盖当前的
        if (sl->elem[i] != e) {
            sl->elem[j] = sl->elem[i];
            j++;
        } else {
            sl->last--;    // 实现表尾指针的更新
        }

    }
}

// 遍历输出顺序表中的内容
void foreach(SeqList sl) {
    printf("所有的数据是:{");

    for (int i = 0; i < sl.last; i++) {
        if (i == (sl.last - 1)) {
            printf("%d}
", sl.elem[i]);
        }
        printf("%d,", sl.elem[i]);
    }
}

4.顺序表实现添加元素

#include <stdio.h>

// 插入操作
// 是顺序表的节点的物理位置必须和逻辑位置保持一致
// 在插入的过程中,要将插入后的所有数据集体向后移动一位,以保持整体完整性
// 要注意:这里应该传入数组指针,而不是数组,因为C中的数组是值传递,不像java中是会直接修改值
// 算法的复杂度是:O((n-1)/2)

#define MAX_SIZE 20
#define OK 1
#define ERR 0

// 定义结构体
typedef struct{
    int elem[MAX_SIZE];
    int last;
} SeqList;

// 函数头
int insertList(SeqList sl,int e,int index);
void foreach(SeqList sl);
int insertList2(SeqList *sl,int e,int index);

void main(){
    // 初始化结构体
    SeqList sl = {{2,4,6,8,10},5};
    //int res = insertList(sl,3,2);
    int res = insertList2(&sl,3,2);
    printf("插入数据的返回值是:%d
",res);
    foreach(sl);
}

// 这个是错误的,好像sl变成了引用传递。
int insertList(SeqList sl,int e,int index){
    // 数组越界
    if( index>=sl.last || index<0 ){
        printf("插入数据的位置不合法
");
        return ERR;
    }
    if(sl.last>=MAX_SIZE-1){
        printf("数组的空间不够
");
        return ERR;
    }

    int i = sl.last;
    while( i > (index-1) ){
        sl.elem[i] = sl.elem[i-1];
        i--;
    }

    if(i==(index-1)){
        sl.elem[i]=e;
        sl.last=sl.last+1;
        return OK;
    }

    return ERR;
}

// 遍历输出顺序表中的内容
void foreach(SeqList sl){
    printf("所有的数据是:{");

    for(int i=0;i<sl.last;i++){
        if(i==(sl.last-1)){
            printf("%d}
",sl.elem[i]);
        }
        printf("%d,",sl.elem[i]);
    }
}

// 算法思想:
// 从数组最后开始遍历,将数据逐个往后移动,移动到给定的位置后,添加元素,并更新指针
int insertList2(SeqList *sl,int e,int index){
    // 数组越界
    if( index>=sl->last || index<0 ){
        printf("插入数据的位置不合法
");
        return ERR;
    }
    if(sl->last>=MAX_SIZE-1){
        printf("数组的空间不够
");
        return ERR;
    }
    // 从最后开始遍历数组,如果没有到给定的位置,就逐个的往后移动
    int i = sl->last;
    while( i > (index-1) ){
        sl->elem[i] = sl->elem[i-1];
        i--;
    }
    // 如果到了指定的位置,就添加,并且更新last指针的值
    if(i==(index-1)){
        sl->elem[i]=e;
        sl->last=sl->last+1;
        return OK;
    }

    return ERR;
}

5.顺序表实现合并操作

#include <stdio.h>

#define ElemType int
#define MAX_SIZE 20
#define OK 1
#define ERR 0

// 定义结构体
typedef struct {
    ElemType elem[MAX_SIZE];
    int last;
} SeqList;

// 函数头
void foreach(SeqList sl);
int mergeList(SeqList *l1, SeqList *l2, SeqList *l3);


void main() {
    SeqList l1 = {{1, 3, 4, 5}, 4};
    SeqList l2 = {{2, 6, 8, 10, 11}, 5};
    SeqList l3;

    mergeList(&l1, &l2, &l3);
    foreach(l3);


}

// 合并顺序表
// 比较逐个遍历a,b表,当前位置谁小就把谁写入c表中。大的放到下一轮比较中
// 最后逐个将还有数据的表写入到c表中
int mergeList(SeqList *l1, SeqList *l2, SeqList *l3) {
    int i, j, k;
    i = 0;
    j = 0;
    k = 0;

    while (i < l1->last && j < l2->last) {
        if (l1->elem[i] <= l2->elem[j]) {
            l3->elem[k] = l1->elem[i];
            j--;
        } else {
            l3->elem[k] = l2->elem[j];
            i--;
        }
        i++;
        j++;
        k++;
    }

    while (i < l1->last) {
        l3->elem[k] = l1->elem[i];
        i++;
        k++;
    }

    while (j < l1->last) {
        l3->elem[k] = l2->elem[j];
        j++;
        k++;
    }

    l3->last = l2->last + l1->last - 1;

}


// 遍历输出顺序表中的内容
void foreach(SeqList sl) {
    printf("所有的数据是:{");

    for (int i = 0; i < sl.last; i++) {
        if (i == (sl.last - 1)) {
            printf("%d}
", sl.elem[i]);
        }
        printf("%d,", sl.elem[i]);
    }
}

 

以上是关于顺序表实现增,删,查与合并操作的主要内容,如果未能解决你的问题,请参考以下文章

python 列表的增删改查与嵌套

顺序表详解及其c语言代码实现

02线性表之顺序表

触发器实现源表操作(增,删,改)自动补录操作日志

sql语句增删改查与子查询

(java实现)顺序表-ArrayList