线性数据结构---顺序表

 本文为学习数据结构过程中的笔记,内容较为浅显,有问题的评论区见~~

一、基本概念

        顺序表是一种有序的数据结构,用于存储一组具有相同数据类型的元素。顺序表中的元素在内存中是连续存放的,因此可以通过下标直接访问元素。

优点:

        访问速度快:可以通过下标直接访问元素,时间复杂度为O(1)。

        占用空间少:连续存储减少了空间开销。

缺点:

        插入和删除操作效率低:需要移动大量元素,时间复杂度为O(n)。

顺序表有两种实现方式:

        第一种是分配一块固定的的内存(数组),缺点是我们通常无法事先确定需要存储多少数据,从而难以选择合适的数组长度。若长度过小,则很可能无法满足使用需求;若长度过大,则会造成内存空间浪费。

        第二种方式是使用动态数组实现,它继承了数组的各项优点,并且可以在程序运行过程中进行动态扩容。本文主要讨论第二种方式。

二、结构定义

数据类型为int类,capacity用来保存顺序表的容量

// 定义顺序表结构
typedef struct {
    int* data;
    int capacity;
} DynamicArray;

// 初始化顺序表 
void initArray(DynamicArray* array);
// 动态调整顺序表容量
void resizeArray(DynamicArray* array, int newCapacity);
// 插入元素
void insertElement(DynamicArray* array, int element, int position);
// 删除元素
void deleteElement(DynamicArray* array, int position);
// 查找元素
int findElement(DynamicArray* array, int element);
// 修改元素
void updateElement(DynamicArray* array, int position, int newElement);
// 打印
void printArray(DynamicArray* array);
// 释放内存
void freeArray(DynamicArray* array);

三、内容实现

1.初始化顺序表

初始化数据为空,容量为0

void initArray(DynamicArray *array) {
    array->data = NULL;
    array->capacity = 0; 
}

2.动态调整顺序表容量

使用realloc函数先判断当前的指针是否有足够的连续空间,如果有,扩大data指向的地址,并且将data返回,如果空间不够,先按照newCapacity指定的大小分配空间,将原有数据从头到尾拷贝到新分配的内存区域,而后释放原来data所指内存区域(注意:原来指针是自动释放,不需要使用free),同时返回新分配的内存区域的首地址。

void resizeArray(DynamicArray* array, int newCapacity) {
    int* newData = (int*)realloc(array->data, newCapacity * sizeof(int));
    if (newData) {
        array->data = newData;
        array->capacity = newCapacity;
    }
    else {
        printf("内存分配失败!\n");
    }
}

3.插入元素

先判断插入位置是否合法,然后将顺序表的容量+1,如果插入位置为表的尾部则直接插入,否则需要先移动元素位置再插入,过程如下图:

插入元素5到位置1

void insertElement(DynamicArray* array, int element, int position) {
    if (position < 0 || position > array->capacity) {
        printf("插入位置无效!\n");
        return;
    }
    //元素容量+1
    resizeArray(array, array->capacity + 1);
    //尾插则直接插入
    if (position == array->capacity - 1) {
        array->data[position] = element;
    }
    else {//否则移动后面元素并插入到指定位置
        for (int i = array->capacity - 1; i > position; i--) {
            array->data[i] = array->data[i - 1];
        }
        array->data[position] = element;
    }
}

4.删除元素

先判断删除元素的位置是否合法(也可以修改为遍历表来找到对应元素),如果位置位于表尾则直接删除,否则移动元素位置覆盖需要删除的元素,再更新表的容量,过程如下图:

删除位置1的元素2

void deleteElement(DynamicArray* array, int position) {
    if (position < 0 || position >= array->capacity) {
        printf("删除位置无效!\n");
        return;
    }

    if (position == array->capacity - 1) {
        // 对于表尾元素,直接删除
        resizeArray(array, array->capacity - 1);
    }
    else {
        // 否则移动表内元素位置
        for (int i = position; i < array->capacity - 1; i++) {
            array->data[i] = array->data[i + 1];
        }
        resizeArray(array, array->capacity - 1);
    }
}

5.查找元素

通过元素内容来遍历表查找,如果知道元素位置可以直接获取元素内容

int findElement(DynamicArray* array, int element) {
    for (int i = 0; i < array->capacity; i++) {
        if (array->data[i] == element) {
            return i;
        }
    }
    printf("没有该元素\n");
    return -1; 
}

6.修改元素

先判断修改位置是否合法,将新元素赋值到该位置

void updateElement(DynamicArray* array, int position, int newElement) {
    if (position < 0 || position >= array->capacity) {
        printf("修改位置无效!\n");
        return;
    }
    array->data[position] = newElement;
}

7.打印表中内容

遍历表并打印

void printArray(DynamicArray* array) {
    for (int i = 0; i < array->capacity; i++) {
        printf("%d ", array->data[i]);
    }
    printf("\n");
}

8.释放内存

void freeArray(DynamicArray* array) {
    free(array->data);
    array->capacity = 0;
}

9.主函数与部分测试用例

int main() {
    DynamicArray array; 
    initArray(&array); // 测试插入元素
    printf("测试插入元素:\n"); 
    insertElement(&array, 10, 0); 
    insertElement(&array, 20, 1); 
    insertElement(&array, 30, 2); 
    printf("顺序表内容: ");
    printArray(&array); // 测试删除元素 
    printf("\n测试删除元素:\n");
    deleteElement(&array, 1); 
    printf("删除元素后顺序表内容: "); 
    printArray(&array); // 测试查找元素 
    printf("\n测试查找元素:\n"); 
    int position = findElement(&array, 30);

    if (position != -1) { 
        printf("元素30的位置: %d\n", position); 
    } else { 
        printf("元素30未找到\n");
    } 
    // 测试修改元素
    printf("\n测试修改元素:\n");
    updateElement(&array, 0, 15); 
    printf("修改元素后顺序表内容: ");

    printArray(&array); // 测试边界情况
    printf("\n测试边界情况:\n"); 
    insertElement(&array, 25, array.capacity); // 插入到最后 
    deleteElement(&array, 0); // 删除第一个元素

    printf("边界情况测试后顺序表内容: ");
    printArray(&array); // 释放顺序表内存 
    freeArray(&array); 
    return 0;
}

全文完,赏个点赞收藏吧~~

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值