IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 数据结构与算法 -> [数据结构与算法] 线性表之数组基本操作代码实现详解 -> 正文阅读

[数据结构与算法][数据结构与算法] 线性表之数组基本操作代码实现详解

活动地址:CSDN21天学习挑战赛

一、创建数组(为数组分配内存)

1.1 c语言

静态分配内存

内存分配在栈上,离开栈内存自动销毁。

可以直接创建数组并指定大小。

C99之前创建数组必须传入固定大小,如下:

int num[10];

C99开始支持传入变量的变长数组

int size = 10;
int num[size];
动态分配内存

内存分配在堆上,需要使用free手动释放,否则直到程序结束才释放。

使用malloc函数分配内存,如:

// 为数组分配一个可以存储10个int数据的内存空间
int* p_int = (int*)malloc(sizeof(int) * 10);

malloc分配的内存,在使用结束时要调用free函数手动释放:

free(p_int);

二、初始化数组

2.1 c语言

可以在创建时初始化,也可以创建后再初始化。

  1. 创建时初始化可以不写大小,申请空间时通过数据元素个数计算大小。
int num[] = {1, 2, 3};
  1. 在自定义函数中,如果数组创建后没有初始化,数组会被随机值填充。
  2. 在全局域或main函数中,如果数组创建后没有初始化,数组会被0填充。
  3. 当创建时初始化,初始化的元素个数比数组申请的大小少,即没有将数组所有元素初始化,未初始化的数组元素将被0填充。

代码验证如下:

#include <stdio.h>

// 全局域创建数组
int num1[3];
int num5[3] = {1};

void init_array()
{
    // 自定义函数局部域
    int num3[3];
    int num4[3] = {1};
    printf("自定义函数num3[1]: %d\n", num3[1]);
    printf("\n打印数组创建时初始化,未被初始化的元素\n");
    printf("自定义函数num4[1]: %d\n", num4[1]);
}

int main()
{
    printf("打印数组创建时未初始化,数组的元素\n");
    printf("全局域num1[1]: %d\n", num1[1]);
    int num2[3];
    printf("main函数num2[1]: %d\n", num2[1]);

    init_array();
    
    printf("全局域num5[1]: %d\n", num5[1]);
    int num6[3] = {1};
    printf("main函数num6[1]: %d\n", num6[1]);
    
    return 0;
}

打印结果如下:

打印数组创建时未初始化,数组的元素
全局域num1[1]: 0
main函数num2[1]: 0
自定义函数num3[1]: 21899

打印数组创建时初始化,未被初始化的元素
自定义函数num4[1]: 0
全局域num5[1]: 0
main函数num6[1]: 0

三、获取数组大小

3.1 c语言

数组容量大小(最多能存储的数据个数)

想要获取数组的内存大小,可以使用sizeof函数

int arr[10];
int max_size = sizeof(arr)/sizeof(arr[0]);
数组当前存储数据的个数(面向对象思想)

实际上我们需要的,常常是数组存储数据的个数,而不是数组最多能存储多少和数据,如果数组一开始分配内存比实际存储的数据所占内存大(实际上常常就是这样),就需要使用另一种方法了。

常用的是面向对象的思想,不要以为c语言是面向过程的语言,其实它早已偷偷加入了面向对象的东西,而且面向对象的思想,是思想,可以用任何语言实现。

利用c语言的结构体,创建一个数组结构体类型,每次操作数据记录当前长度。

// 以动态分配内存为例
typedef struct{
	int* data;		// 数组的首地址
	int  length;    // 数组的当前长度  
    int  maxSize;   // 数组最大容量大小
} Array;

四、插入元素

4.1 不需保证数组元素原有排序

当不需要保证数组元素原有排序时,不用指定插入位置,直接使用尾插法,不用移动元素,时间复杂度为O(1)

bool insertBack(Array* array, int num)
{
    if (array->length >= array->maxSize)
    {
        return false;
    }
    array->pData[array->length] = num;
    array->length++;

    return true;
}

4.2 需保证数组元素原有排序

当需要保证数组元素原有排序时,要指定插入位置,并且插入位置以后元素都要后移,为新元素腾出位置。

bool insert(Array* array, int index, int num)
{
    if (array == NULL || array->pData == NULL || array->length > array->maxSize)
    {
        return false;
    }

    for (int i = array->length; i > index; i--)
    {
        array->pData[i] = array->pData[i-1];
    }
    array->length++;
    array->pData[index] = num;

    return true;
}

当原数组无数值顺序,需要人为指定插入位置。

当原数组有数值顺序,要先将新元素的数值与原数组元素比较大小,找到对应位置,再调用上面函数。

五、删除元素

和插入元素一样,如果不需保证原有数组的顺序,需把最后一个元素覆盖要删除的元素即可,时间复杂度O(1)。

如果需保证原有数组的顺序,删除位置以后的元素要往前移动,以保证数组内存的连续性,时间复杂度O(n)。

以上复杂度只是删除操作的复杂度,如果需要查找定位,就另说了。这里仅说明需保证原有数组顺序的情况。

根据提供的数据不同,可分为以下两种方法:

5.1 指定索引删除

找到给定位置,将此位置后面的元素前移,把该位置的元素覆盖即可。

bool removeWithIndex(Array* array, int index)
{
    if (array == NULL || array->pData == NULL || array->length > array->maxSize)
    {
        return false;
    }

    for (int i = index+1; i < array->length; i++)
    {
        array->pData[i-1] = array->pData[i];
    }
    array->length--;

    return true;
}

5.2 指定数值删除

这里涉及了查找操作,需要先根据数值查找定位元素,再执行删除操作。

这里以穷举遍历查找为例,仅说明一下删除操作:

bool removeWithValue(Array* array, int value)
{
    if (array == NULL || array->pData == NULL || array->length > array->maxSize)
    {
        return false;
    }

    int tmpArray[array->length];
    int j = 0;
    for (int i = 0; i < array->length; i++)
    {
        if (array->pData[i] == value)
        {
            continue;
        }
        tmpArray[j++] = array->pData[i];
    }
    array->pData = tmpArray;
    array->length = j;

    return true;
}

六、访问元素

访问元素可以通过下标访问,也可以通过指针访问。

// 下标
int arr[10];
arr[1] = 2;
int a = arr[1];

// 指针
int arr[10];
*arr = 2; // 等价于arr[0] = 2;
int a = *(arr+1); // 等价于a = arr[1];
  数据结构与算法 最新文章
【力扣106】 从中序与后续遍历序列构造二叉
leetcode 322 零钱兑换
哈希的应用:海量数据处理
动态规划|最短Hamilton路径
华为机试_HJ41 称砝码【中等】【menset】【
【C与数据结构】——寒假提高每日练习Day1
基础算法——堆排序
2023王道数据结构线性表--单链表课后习题部
LeetCode 之 反转链表的一部分
【题解】lintcode必刷50题<有效的括号序列
上一篇文章      下一篇文章      查看所有文章
加:2022-08-19 19:31:09  更:2022-08-19 19:35:16 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/25 21:32:57-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码