数据结构(Day15)

一、学习内容

  1. 结构体位域

    #include <myhead.h>
    
    typedef struct
    {
    	int a:2;
    	short b:1;
    	char c:1;
    }m1;
    
    typedef struct
    {
    	char a:3;
    	short b:7;
    	int c:10;
    }m2;
    int main(int argc, const char *argv[])
    {
    	printf("%ld\n",sizeof(m1));
    	printf("%ld\n",sizeof(m2));
    	return 0;
    }

  2. 共用体(union)

    • 概念

      • 与结构体一样,自定义类型,允许在同一内存上存储不同类型的变量,但是多个变量一次只能使用或者赋值一个变量,多个变量共享内存空间。

    • 作用

      • 节约内存空间,多个变量共享一个内存空间。

    • 定义格式

      • union EUM { 类型1 成员1; 类型2 成员2; 类型3 成员3; };

    • 共用体注意事项

      • 内存占用,所有基础成员中最大的成员所占大小就是联合体内存大小。

      • 赋值或者使用时,一次只能赋值或者使用一个成员变量。

    • 共用体初始化

      •  #include <myhead.h>
        
        union EMU
        {
        	int age;
        	char a;
        	short b;
        	double c;
        };
        
        int main(int argc, const char *argv[])
        {
        	union EMU www;
        	www.age = 200;
        	www.a  ='W';
        	www.b = 10;
        	www.c = 120;
        	printf("www.age = %d\n",www.age);//第一个赋值可以输出
        	printf("www.a = %c\n",www.a);//第一个被第二个覆盖掉
        	printf("www.b = %d\n",www.b);//第二个被第三个覆盖掉
        	printf("www.c = %lf\n",www.c);//第三个被第四个覆盖掉
        	
        	
        	return 0;
        }

  3. 枚举

    • 枚举实际就是枚举常量

    • 定义格式

      • 枚举常量: 定义格式: enum 枚举名 { 成员1,成员2,成员3,成员4 };

        • 枚举成员直接使用,不需要结构体或者联合体那样引用。

        • 默认第一个成员是0,如果给第一个成员赋值,后面成员依次累加1

    • 枚举的初始化

  4. 数据结构绪论

    • 概念

      • 数据的组织方式,施加在数据上的一组操作,(增删改查等)

    • 数据

      • 能被计算机识别存储处理的符号集合

        • 数据分为数值类型和非数值类型

        • 数值:int a,123,float b;等我们熟知的变量和常量都是数值数据。

        • 非数值:mp3,光盘,磁带,电影视频。

    • 数据对象

      • 多个数据对象构成了数据

        • 例如:24081班,24071班,24091班 都属于数据对象,构成上海中心属于数据。

    • 数据元素

      • 多个数据元素构成了数据对象

        • 例如:24081班有27个(学生)数据元素。

    • 数据项

      • 数据元素的最小组成单位

        • 例如:数据元素张震有两条腿,有耳朵,有嘴,这些都是组成数据元素的最小单位。

        • 数据>数据对象>数据元素>数据项

        • 数据元素是组成数据的基本单位,数据项是数据的最小单位。

    • 数据结构体分为逻辑结构和物理结构体

      • 数据结构

        • 逻辑结构

          • 集合结构:数据元素之间没有关系

          • 线性结构:数据元素一对一的关系

          • 树形结构:数据元素一对多的关系

          • 图形结构:数据元素多对多的关系

        • 物理结构(真实的结构)

          • 顺序存储

            • 逻辑相邻的元素物理上也相邻

          • 链式存储

            • 逻辑相邻的元素物理上不一定相邻

          • 散列存储

            • 哈希存储,数据元素的存储和哈希函数和关键字有关(了解)

          • 索引存储

            • 在存储数据元素时建立一个索引表,以便快速查找

    • 顺序存储和链式存储的区别

        • 顺序存储必须占用连续的内存空间。

        • 链式存储内存空间连续与否均可。

        • 链式存储时节点体积较小,可以充分利用内存碎片。

        • 相同节点个数的顺序存储和链式存储,链式存储占用内存较多。

        • 链式存储和顺序存储都有优缺点,不能单纯的认为链式或者顺序存储较好。

  5. 线性表(部分)

    • 例如:顺序表,顺序栈,顺序队列,顺序串,单链表,双链表,循环链表都属于线性表。

        • 第一个元素没有前驱最后一个元素没有后继。

        • 中间 的元素都有唯一的前驱和唯一的后继,元素之间一对一关系。

    • 顺序表

      • 概念

        • 数据元素之间采用顺序存储的方式。

        • 数据元素之间占用连续的内存空间。

        • 采用数组存储顺序表。

    • 实现方式

        • 借助数组来存储顺序表。

        • 数组长度固定

        • 顺序表长度可变。

        • 顺序表长度<=数组长度。

    • 顺序表的组成

      • 顺序表借助数组来存储,封装结构体时需要封装数组。

      • 顺序表长度不固定,所以还需要封装计数器,统计顺序表元素个数。

      • 结构体内部成员data和len,不能直接使用,必须使用指针L来引用成员。

  6. 脑图

