数据结构学习之顺序表(各种操作合集)

顺序表(各种操作合集)

顺序表的两种创建方式:

方式1:根据函数的返回值创建

  • 通过返回值返回所申请的内存空间的首地址
  • 示例代码:
list_t *create_seq_list_1(){

    list_t *p = (list_t *)malloc(sizeof(list_t));
    if(NULL == p){

        printf("内存分配失败\n");

        exit(-1);

    }

    memset(p,0,sizeof(list_t));
    return p;

}
  • 注意事项:
  • 1.分配完内存地址空间后,一定要检查内存分配是否成功
  • 2.若内存分配失败,需要使用shell命令exit(-1)退出

方式2:根据地址传参创建

  • 使用地址传参创建顺序表;
  • 示例代码:
int create_seq_list_2(list_t **p){

    if(NULL == p){

        printf("入参为NULL\n");

        return -1;

    }

    *p = (list_t *)malloc(sizeof(list_t));

    if(NULL == *p){

        printf("内存分配失败\n");

        return -1;

    }

    memset(*p,0,sizeof(list_t));

    return 0;
    
}
  • 注意事项:
  • 1.所传入的形参必须是二级指针变量,因为二级指针用来存储一级指针变量的地址,即所申请的顺序表内存空间的地址
  • 2.形参传入到创建顺序表的功能函数后,一定要做入参合理性检查
  • 3.同方式1一样,分配完内存地址空间后,一定要检查内存分配是否成功

顺序表的两种插入方式:

方式1:尾插法

  • 在顺序表末端插入数据元素,代码如下:
  • 示例代码:
int insert_seq_list_1(list_t *seq_list,int data){

    if(NULL == seq_list){

        printf("入参为NULL\n");

        return -1;

    }

    if(N == seq_list->count){

        printf("顺序表已满,插入失败\n");

        return -1;

    }

    seq_list->a[seq_list->count].num = data;
    seq_list->count++;

    return 0;

}
  • 注意事项:
  • 1.形参传入到具有插入数据元素功能的函数后,需要做入参合理性检查
  • 2.还需要判断此时顺序表所存储的数据元素是否已满
  • 3.本示例代码中的count是计数的变量每次插入一个数据元素后,需要加1,此处易忽略

方式2:任意位置插入新数据

  • 在顺序表的任意位置插入数据元素,代码如下:
  • 示例代码:
int insert_seq_list_2(list_t *seq_list,int pos, int data){


    if(NULL == seq_list){

        printf("入参为NULL\n");

        return -1;

    }
    if(N == seq_list->count){

        printf("顺序表已满,插入失败\n");

        return -1;

    }
    if( pos < 0 || pos > seq_list->count){

        printf("插入位置不合理,插入失败\n");

        return -1;

    }

    int i = 0;
    i = seq_list->count-1;

    while(i >= pos){

        seq_list->a[i+1] = seq_list->a[i];

        i--;

    }

    seq_list->a[pos].num = data;
    seq_list->count++;

    return 0;
}
  • 注意事项:
  • 1.同方式1:形参传入到具有插入数据元素功能的函数后,需要做入参合理性检查
  • 2.也同方式1:还需要判断此时顺序表所存储的数据元素是否已满
  • 3.判断所要插入数据元素的位置在顺序表中是否合理
  • 4.可以采用while循环或者for循环的方式找到所要插入数据元素的位置后,此位置的数据元素以及此位置之后的所有数据元素,依次向后挪动一个位置,目的是腾出所指定的待插入位置
  • 5.将所要插入的数据元素的值赋值给该位置的值,也就是覆盖,记得count加1

顺序表的两种删除方式:

方式1:尾删法

  • 在顺序表的末端删除所存储的数据元素,代码如下:
  • 示例代码:
int delete_seq_list_1(list_t *seq_list){

    if(NULL == seq_list){

        printf("入参为NULL\n");

        return -1;

    }
    if(0 == seq_list->count){

        printf("顺序表为空,删除失败\n");

        return -1;
    }
    seq_list->count--;

    return 0;
}
  • 注意事项:
  • 1.形参传入到具有删除数据元素功能的函数后,需要做入参合理性检查
  • 2.还需要判断此时顺序表所存储的数据元素是否为空
  • 3.count是计数的变量每次删除一个数据元素后,需要减1,此处易忽略

方式2:任意位置删除旧数据

  • 在顺序表的任意位置删除数据元素,代码如下:
  • 示例代码:
int delete_seq_list_2(list_t *seq_list,int pos){

    if(NULL == seq_list){

        printf("入参为NULL\n");

        return -1;

    }
    if(0 == seq_list->count){

        printf("顺序表为空,删除失败\n");

        return -1;
    }

     if( pos < 0 || pos >= seq_list->count){

        printf("删除位置不合理,删除失败\n");

        return -1;

    }

    int i = pos;

    while(i < seq_list->count-1){

        seq_list->a[i] = seq_list->a[i+1];

        i++;

    }

    seq_list->count--;

    return 0;

}
  • 注意事项:
  • 1.同方式1:形参传入到具有删除数据元素功能的函数后,需要做入参合理性检查
  • 2.也同方式1:还需要判断此时顺序表所存储的数据元素是否为空
  • 3.判断所要删除数据元素的位置在顺序表中是否合理,一定要区别在任意位置插入数据元素的位置合理性检查,两者略有不同,防止越界操作,所导致运行结果出错
  • 4.可以采用while循环或者for循环的方式找到所要删除数据元素的位置后,此位置之后的所有数据元素,依次向前挪动一个位置,目的是删除所指定的待删除位置
  • 5.删除所指定位置的数据元素后,记得count减1

