基础数据结构1:顺序表结构、动态扩容、例子

顺序表
顺序表的结构定义

​ 一种更高级的数组,一片连续存储空间存储元素,存储任意类型的元素,但是不能混着存

​ 定义三个关键参数:

size:数组空间大小
length:已具有元素多少,存了多少个
data_type:存的类型

操作:插入、删除

​ 插入:插到中间,就意味着后面的元素都要往后移动,最安全的做法是从最后开始向后移动,完成后关键参数需要修改(length修改)

​ 删除:告诉计算机该空间是可以修改的,因此可以用后面的覆盖掉前面的,同样最后需要修改length。

动态扩容

​ malloc:管开不管置零

​ calloc:管开也管置零,但不能扩容

​ realloc:管开管埋管扩容,扩容格式

example:
	(int *)realloc(vec->data, sizeof(vec->length + extr_length));
顺序表的一个例子:

实现一个int类型的顺序表,需要执行插入、清除、扩容、回收内存的操作。

/*  思路:          
  初始化:返回顺序表的首地址  
  顺序表的销毁操作:是否存在,释放哪片空间        
                                                   
  插入操作:传去哪里,传什么,插在哪里             
    判断能否插入(操作是否违法)                   
    将插入位置之后的所有元素向后移动一位         
    完成之后插入                                 
    插入完成之后修改length  

 删除操作:删谁的,删哪
    判断是否合法 
    删除位后面的覆盖掉前面的              
    修改length   
 
 输出顺序表操作:明确输出谁即可           
    判断是否合法           
*/                                              

/*                                                                                      
测试:选取一个随机值(srand(time(0)))                                                  
随机插入100以内的数,20次                                                                   
        index如何取到负数                                                                           
                         
*/                                                                                       
                           
/*   动态开辟内存                                                                                
    malloc:堆区开辟,不清空,返回首地址                                                    
    calloc:堆区开辟,请空,返回首地址                                                      
    realloc:对连续空间再次开辟,
        会优先尝试在原来的空间上扩容返回原来的,
        不行的话会找一个够大的空间,然后把原来的拷贝过来,再释放原来的空间,最后返回新的地址值。
        如果发现找不到这样的空间的话,realloc仍让会返回,不过返回的地址是NULL空地址。
注意动态开辟的话如果直接返回到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;
}


int insert(vector *vec, int ind, int val){
    if (ind < 0 || ind > vec->length) return 0;
    if (vec == NULL) 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 (ind > vec->length || ind < 0) return 0;
    for(int i = ind; i < vec->length; i ++){
        vec->data[ind - 1] = vec->data[i];
    }
    vec->length -= 1;
    return 1;
}

int expand(vector *vec){
    int extr = vec->size;
    int *p;
    while(extr){
        p = (int *)realloc(vec->data, sizeof(int) * (vec->length + extr));
        if (p) break;
        extr /= 2;
    }
    if (!extr) return 0;
    vec->data = p;
    vec->size += extr;
}


void clear(vector *vec){
    free(vec->data);
    free (vec);
    return;
}

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


int main(){
    srand(time(0));
    #define len 100
    vector *vec = init(len);
    for(int i = 0; i < len; i ++){
        int loop = rand() % 4;
        int ind = rand() % (vec->length + 3) - 1;
        int val = rand() % 100;
        switch(loop){
            case 0:
            case 1:
            case 2:{
                printf("insert %d at %d to vector ,now :%d\n", val, ind, insert(vec , ind , val));
            }break;
            case 3:{
                printf("erase a num at %d from vector,now :%d\n", ind, erase(vec, ind));
            }break;
        }
        output(vec);
        printf("\n");
    }
    clear(vec);
    #undef len
    return 0;
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值