数据结构学习(1)——指针、结构体、链表(C语言)
算法题的对数据结构相关知识的要求较高,接下来将学习一段时间的数据结构,今天来介绍一下C语言中的指针、结构体和链表的知识。
指针
定义
指针是C语言中一个非常重要的知识点。首先需要明确的一点是:指针本身是一种数据类型,该变量保存的是对应类型变量的一个地址。保存了这个地址后,我们就可以通过这个地址访问到变量,操作该变量所在的内存空间(可以修改该变量)。
形象解释
小明在A地点放了1kg黄金 ,小明将A地址的地址写在一张纸Z1上,这张纸就相当于是一个指针变量指向黄金。小明将这张纸放在了B地点 ,又写了一张纸Z2,将Z1这张纸存放的地址 B地点 写在Z2这张纸上,那么Z2就相当于一个指针变量指向Z1。这样下来,小明就可以通过Z1找到黄金,也可以通过Z2找到Z1,从而找到黄金。这种方式就是通过指针访问变量的形象解释。
定义格式
数据类型 *指针变量名= 某个变量的地址/一段内存的地址;
同时,指针可以是多层的,例如要保存一个单层指针的地址,则可以加多一个*,然后对要保存的单层指针取址。(以此类推)
示例代码
#include <stdio.h>
#include <stdlib.h>int main() {int a = 10;//定义一个指针变量存储变量a的地址int *z1 = &a;//直接打印z1printf("z1=%d\n", z1);//打印z1地址下对应的变量printf("*z1=%d\n", *z1);//改变z1保存的地址对应的数据*z1 = *z1 + 10;printf("*z1=%d\n", *z1);int **z2 = &z1;printf("*z2=%d\n", *z2);printf("**z2=%d\n", **z2);
}
结构体
定义
结构体是C语言中一种重要的用户自定义复合数据类型,它允许将多个不同类型的数据元素(称为成员)组织在一起,形成一个整体。结构体的主要作用是封装数据,便于管理和操作复杂的数据集合。其作用和地位相当于Java中的对象,可以通过名字调用里面的成员并进行操作。
定义格式
①使用结构体变量
创建:struct 结构体名{ }; 大括号中可以书写不同类型的数据(属性)
调用:struct 结构体名 调用时的名 ; 相当于Java中的创建类的对象,然后通过对象调用属性
注意:使用结构体变量是调用使用的符号是" . "!
示例代码
#include <stdio.h>
#include <stdlib.h>struct Student {int id;int age;char name;
};
int main() {struct Student s;s.name = 'M';s.age = 18;s.id = 27;printf("name=%c\n", s.name);printf("age=%d\n", s.age);printf("id=%d\n", s.id);return 0;
}
②使用结构体指针
创建:struct 结构体名{ };
调用:struct 结构体名 *调用时使用的名=(结构体名 *)malloc(sizeof(结构体名))
注意:使用结构体指针需要使用malloc函数分配内存地址,并且需要用小括号转换成“结构体类型的指针”的数据类型。并且,与使用结构体变量不同的还有在调用的时候需要用符号 “->” 调用结构体中的属性。
示例代码
#include <stdio.h>
#include <stdlib.h>struct Student {int id;int age;char name;
};int main() {struct Student *s = (Student *)malloc(sizeof(Student));s->age = 18;s->id = 27;s->name = 'm';printf("age=%d\n", s->age);printf("id=%d\n", s->id);printf("name=%c\n", s->name);return 0;
}
输出结果与上面“使用结构体变量”一致!
链表
定义
链表是通过指针相连保存数据的一种数据结构,其存储单元为节点。链表的特点是节点在内存中不必连续存储,节点的逻辑顺序是通过每个节点中的指针链接实现的,可以只通过头节点访问到链表不同位置的数据。
一个节点需要包括两个变量:一个用来存储数据,另一个变量是一个指针变量,用来存储下一个节点的地址。由于两个变量类型不一致,就需要用到结构体指针。
定义方法(先介绍不用循环的)
我们要书写一个结构体指针,在里面定义两个变量data和*next,然后在主函数中创建多个节点,并分配内存,最后通过调用data和*next并对其赋值,就可以建立起各个节点的联系。注意,创建完链表之后只需要使用头节点操作链表中的数据!
如果想要在链表中添加数据,只需要创建一个新的节点,赋上对应的data和*next即可。以添加到链表最后为例,data可以是键盘输入的,*next为NULL。
示例代码
#include <stdio.h>
#include <stdlib.h>//定义一个结构体
struct ListNode {int data;ListNode *next;
};int main() {//先创建多个节点,并分配内存ListNode *node1 = (ListNode *)malloc(sizeof(ListNode));ListNode *node2 = (ListNode *)malloc(sizeof(ListNode));ListNode *node3 = (ListNode *)malloc(sizeof(ListNode));ListNode *node4 = (ListNode *)malloc(sizeof(ListNode));ListNode *node5 = (ListNode *)malloc(sizeof(ListNode));node1->data = 100;node2->data = 200;node3->data = 300;node4->data = 400;node5->data = 500;//接下来将所有的节点连接node1->next = node2;node2->next = node3;node3->next = node4;node4->next = node5;//接下来只能借助头节点进行链表的相关操作printf("1:%d\n", node1->data);printf("2:%d\n", node1->next->data);printf("3:%d\n", node1->next->next->data);printf("4:%d\n", node1->next->next->next->data);printf("5:%d\n", node1->next->next->next->next->data);//添加一个新的节点ListNode *newNode = (ListNode *)malloc(sizeof(ListNode));node5->next = newNode;//将输入的数字添加到下一个节点上int n;printf("请输入一个数据添加到下一个节点:");scanf("%d", &n);newNode->data = n;newNode->next = NULL;printf("6:%d\n", node1->next->next->next->next->next->data);return 0;
}