二、作业

1.定义结构体数组存储5个学生的信息:姓名,年龄,性别

定义函数实现输入,要求形参使用结构体指针接收

函数实现5个学生年龄排序(注意对年龄排序时,交换的是所有信息)

定义函数实现输出,要求形参使用结构体指针接收 

代码解答:

#include <myhead.h>

// 定义学生结构体,包含姓名、年龄和性别
typedef struct {
	char name[20];  // 存储学生的姓名,最大长度 20
	int age;        // 存储学生的年龄
	char sex[10];   // 存储学生的性别,最大长度 10,考虑 "female" 等情况
} stu, *sstu;

// 输入学生信息函数,参数为指向学生结构体数组的指针
int input_stu(sstu S) {
	for (int i = 0; i < 5; i++) {
		// 输入学生的姓名
		printf("请输入学生的名字:");
		fgets(S[i].name, sizeof(S[i].name), stdin);
		S[i].name[strcspn(S[i].name, "\n")] = 0; // 移除 fgets 读取的换行符

		// 输入学生的年龄
		printf("请输入学生的年龄:");
		scanf("%d", &S[i].age);

		// 输入学生的性别
		printf("请输入学生性别:");
		scanf("%s", S[i].sex);

		// 吃掉输入缓冲区中的多余换行符,避免下次 fgets 读取到它
		getchar();
		printf("\n");
	}
	return 0;
}

// 输出学生信息函数,参数为指向学生结构体数组的指针
int output_stu(sstu S) {
	for (int i = 0; i < 5; i++) {
		// 打印学生的姓名、年龄和性别信息
		printf("%s\t%d\t%s\n", S[i].name, S[i].age, S[i].sex);
	}
	return 0;
}

// 根据年龄对学生进行排序的函数,参数为指向学生结构体数组的指针
int sort_stu(sstu S) {
	stu temp; // 用于临时存储学生信息的变量
	// 冒泡排序,按年龄从小到大排序
	for (int i = 0; i < 5 - 1; i++) {
		for (int j = 0; j < 5 - i - 1; j++) {
			if (S[j].age > S[j + 1].age) {
				// 交换两个学生的所有信息
				temp = S[j];
				S[j] = S[j + 1];
				S[j + 1] = temp;
			}
		}
	}
	return 0;
}

// 主函数
int main(int argc, const char *argv[]) {
	// 动态分配内存,存储 5 个学生的结构体数组
	sstu S = (sstu)malloc(sizeof(stu) * 5); // 强制转换 malloc 返回的 void* 类型为 sstu 类型
	
	// 调用输入函数,输入 5 个学生的信息
	input_stu(S);
	
	// 调用排序函数,按年龄排序
	sort_stu(S);
	
	// 调用输出函数,输出排序后的学生信息
	output_stu(S);
	
	// 释放之前分配的动态内存,避免内存泄漏
	free(S);
	S = NULL; // 防止悬空指针

	return 0;
}

