ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

数据结构一顺序表

2022-02-02 22:00:31  阅读:158  来源: 互联网

标签:顺序 return int length Vector vec ind 数据结构


数据结构 = 数据定义 + 数据操作

顺序表:一片连续存储的区域

结构定义:

size:代表当前顺序表大小

length:当前一共存储了多少个元素

data_type:存储的元素类型

结构操作:

插入:

删除:

1、数据结构的定义:

typedef struct Vector{
    int *data;
    int size,length;

}Vector;

将struct结构类型重新定义成vector数据类型

int * data:指针是地址。 数据一片连续的存储区域,

2、初始化存储n个元素的顺序表

Vector *init(int n){

    Vector *vec = (Vector *)malloc(sizeof(Vector));
    vec->data = (int*)malloc(sizeof(int)*n);
    vec->size = n;
    vec->length = 0;
    return vec;
}

数据类型Vector*,也就是前面的结构体

函数名init

参数int n

函数内定义了一个vec顺序表,并为顺序表初始化了一段内存空间

然后为顺序表中连续存储的数据data也初始化了一段空间

元素个数size初始化为n,也就是传入的参数

已有元素length初始话为0

最后返回顺序表vec

3、顺序表的销毁操作:

void clear(Vector *vec){
    if(vec == NULL)return;
    free(vec->data);
    free(vec);
    return;
}

定义了一个没有返回值的函数,传入的参数是顺序表

if顺序表为空直接返回

不为空释放数据存储空间地址

释放顺序表。

4、顺序表插入操作:

int insert(Vector *vec, int ind, int val){
    if (vec == NULL ) return 0;
    if (vec->length == vec->size) return 0;
    if (ind <0 || ind>vec->length ) return 0;

    for (int i = vec->length;i>ind;i--){
        vec->data[i] = vec->data[i-1];
    }
    vec->data[ind] = val;
    vec->length +=1;
    return 1;

}

定义一个插入函数,int类型,插入成功返回1.失败为0

传入的参数分别为vec顺序表   ind位置  和val要传入的值

有几种非法的情况

1、当表为空

2、表已经满了

3、插入的位置超过上下限

以上都是非法的不能插入,直接返回0.

插入操作,我们插入的时候需要把插入位置及后面的数据依次往后移动

移动完成后再在插入位置写入我们要插入的数据

定义了一个for循环,初始化i为顺序表的已经存储的个数,因为是从0开始的所以不需要加1

循环结束条件是循环到我们要插入的位置ind

当循环结束

再插入位置插入我们的值

长度加1

返回1插入成功

5、删除顺序表元素

int erase(Vector *vec , int ind){
    if (vec == NULL ) return 0;
    if (vec->length == 0) return 0;
    if (ind <0 || ind>vec->length ) return 0;
    for(int i = ind+1;i<vec->length;i++){
        vec->data[i-1] = vec->data[i];
    }
    vec->length -=1;
    return 1;
}

具体的和插入类似。不详细解释了

6、依次输出顺序表中元素的函数

输出格式类似于这个[1,2,2,3,6]

void output(Vector *vec){
    printf("Vector(%d) = [",vec->length);
    for (int i = 0;i<vec->length ; i++){
        printf("%d",vec->data[i]);
    }
    printf("]\n");
    return;
}

一个没有返回值的函数

传入元素是顺序表

输出vector(%d),表中有多少元素,类似vector(10),是个元素

用for循环遍历顺序表

6、主函数测试顺序表

随机位置随机插入删除值。

引入随机种子

int main()
{
    srand(time(0));
    #define MAX_OP 20
    Vector *vec = init(MAX_OP);
    int op ,ind ,val;
    for(int i=0 ;i<MAX_OP;i++){
        op = rand()%2;
        ind = rand()%(vec->length +1);
        val = rand()%100;
        switch(op){
            case 0:{
            printf("insert %d at %d to vector \n",val,ind);
            insert(vec,ind,val);

        }break;
            case 1:{
            printf("erase item at %d from vector \n",ind);
            erase(vec,ind);

        }break;

        }
        output(vec);
    }


return 0;
}

