C语言线性表的实现(详解)

数据结构之线性表

线性表的基本概念:线性表是由0个或者多个数据元素的有限序列
特性是:
​ 1:数据元素之间都是有顺序的
​ 2:数据元素的个数是有限的,
​ 3:数据元素的类型是相同的
​ 性质是:
a0是线性表的第一个元素,只有一个后继,an为线性表的最后一个元素,只有一个前驱
​ 除去a0和an外的其他元素ai,既有前驱也有后继线性表可以逐项访问的顺序存取

线性表的顺序存储结构:指的是用一组地址连续的存储单元依次存储线性表中的数据元素
1: 当插入一个新的元素时,发现内存空间不足申请一块更大的内存空间
2: 将原空间的数据拷贝到新的内存空间
3: 释放旧的内存空间
4: 把元素放入新的空间

1: 动态的内存增加,将存放数据的内存放到堆上(堆的内存空间比较大,不容易发生溢出)
2: 动态数组,如果是5个元素,申请内存,拷贝数据,释放内存,插入第7个数据?
3: capacity容量表示在这一块的内存空间中可以存放多少元素
4: size的概念记录当前数组中具体的内存个数

在这里插入图片描述
程序的头部文件
在这里插入图片描述具体头文件的代码如下所示

 #ifndef DYNAMIC_ARRAY_H
#define DYNAMIC_ARRAY_H
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <string.h>
#include <iostream>


/*
	  线性表的基本概念:线性表是由0个或者多个数据元素的有限序列
	  特性是:1:数据元素之间都是有顺序的,2:数据元素的个数是有限的,3:数据元素的类型是相同的
	  性质:a0是线性表的第一个元素,只有一个后继,an为线性表的最后一个元素,只有一个前驱
	  除去a0和an外的其他元素ai,既有前驱也有后继线性表可以逐项访问的顺序存取

	  线性表的顺序存储结构:指的是用一组地址连续的存储单元依次存储线性表中的数据元素
	
	  1: 当插入一个新的元素时,发现内存空间不足申请一块更大的内存空间
	  2: 将原空间的数据拷贝到新的内存空间
	  3: 释放旧的内存空间
	  4: 把元素放入新的空间
	
	  // 动态的内存增加,将存放数据的内存放到堆上
	  // 动态数组,如果是5个元素,申请内存,拷贝数据,释放内存,插入第7个数据?
	  // capacity容量表示在这一块的内存空间中可以存放多少元素
	  // size的概念记录当前数组中具体的内存个数

*/




typedef struct DYNAMICARRAY {
	int* pAddr; // 具体存放数据的地址
	int size;  // 当前有多少个元素
	int capacity;  //当前容器最大容纳多少个元素

}Dynamic_Array;



// 初始化数组
Dynamic_Array* Init_Array();
// 插入
void Push_Back_Array(Dynamic_Array* arr, int value);
// 删除,根据位置对相应的数据进行删除
void Remove_Array(Dynamic_Array* arr, int pos);
// 根据值进行删除
void RemoveByValue_Array(Dynamic_Array* arr, int value);
//查找
int Find_Array(Dynamic_Array* arr, int value);
// 打印输出动态数组当中的值
void Print_Array(Dynamic_Array* arr);
//清空数组
void Clear_Array(Dynamic_Array* arr);
// 获得动态数组容量
int Capacity_Array(Dynamic_Array* arr);
//获得动态数组当前的元素个数
int Size_Array(Dynamic_Array* arr);
int At_Array(Dynamic_Array* arr, int pos);
//释放动态数组的内存
void FreeSpace_Array(Dynamic_Array* arr);


#endif

程序的主文件main
在这里插入图片描述主要文件代码如下所示:

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <iostream>
#include <string.h>
#include "DynamicArray.h"