结果展现:

2.定义小车结构体,存储名称、价钱、颜色。定义两个变量a,b,初始化,实现ab互换。

代码解答:

#include <myhead.h>


// 定义小车结构体,包含名称、价钱和颜色
typedef struct {
    char name[20];   // 小车的名称
    float price;     // 小车的价格
    char color[10];  // 小车的颜色
} car;

int main() {
    // 定义两个小车变量 a 和 b
    car a = {"Toyota", 20000.0, "Red"};   // 初始化 a
    car b = {"BMW", 18000.0, "Blue"};   // 初始化 b

    // 打印互换前的小车信息
    printf("交换前:\n");
    printf("a: %s, %.2f, %s\n", a.name, a.price, a.color);
    printf("b: %s, %.2f, %s\n", b.name, b.price, b.color);

    // 互换 a 和 b 的信息
    car temp = a;
    a = b;
    b = temp;

    // 打印互换后的小车信息
    printf("\n交换后:\n");
    printf("a: %s, %.2f, %s\n", a.name, a.price, a.color);
    printf("b: %s, %.2f, %s\n", b.name, b.price, b.color);

    return 0;
}

成果展现:

三、总结

学习内容概述

1. 位域(Bit Fields)

位域是一种能够在结构体内存中精确控制数据成员所占位数的技术。主要用于节省内存,尤其在硬件寄存器中使用。

2. 共用体(Union)

共用体是一种允许多个成员共享同一块内存的自定义类型,可以有效节省内存,但同一时间只能使用一个成员。

3. 枚举(Enum)

 枚举用于定义一组命名常量,通常用于表示有限的、互斥的选项。枚举成员默认从 0 开始,也可以手动赋值。

4. 数据结构基本概念

数据:由数值类型和非数值类型组成,能被计算机存储和处理的符号集合。

数据:元素是构成数据的基本单位。

数据项:是数据元素的最小组成单位。

数据结构分类:

逻辑结构:集合结构、线性结构、树形结构、图形结构。

物理结构:顺序存储、链式存储、哈希存储、索引存储。

5. 线性表

线性表是一种具有一对一数据元素关系的数据结构,包含顺序表和链表等具体实现。

学习难点

1. 位域的内存对齐与实际内存使用:

如何在不同类型的数据之间正确分配位数,避免内存浪费。

2. 共用体的使用规则:

理解如何在不损坏数据的情况下有效利用内存,尤其是当不同类型数据共存时。

3. 数据结构的逻辑与物理存储差异:

如何根据需求选择合适的存储方式(顺序存储与链式存储)以优化性能。

4. 线性表的实现:

如何合理使用数组实现顺序表,并动态管理顺序表长度。

主要事项

1. 位域:

理解位域的数据成员如何分配位数,以及不同类型的数据成员的最大限制。

2. 共用体:

在使用共用体时,确保一次只能使用一个成员,防止数据覆盖。

3. 顺序存储与链式存储的权衡:

顺序存储适用于访问速度快的场景,而链式存储适合内存不连续的场景。理解何时应选用哪种存储方式。

4. 线性表的动态性:

顺序表使用数组存储,但数组长度是固定的。要确保顺序表不会超过数组长度,并且能够灵活扩展。

未来学习重点

1. 深入理解位域的应用场景:

特别是在嵌入式系统和硬件编程中,通过位域节省内存的实际应用。

2. 共用体在复杂场景中的使用:

探索如何在资源受限的场景下合理使用共用体,同时避免数据丢失或覆盖。

3. 链表的深入学习:

链式存储的优势在于节省内存碎片以及动态扩展能力,后续可重点学习单链表、双链表及其操作。

4. 复杂数据结构的实现:

在掌握顺序表和链式存储的基础上,未来可以探索栈、队列、哈希表和树等更复杂的数据结构。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值