顺序表的两种修改方式:

方式1:根据位置修改

  • 根据顺序表中数据元素的位置进行修改,代码如下:
  • 示例代码:
int modify_seq_list_1(list_t *seq_list,int pos, int data){


    if(NULL == seq_list){

        printf("入参为NULL\n");

        return -1;

    }

    if( pos < 0 || pos >= seq_list->count){

        printf("修改位置不合理,修改失败\n");

        return -1;

    }

    seq_list->a[pos].num = data;


    return 0;
}
  • 注意事项:
  • 1.形参传入到具有修改数据元素功能的函数后,需要做入参合理性检查
  • 2.判断所要修改数据元素的位置在顺序表中是否合理,if条件语句内容和任意位置删除功能函数一致;

方式2:根据数值修改

  • 根据顺序表中数据元素的值进行修改,代码如下:
  • 示例代码:
int modify_seq_list_2(list_t *seq_list,int data1, int data2){

    if(NULL == seq_list){

        printf("入参为NULL\n");

        return -1;

    }

    int i = 0;
    int count = 0;

    while(i < seq_list->count){

        if(seq_list->a[i].num == data1){

            seq_list->a[i].num = data2;

            count++;

        }

        i++;
    }

    if(0 == count){


        printf("顺序表中无所要修改的值\n");

    }

    return 0;
}
  • 注意事项:
  • 1.同方式1,形参传入到具有修改数据元素功能的函数后,需要做入参合理性检查
  • 2.可以采用while循环或者for循环的方式找到所要修改数据元素的值后,将新值赋值于旧值即可;
  • 3.该函数中定义的count变量,用来记录顺序表中有无所要修改的值

顺序表的查找:

  • 根据顺序表中数据元素的位置进行查找,代码如下:
  • 示例代码:
int search_seq_list(list_t *seq_list,int pos,int *num){

    if(NULL == seq_list || NULL == num){

        printf("内存分配失败\n");

        return -1;

    }

    if( pos < 0 || pos >= seq_list->count){

        printf("查找位置不合理,查找失败\n");

        return -1;

    }

    *num = seq_list->a[pos].num;

    return 0;
}
  • 注意事项:
  • 1.形参传入到具有查找数据元素功能的函数后,需要做入参合理性检查,比如函数中的形参seq_list和num
  • 2.判断所要查找数据元素的位置在顺序表中是否合理,if条件语句内容和任意位置删除功能函数一致;

顺序表的排序:

  • 根据顺序表中每个数据元素的大小,对数据元素做冒泡排序,代码如下:
  • 示例代码:
int sort_seq_list(list_t *seq_list){

    if(NULL == seq_list){

        printf("入参为NULL\n");

        return -1;

    }

    for(int i = 0 ; i < seq_list->count - 1; i++){

        for(int j = 0; j < seq_list->count - 1 - i; j++ ){

            if(seq_list->a[j].num > seq_list->a[j+1].num){

                data_t temp = seq_list->a[j];

                seq_list->a[j] = seq_list->a[j+1];

                seq_list->a[j+1] = temp;

            }

        }
    }

    printf("本次排序结束\n");
    return 0;
}
  • 注意事项:
  • 1.定义一个结构体变量,作为第三方变量,根据if条件语句交换两个数据元素的位置
  • 2.注意越界问题,比如第二层for循环j < seq_list->count - 1 - i;-1是为了防止越界

顺序表的去重:

  • 剔除顺序表中的重复的数据元素,例如:
11 33 55 55 66 66 66 66 
本次去重结束
11 33 55 66 
  • 示例代码:
int del_rep_seq_list(list_t *seq_list){

    if(NULL == seq_list){

        printf("入参为NULL\n");

        return -1;

    }

    for(int i = 0; i < seq_list->count; i++){

        for(int j = i + 1; j < seq_list->count;){

                if(seq_list->a[i].num == seq_list->a[j].num){

                   for(int k = j; k < seq_list->count-1; k++){

                        seq_list->a[k] = seq_list->a[k+1];

                    }

                    seq_list->count--;

                } else {

                    j++;
                }

        }


    }

    printf("本次去重结束\n");

    return 0;
}
  • 注意事项:
  • 1.第二层for循环是为了在顺序表中寻找相同的数据元素
  • 2.顺序表去重的具体操作方法和在顺序表的任意位置删除数据元素操作一致

顺序表的清空:

  • 只需要将结构体变量的成员count赋值0即可清空顺序表
  • 示例代码:
int clean_seq_list(list_t *seq_list){

    if(NULL == seq_list){

        printf("入参为NULL\n");

        return -1;

    }

    seq_list->count = 0;

    printf("清空顺序表完成\n");

    return 0;
}

  • 注意事项:
  • 形参传入到具有清空数据元素功能的函数后,需要做入参合理性检查;

顺序表的销毁:

  • 示例代码:
int destroy_seq_list(list_t **seq_list){

    if(NULL == seq_list || NULL == *seq_list){

        printf("入参为NULL\n");

        return -1;

    }

    free(*seq_list);
    *seq_list = NULL;

    printf("销毁顺序表完成\n");


    return 0;

}
  • 注意事项:
  • 1.形参传入到具有销毁数据元素功能的函数后,需要做入参合理性检查;
  • 2.使用free函数释放顺序表的内存空间后,要记得做*seq_list = NULL;操作,这样是为了防止内存空间出现野指针

你可能感兴趣的:(数据结构学习系列,编程基础,面试题,数据结构,学习,顺序表)