【C-数据结构】顺序表(int)

实现方式

以动态数组的方式实现,多了扩容的功能

顺序表特点

  1. 可以随机访问,查找和修改方便
  2. 添加和删除的开销大,可以会移动大量元素
  3. 扩充容量的开销大,会拷贝大量元素,增加时间和空间的开销,建议初始化时多申请一些
  4. 适合频繁查找的场景,不适合频繁增删的场景





设计数据结构


有三个元素
  1. 指向堆空间的指针
  2. 当前长度
  3. 数组容量
typedef struct Array {
    int *_pdata;
    int _size;
    int _capacity;
}Array_t, *pArray_t;



动态数组的相关操作

  1. 容量(扩容、判空、判满)
  2. 初始化(申请堆空间)
  3. 销毁(销毁堆空间)
  4. 插入(尾部插入、有序插入)
  5. 删除(按值删除、尾部删除)
  6. 查找(按值查找)
  7. 修改(按值修改)





头文件 array.h

#ifndef __ARRAY_H__
#define __ARRAY_H__

typedef struct Array
{
    int *_pdata;
    int _size;
    int _capacity;
}Array_t, *pArray_t;

int arr_empty(pArray_t parr);
int arr_full(pArray_t parr);

//初始化    
void arr_init(pArray_t parr, int capacity);
//扩容
void arr_reallocate(pArray_t parr);
//增加
int arr_push_back(pArray_t parr, int val);
int arr_insert(pArray_t parr, int val);
//删除
int arr_erase(pArray_t parr, int val);
int arr_pop_back(pArray_t parr);
//查找
int* arr_find(pArray_t parr, int val);
//修改
int arr_modify(pArray_t parr, int oldval, int newval);


//销毁申请的堆空间
void arr_destory(pArray_t parr);
//展示数组所有元素
void arr_show(pArray_t parr);


#endif



实现文件 array.c

#include "array.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

void arr_init(pArray_t parr, int capacity)
{
    parr->_pdata = (int*)calloc(capacity, sizeof(int));
    parr->_size = 0;
    parr->_capacity = capacity;
}

void arr_show(pArray_t parr)
{
    if (!arr_empty(parr)) {
        printf("arr_data: ");
        for (int i = 0; i < parr->_size; ++i) {
            printf("%d ", parr->_pdata[i]);
        }
        printf("\n");
        
        printf("arr_size: %d\n", parr->_size);
        printf("arr_capacity: %d\n", parr->_capacity);
    }
    else {
        printf("arr is empty!\n");
    }
}

//扩容
void arr_reallocate(pArray_t parr)
{
    if (arr_full(parr)) {
        //保存旧数据
        Array_t tmp = *parr;
        
        //确定新容量
        int newcapacity = 2 * tmp._capacity == 0 ? 1 : 2 * tmp._capacity;
        //申请新空间
        parr->_pdata = (int *)calloc(newcapacity, sizeof(int));
        //拷贝数据
        memcpy(parr->_pdata, tmp._pdata, tmp._size * sizeof(int));
        parr->_capacity = newcapacity;

        //释放旧空间
        free(tmp._pdata);
        tmp._pdata = NULL;
    }
}

//增加, 有序
int arr_push_back(pArray_t parr, int val)
{
    if (arr_full(parr)) {
        arr_reallocate(parr);
    }

    //插在末尾
    parr->_pdata[parr->_size++] = val;

    return 0;
}

int arr_insert(pArray_t parr, int val)
{
    if (arr_full(parr)) {
        arr_reallocate(parr);
    }
   
    //空表时直接插入
    //非空时,从后往前找到第一个小于等于插入值的,放其后,否则元素后移
    //找不到时,放首位
    
    if (arr_empty(parr)) {
        parr->_pdata[parr->_size++] = val;
    }
    else {
        int i = parr->_size - 1;
        for (; i >= 0; --i) {
            if (parr->_pdata[i] > val) {
                parr->_pdata[i + 1] = parr->_pdata[i];
            }
            else {
                parr->_pdata[i + 1] = val;
                parr->_size++;
                break;
            }
        }

        if (val < parr->_pdata[0]) {
            parr->_pdata[0] = val;
            parr->_size++;
        }
    }

    return 0;
}


//删除
int arr_erase(pArray_t parr, int val)
{
    //空表
    if (arr_empty(parr)) {
        printf("Arr is empty, cannot erase!\n");
        return -1;
    } 

    //从头遍历,如果等于val, ++count, --size, 否则 arr[i - count] = arr[i]
    int count = 0;
    int size = parr->_size;
    for (int i = 0; i < parr->_size; ++i) {
        if (val == parr->_pdata[i]) {
            ++count;
            --size;
        }
        else {
            parr->_pdata[i - count] = parr->_pdata[i];
        }
    }

    if (0 == count) {
        printf("Not found, cannot erase!\n");
        return -1;
    }
    else {
        parr->_size = size;
        return 0;
    }
}

int arr_pop_back(pArray_t parr)
{
    if (arr_empty(parr)) {
        fprintf(stderr, "array is empty, cannot delete elem!\n");
        return -1;
    }

    parr->_size--;
    return 0;
}

//查找
int* arr_find(pArray_t parr, int val)
{
    if (!arr_empty(parr)) {
        for (int i = 0; i < parr->_size; ++i) {
            if (val == parr->_pdata[i]) {
                return &parr->_pdata[i];
            }
        }        
    }
    
    return NULL;
}

//修改
int arr_modify(pArray_t parr, int oldval, int newval)
{
    //空表
    if (arr_empty(parr)) {
        printf("arr is empty!\n");
        return -1;
    }

    int *ret = arr_find(parr, oldval);
    if (NULL == ret) {
        printf("Not found, cannot modify!\n");
        return -1;
    }
    else {
        *ret = newval;
        return 0;
    }
}

int arr_empty(pArray_t parr)
{
    return parr->_size == 0;
}

int arr_full(pArray_t parr)
{
    return parr->_size == parr->_capacity;
}

void arr_destory(pArray_t parr)
{
    if (parr->_pdata) {
        free(parr->_pdata);
        parr->_pdata = NULL;
    }
}



测试文件 test_arr.c

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

int main() 
{
    //申请数组
    pArray_t arr = (pArray_t)malloc(sizeof(Array_t));
    arr_init(arr, 10);
    arr_show(arr);

    for (int i = 0; i < 10; ++i) {
        arr_push_back(arr, i + 3);
    }
    arr_show(arr);

    printf("\n---------test arr_insert------------\n");
    arr_insert(arr, 1);
    arr_insert(arr, 10);
    arr_show(arr);

    printf("\n---------test arr_erase------------\n");
    arr_erase(arr, 3);
    arr_erase(arr, 10);
    arr_show(arr);

    printf("\n---------test arr_erase------------\n");
    arr_pop_back(arr);
    arr_pop_back(arr);
    arr_show(arr);


    //释放数组
    arr_destory(arr);
    free(arr);
    arr = NULL;

    return 0;
}
  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值