// 初始化数组
Dynamic_Array* Init_Array() {
    // 申请内存
    Dynamic_Array* myArray =(Dynamic_Array*) malloc(sizeof(Dynamic_Array));
    // 初始化
    myArray->size = 0;
    myArray->capacity = 20;
    myArray->pAddr = (int *)malloc(sizeof(int) * myArray->capacity);
    return myArray;

};
// 插入
void Push_Back_Array(Dynamic_Array* arr, int value) {
    if (arr == NULL) {
        return;
    }
    // 判断空间是否足够
    if (arr->size == arr->capacity) {
        // 第一步,申请一块更大的内存空间,新的空间默认就旧空间的2倍
        int* newSpace = (int*)malloc(sizeof(int) * arr->capacity * 2);
        // 第二步,拷贝数据到新的内存空间
        memcpy(newSpace, arr->pAddr, arr->capacity * sizeof(int));
        // 释放旧空间的内存
        free(arr->pAddr);
        // 更新容量
        arr->capacity = arr->capacity * 2;
        arr->pAddr = newSpace;
    }
    //插入新的元素,从尾部插入
    arr->pAddr[arr->size] = value;
    arr->size++;
};

// 删除,根据位置对相应的数据进行删除
void Remove_Array(Dynamic_Array* arr, int pos) {
    if (arr == NULL) {
        return;
    }
    // 判断位置是否有效
    if (pos < 0 || pos >= arr->size) {
        return;
    }
    // 删除元素
    for (int i = pos; i < arr->size - 1; i++) {
        arr->pAddr[i] = arr->pAddr[i + 1];
    }

    arr->size--;

};


// 根据值进行删除
void RemoveByValue_Array(Dynamic_Array* arr, int value) {
    if (arr == NULL) {
        return;
    }
    // 找到值的位置
    int pos = Find_Array(arr,value);
    for (int i = 0; i < arr->size; i++) {
        if (arr->pAddr[i] == value) {
             pos = i;
             break;
        }
    }
    // 根据位置删除
    Remove_Array(arr, pos);

};
//查找
int Find_Array(Dynamic_Array* arr, int value) {
    if (arr == NULL) {
        return -1;
    }
    int pos = -1;
    for (int i = 0; i < arr->size; i++) {
        if (arr->pAddr[i] == value) {
            pos = i;
            break;
        }
    }
    return pos;
};
// 打印
void Print_Array(Dynamic_Array* arr) {
    if (arr == NULL) {
        return;
    }
    // 使用for循环打印输出相关的数据
    for (int i = 0; i < arr->size; i++) {
        printf("%d ", arr->pAddr[i]);

    }
    printf("\n");

};


//清空数组
void Clear_Array(Dynamic_Array* arr) {
    if (arr == NULL) {
        return;
    }
    // pAddr - > 空间
    arr->size = 0;
};
// 获得动态数组容量
int Capacity_Array(Dynamic_Array* arr) {
    if (arr == NULL) {
        return -1;
    }
    return arr->capacity;
};
//获得动态数组当前的元素个数
int Size_Array(Dynamic_Array* arr) {
    if (arr == NULL) {
        return -1;
    }
    return arr->size;
};
int At_Array(Dynamic_Array* arr, int pos) {
    if (arr == NULL) {
        return -1;
    }
    return arr->pAddr[pos];
};
//释放动态数组的内存
void FreeSpace_Array(Dynamic_Array* arr) {
    if (arr == NULL) {
        return;
    }

    // 先释放动态数组内存中里面那块的内存
    if (arr->pAddr != NULL) {
        free(arr->pAddr);
    }
    free(arr);

};


int main(void) {
    Dynamic_Array* myArray = Init_Array();
    // 打印输出数组容量
    printf("数组容量:%d\n", Capacity_Array(myArray));
    printf("数组大小:%d\n", Size_Array(myArray));

    // 插入元素
    for (int i = 0; i < 30; i++) {
        Push_Back_Array(myArray, i);
    }
    printf("数组容量:%d\n", Capacity_Array(myArray));
    printf("数组大小:%d\n", Size_Array(myArray));
    
    // 删除里面的数据
    RemoveByValue_Array(myArray,0);
    RemoveByValue_Array(myArray, 27);
    
    printf("数组容量:%d\n", Capacity_Array(myArray));
    printf("数组大小:%d\n", Size_Array(myArray));
    
    // 查找第五个位置
    int pos = Find_Array(myArray, 5);
    printf("查找5的位置pos:%d  %d\n",pos, At_Array(myArray,pos));


    // 打印
    Print_Array(myArray);
    
    //销毁
    FreeSpace_Array(myArray);system("pause");
    return 0;

}