引入头文件

#include <time.h>

定义一个20常量

初始化顺序表

定义插入删除,位置,值的变量

op是0和1

0插入

1删除

定义一个for循环

循环条件0-20

%2随机出来0和1

%(vec->length+1)从已有元素的大小中随机

%100 随机到100数插入

用switch判断是插入还是删除

并输出

完整代码如下

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
typedef struct Vector{
    int *data;
    int size,length;

}Vector;

Vector *init(int n){

    Vector *vec = (Vector *)malloc(sizeof(Vector));
    vec->data = (int*)malloc(sizeof(int)*n);
    vec->size = n;
    vec->length = 0;
    return vec;
}

void clear(Vector *vec){
    if(vec == NULL)return;
    free(vec->data);
    free(vec);
    return;
}

int insert(Vector *vec, int ind, int val){
    if (vec == NULL ) return 0;
    if (vec->length == vec->size) return 0;
    if (ind <0 || ind>vec->length ) return 0;

    for (int i = vec->length;i>ind;i--){
        vec->data[i] = vec->data[i-1];
    }
    vec->data[ind] = val;
    vec->length +=1;
    return 1;

}

int erase(Vector *vec , int ind){
    if (vec == NULL ) return 0;
    if (vec->length == 0) return 0;
    if (ind <0 || ind>vec->length ) return 0;
    for(int i = ind+1;i<vec->length;i++){
        vec->data[i-1] = vec->data[i];
    }
    vec->length -=1;
    return 1;
}

void output(Vector *vec){
    printf("Vector(%d) = [",vec->length);
    for (int i = 0;i<vec->length ; i++){
        if (i!=0) printf(",");
        printf("%d",vec->data[i]);
    }
    printf("]\n");
    return;
}

int main()
{
    srand(time(0));
    #define MAX_OP 20
    Vector *vec = init(MAX_OP);
    int op ,ind ,val;
    for(int i=0 ;i<MAX_OP;i++){
        op = rand()%2;
        ind = rand()%(vec->length +1);
        val = rand()%100;
        switch(op){
            case 0:{
            printf("insert %d at %d to vector \n",val,ind);
            insert(vec,ind,val);

        }break;
            case 1:{
            printf("erase item at %d from vector \n",ind);
            erase(vec,ind);

        }break;

        }
        output(vec);
    }


return 0;
}










以上的代码是有瑕疵的

对于插入的非法检查,几乎随机出来的每个操作都还是合法的

所有的插入操作都是合法的,测试就是不够充分的,必须要测出插入非法的会不会出问题。

插入非法的位置

对插入的位置+3就会随机生成超过原有大小的位置

ind = rand()%(vec->length +3)

然后我们设计一个百分之75是插入

百分之25是删除的改动

改动代码如下

int main()
{
    srand(time(0));
    #define MAX_OP 20
    Vector *vec = init(MAX_OP);
    int op ,ind ,val;
    for(int i=0 ;i<MAX_OP;i++){
        op = rand()%4;
        ind = rand()%(vec->length +3);
        val = rand()%100;
        switch(op){
            case 2:
            case 3:
            case 0:{
            printf("insert %d at %d to vector = %d\n",
                   val,ind , insert(vec,ind,val));
            insert(vec,ind,val);

        }break;
            case 1:{
            printf("erase item at %d from vector= %d \n",
                   ind,erase(vec,ind));
            erase(vec,ind);

        }break;

        }
        output(vec);
    }


return 0;
}

然我们继续更改,当前设计的顺序表的大小是固定的,但是我们想让他随机,可以自己扩容

加一个扩容操作。

