数据结构之顺序表1

顺序表

结构定义

一个数组+2个元素(size数组大小,count数组储存元素个数)

#include <stdio.h>
#include <stdlib.h>
//结构定义
typedef struct vector{
		int size;//数组大小
		int count;//输出储存元素个数
		int *data;//数组本身的指针
}vector;

结构操作

初始化

vector *getNewVector(int n){**//返回的是一个size=n的顺序表**
		vector *p=(vector *)malloc(sizeof(vector));**//p是一个指向vector类型的指针,所占的空间大小是vectoor的结构体那么大**
		p->size=n;**//大小为n**
		p->count=0;**//初始化值为0(起始的时候没有元素)**
		p->data=(int *)malloc(sizeof(int)*n);**//p中的data对应分配的大小就是sizeof(int)*n个
}**

销毁

void clear(vector *v){
		if (v==NULL)return ;//由于是void函数返回直接是空值
		free(v->data);//先释放里面的内存
		free(v);//再释放外面的内存
		return;
}

插入

选取插入点A,将A后面所有的元素都平移至连续排列,然后将数据放入A位置

int insert(vector *v,int pos,int val){
		if(pos<0||**pos>v->count**)return 0;//判断数据合法性
		**if(v->size==v->count&&!expand(v))return 0;//扩容也不成功才返回0**
		if( v->size==v->count)return 0;//插入超出数组大小,插入不成功返回0
		//逆序遍历,顺序遍历会导致数据覆盖问题
		for(int i=v->**count-1**;i>=pos;i--){
			v->data[i+1]=v->data[i]
		}//移位操作
		v->data[pos]=val;//插入数据
		v->count+=1;//改变元素数
		return 1;
}

删除

删除A位置的元素,然后将A后面的元素向前平移至连续排列

int erase(vector *v,int pos){
		if(pos<0||pos>**=v->count**)return 0;//判断数据合法性
		//逆序无法完成,只能顺序
		for (int i=pos+1;i<v->count;i++){
				v->data[i-1]=v->data[i];
		}//移位操作
		v->count-=1;//改变元素数
		return 1;
}

自动扩容

插入过程中发现容量满了,再发起扩容

int expand(vector *v) {
    if (v == NULL) return 0;//指向空地址无法进行扩容操作
    //2倍扩容法,对data区进行扩容--realloc
    printf("expand v from %d to %d\\n", v->size, 2 * v->size);
    **int *p =** (int *)realloc(v->data, sizeof(int) * 2 * v->size);
    **if (p == NULL) return 0;**
    v->data = p;
    v->size *= 2;
    return 1;
}

**realloc的处理逻辑有3种方式
1.原内存后面有内存存在,所以直接在后面进行内存扩容返回原来的地址
2.原内存后面扩容区域不够,于是新开辟一段内存然后再拷贝原来内存的信息到新的内存中去,返回新的地址
3.找不到能达到扩容大小的区域,返回NULL,原内存不动
//此处有bug,会丢失原来存储信息
那么如何处理呢?来一个新的指针被realloc赋值,如何不为空再复制给data(上面绿色部分)**

测试代码

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

typedef struct vector {
    int size, count;
    int *data;
} vector;

vector *getNewVector(int n) {
    vector *p = (vector *)malloc(sizeof(vector));
    p->size = n;
    p->count = 0;
    p->data = (int *)malloc(sizeof(int) * n);
    return p;
}

int expand(vector *v) {
    if (v == NULL) return 0;
    printf("expand v from %d to %d\\n", v->size, 2 * v->size);
    int *p = (int *)realloc(v->data, sizeof(int) * 2 * v->size);
    if (p == NULL) return 0;
    v->data = p;
    v->size *= 2;
    return 1;
}

int insert(vector *v, int pos, int val) {
    if (pos < 0 || pos > v->count) return 0;
    if (v->size == v->count && !expand(v)) return 0;
    for (int i = v->count - 1; i >= pos; i--) {
        v->data[i + 1] = v->data[i];
    }
    v->data[pos] = val;
    v->count += 1;
    return 1;
}

int erase(vector *v, int pos) {
    if (pos < 0 || pos >= v->count) return 0;
    for (int i = pos + 1; i < v->count; i++) {
        v->data[i - 1] = v->data[i];
    }
    v->count -= 1;
    return 1;
}

void output_vector(vector *v) {
    int len = 0;
    for (int i = 0; i < v->size; i++) {
        len += printf("%3d", i);//记录第一行总长度从而来确定第二行的长度
    }
    printf("\\n");
    for (int i = 0; i < len; i++) printf("-");
    printf("\\n");
    for (int i = 0; i < v->count; i++) {
        printf("%3d", v->data[i]);
    }
    printf("\\n");
    printf("\\n\\n");
    return ;
}

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

int main() {
    srand(time(0));
    #define MAX_OP 20
    vector *v = getNewVector(2);//最开始只能加两个元素,但是上界仍然是20
    for (int i = 0; i < MAX_OP; i++) {
        int op = rand() % 4, pos, val, ret;
        switch (op) {
            case 0:
            case 1:
            case 2:
                pos = rand() % (v->count + 2);//为了取到可能的非法值,用随机数模取
                val = rand() % 100;
                ret = insert(v, pos, val);
                printf("insert %d at %d to vector = %d\\n", 
                    val, pos, ret);
                break;
            case 3:
                pos = rand() % (v->count + 2);
                ret = erase(v, pos);
                printf("erase item at %d in vector = %d\\n", 
                    pos, ret);
                break;
        }
        output_vector(v);
    }
    clear(v);
    return 0;
}

  • 4
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值