使用代码模拟线性表实现数据的增,删,改,查(程序的运行结果如下所示)

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/192331.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Java代码生成器,一键在线生成,支持自定义模板

【Java代码生成神器】自动化生成Java实体类、代码、增删改查功能&#xff01;点击访问 推荐一个自己每天都在用的Java代码生成器&#xff01;这个网站支持在线生成Java代码&#xff0c;包含完整的Controller\Service\Entity\Dao代码&#xff0c;完整的增删改查功能&#xff01…

给国外客户价格报低了怎么办

前一段时间有一个单子的货发出去了&#xff0c;被朋友提醒才发现自己报错了价格&#xff0c;造成了亏损&#xff0c;而报错价格的原因并不是自己看错了或者是抄错了价格&#xff0c;而是自己的脑子里记错了产品的价格列表。 如果不是朋友善意的提醒&#xff0c;大概我会一直错…

.NET的Dockerfile文件编写要点——以WOL项目为例

本文以 WOL 的.NET 项目为例&#xff0c;介绍了 Dockerfile 的基础知识和编写要点&#xff0c;旨在帮助读者更好地理解和掌握如何为 .NET 应用创建和优化 Dockerfile。 1. 背景 前面我们已经勾选了 Docker 容器化支持&#xff0c;项目已经生成了一个默认的 Dockerfile。但在实…

快速上手Banana Pi BPI-R4 MediaTek MT7988A 开源路由器开发板

基础开发 准备开发 * 准备8G以上TF卡、USB转串口线、Ubuntu系统* 使用 USB 串行电缆&#xff08;3.3V TTL&#xff0c;波特115200&#xff09;连接到 BPI-R4 上的调试控制台G接地&#xff1b;RXBPI-R4输入&#xff1b;TXBPI-R4输出* BPI-R4 引导程序和设备选择跳线设置* 例子…

部署Jenkins

一、介绍 Jenkins 、Jenkins概念 Jenkins是一个功能强大的应用程序&#xff0c;允许持续集成和持续交付项目&#xff0c;无论用的是什么平台。这是一个免费的源代码&#xff0c;可以处理任何类型的构建或持续集成。集成Jenkins可以用于一些测试和部署技术。Jenkins是一种软件允…

代码随想录算法训练营第五十天|309. 买卖股票的最佳时机含冷冻期、714. 买卖股票的最佳时机含手续费

LeetCode 309. 买卖股票的最佳时机含冷冻期 题目链接&#xff1a;309. 买卖股票的最佳时机含冷冻期 - 力扣&#xff08;LeetCode&#xff09; 所谓的冷冻期&#xff0c;就是卖了股票后的第二天不能买入该股票&#xff08;股票上的N2,N1是今天卖明天能买)&#xff0c;所以影响到…

推荐你一个基于Koin, Ktor Paging等组件的KMM Compose Multiplatform项目

推荐你一个基于Koin, Ktor & Paging等组件的KMM Compose Multiplatform项目 Kotlin Multiplatform Mobile&#xff08;KMM&#xff09;已经从一个雄心勃勃的想法发展成为一个稳定而强大的框架&#xff0c;为开发人员提供了在多个平台上无缝共享代码的能力。通过最近的稳定…

肖sir __数据库练习__001

建表语句&#xff1a; create table student ( id int(4),age int(8),sex int(4),name varchar(20), class int(4), math int(4)) DEFAULT charsetutf8; INSERT into student VALUES(1,25,1,‘zhansan’,1833,90); INSERT into student VALUES(2,25,1,‘lisi’,1833,67); INSER…

单片机学习1——点亮一个LED灯

Keil软件编写程序&#xff1a; 特殊功能寄存器声明&#xff1a; #include<reg52.h>sbit LED P1^0;void main() {LED 0;while(1); } 代码说明&#xff1a; sbit 语句是特殊功能位声明。 生成HEX文件&#xff0c;这个文件是下载到单片机里的文件。Options for Target…

三方支付接口成为了电商竞争力的新动力