int expand(Vector *vec)
{
    vec ->size *=2;
    vec ->data = (int *)rralloc(vec->data,sizeof(int)*vec->size);
    return 1;
}
int insert(Vector *vec, int ind, int val){
    if (vec == NULL ) return 0;
    if (vec->length == vec->size) {
        if (!expand(vec))
        return 0;}
    if (ind <0 || ind>vec->length ) return 0;

    for (int i = vec->length;i>ind;i--){
        vec->data[i] = vec->data[i-1];
    }
    vec->data[ind] = val;
    vec->length +=1;
    return 1;

}

扩容函数传入的顺序表

扩容为当前顺序表大小的一倍

用ralloc来扩容

怎么写扩容

malloc用来申请空间

free释放空间

realloc重新分配

重新分配声明一下对哪片空间重新分配

分配多大,

realloc分配成

realloc到底怎么工作的

他是如何扩容的,原有是p

realloc会试着在p后面申请空间,如果能成功申请的话,realloc他返回的值还是原来的数组首地址

如果申请失败,realloc就会调用malloc重新去分配一块空间

功会销毁之前的空间

当他申请到一片新的空间的时候,他会把原来空间的数据拷贝到新空间。拷贝过来后他在返回新申请空间的地址。

原来的空间还没有free,realloc当他成功申请一块新的空间后,会把之前的拷贝过来,并且会释放原来空间

如果申请第二段空间也失效,realloc不会释放掉原来的空间,realloc会返回一个空地址,代表重新分配空间失败,但是你原来的空间我没动。

申请失败,返回的空地址把vec->data的地址覆盖,原来的地址找不到了造成地址泄露。

最终代码

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
typedef struct Vector{
    int *data;
    int size,length;

}Vector;

Vector *init(int n){

    Vector *vec = (Vector *)malloc(sizeof(Vector));
    vec->data = (int*)malloc(sizeof(int)*n);
    vec->size = n;
    vec->length = 0;
    return vec;
}

void clear(Vector *vec){
    if(vec == NULL)return;
    free(vec->data);
    free(vec);
    return;
}

int expand(Vector *vec)
{
    int new_size = vec->size*2;
    int *p = (int *)realloc(vec->data,sizeof(int)*new_size);
    if (p==NULL) return 0;
    vec ->size *=new_size;
    vec ->data =p;
    return 1;
}
int insert(Vector *vec, int ind, int val){
    if (vec == NULL ) return 0;
    if (vec->length == vec->size) {
        if (!expand(vec))
        return 0;
    printf("expand vector size to %d success \n",vec->size);}
    if (ind <0 || ind>vec->length ) return 0;

    for (int i = vec->length;i>ind;i--){
        vec->data[i] = vec->data[i-1];
    }
    vec->data[ind] = val;
    vec->length +=1;
    return 1;

}

int erase(Vector *vec , int ind){
    if (vec == NULL ) return 0;
    if (vec->length == 0) return 0;
    if (ind <0 || ind>vec->length ) return 0;
    for(int i = ind+1;i<vec->length;i++){
        vec->data[i-1] = vec->data[i];
    }
    vec->length -=1;
    return 1;
}

void output(Vector *vec){
    printf("Vector(%d) = [",vec->length);
    for (int i = 0;i<vec->length ; i++){
        if (i!=0) printf(",");
        printf("%d",vec->data[i]);
    }
    printf("]\n");
    printf("\n");
    return;
}

int main()
{
    srand(time(0));
    #define MAX_OP 20
    Vector *vec = init(1);
    int op ,ind ,val;
    for(int i=0 ;i<MAX_OP;i++){
        op = rand()%4;
        ind = rand()%(vec->length +3);
        val = rand()%100;
        switch(op){
            case 2:
            case 3:
            case 0:{
            printf("insert %d at %d to vector = %d\n",
                   val,ind , insert(vec,ind,val));
            insert(vec,ind,val);

        }break;
            case 1:{
            printf("erase item at %d from vector= %d \n",
                   ind,erase(vec,ind));
            erase(vec,ind);

        }break;

        }
        output(vec);
    }


return 0;
}










 

标签:顺序,return,int,length,Vector,vec,ind,数据结构
来源: https://blog.csdn.net/m0_60961911/article/details/122772132

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有