在当前快速发展的互联网时代&#xff0c;随着电子商务行业的兴起&#xff0c;支付体验已经成为企业获取竞争优势的重要因素。一个快速、安全、便捷的支付环节不仅可以提升用户的体验&#xff0c;还能有效促进交易的完成。在众多支付解决方案中&#xff0c;三方支付接口因其独特…

CMakeList项目构建

CMakeList项目构建 OVERVIEW CMakeList项目构建cmake1.变量定义2.指定源文件路径3.指定头文件路径4.字符串操作5.日志打印6.预定义宏 cmake、makefile都是项目构建工具&#xff0c;通过make命令进行项目构建&#xff0c;大多的IDE都集成了make项目构建&#xff0c;如visual stu…

Java Flight Record 详解

核心概念 Java Flight Record 提供一个低开销的数据收集框架&#xff0c;用于对 Java 应用程序和 HotSpot JVM 进行故障排除。Flight Recorder 记录源自应用程序、JVM和操作系统的事件 Flight Record&#xff0c;顾名思义&#xff0c;相当于飞机黑匣子里保存的飞行记录 事件 …

2023-11-27 LeetCode每日一题(子数组的最小值之和)

2023-11-27每日一题 一、题目编号 907. 子数组的最小值之和二、题目链接 点击跳转到题目位置 三、题目描述 给定一个整数数组 arr&#xff0c;找到 min(b) 的总和&#xff0c;其中 b 的范围为 arr 的每个&#xff08;连续&#xff09;子数组。 由于答案可能很大&#xff…

Shopee买家号想要多开怎么解决?

拥有多个Shopee买家号有很多优势。多账号可以帮助卖家获得更多流量、还能帮助提供关键词排名、提高销量等。 但是要管理多个Shopee买家号并非易事。面对不同账号的登录、注销和切换&#xff0c;可能会花费大量的时间和精力。而且&#xff0c;Shopee平台对于使用同一IP地址同时登…

DevEco Studio在预览器上快速定位元素所在的组件代码位置

常规开发过程中 如果我们的组件过多 找对象就会比较困难 我们可以点击如下图指向位置 这边呢 就有一个组件树 我们可以快速定位到当前元素的代码位置 同时你在点元素的时候 代码它也给你标记出来了

仅2万粉,带了2.6万件的货!TikTok Shop美区达人周榜(11.13-11.19)

11月24日&#xff0c;TikTok Shop近日公布了美国市场和英国市场的全托管黑五大促战绩。数据显示&#xff0c;11月14日至11月20日&#xff0c;其美国市场的订单量环比10月20日-10月26日增长了205%。 家居户外热销品有&#xff1a;数码触摸屏相框、毛绒地毯、家居毛毯。黑马商品…

C语言基础篇5:指针(一)

指针是C语言的核心、精髓所在&#xff0c;用好了指针可以在C语言编程中起到事半功倍的效果。指针一方面可以提高程序的编译效率和执行速度&#xff0c;而且还可以通过指针实现动态的存储分配&#xff0c;另一方面使用指针可使程序更灵活&#xff0c;便于表示各种数据结构&#…

学习.NET验证模块FluentValidation的基本用法(续3:ASP.NET Core中的调用方式)

FluentValidation模块支持在ASP.NET Core项目中进行手工或自动验证&#xff0c;主要验证方式包括以下三种&#xff1a;   1&#xff09;手工注册验证类&#xff0c;并在控制器或其它模块中调用验证&#xff1b;   2&#xff09;基于ASP.NET验证管道&#xff08;validation …

CountDownLatch实战应用——批量数据多线程协调异步处理(主线程执行事务回滚)

&#x1f60a; 作者&#xff1a; 一恍过去 &#x1f496; 主页&#xff1a; https://blog.csdn.net/zhuocailing3390 &#x1f38a; 社区&#xff1a; Java技术栈交流 &#x1f389; 主题&#xff1a; CountDownLatch实战应用——批量数据多线程协调异步处理(主线程执行事务…

基于SpringBoot的超市信息管理系

✌全网粉丝20W,csdn特邀作者、博客专家、CSDN新星计划导师、java领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ &#x1f345;文末获取项目下载方式&#x1f345; 一、项目背景介绍&#xff1a; 随着我国经济的不断发…