认识线性表
/* 1.线性表: ---数据结构中最简单的一种存储结构,专门用于存储逻辑关系为"一对一"的数据 2.线性表存储结构,可细分为"顺序存储结构"和"链式存储结构",即如下所示 线性表: 1.顺序表(顺序存储结构) 2.链表(链式存储结构) 3.存储的类型要求 使用线性表存储的数据,如同向数组中存储数据那样要求数据类型必须一致 线性表存储的数据,要么全部都是整型,要么全部都是字符串 一半整型,另一半是字符串的一组数据无法使用线性表存储 4.前驱与后继: 一组数据中的每个个体被称为“数据元素”(简称为“元素”) 1.前驱 某一元素的左侧相邻元素称为“直接前驱”,位于此元素左侧的所有元素都统称为“前驱元素” 2.后继 某一元素的后侧相邻元素称为“直接后继”,位于此元素右侧的所有元素都统称为“后继元素” */


认识顺序表
/* 顺序表: ---它对数据的物理存储结构有要求 顺序表存储数据时,会提前申请一块足够大小的内存 然后将数据依次存储起来 存储时做到数据元素之间不留一丝缝隙(即:连续) */
初始化顺序表
# include <stdio.h> # include <malloc.h> // 定义表格类型 typedef struct { int* head; // 指针,存储申请的内存首地址 int length; // 当前数据个数 int size; // 元素个数(最大容量) }Table; // 生成表格的函数 Table tableFunc() { Table t; // 定义一个变量 t ,其类型为“表格类型” // t 表格的初始化 t.size = 5; // 表格最大容量(元素个数) = 5 t.length = 0; // 表格当前数据个数(元素个数)= 0 t.head = (int*)calloc(t.size,sizeof(int)); // 为表格开辟内存,并把内存首地址赋值给 t.head // 注意!上面的申请内存操作可能会出现申请失败的情况,返回值为 NULL if (!NULL) { printf("申请内存失败,程序终止!\n"); exit(0); } return t; // 返回 t 表格 } int main() { Table myTab = tableFunc(); printf("%d \n", myTab.size); printf("%d \n", myTab.length); printf("%X \n", myTab.head); // 内存地址一般用 %X 十六进制展示 return 0; }
顺序表的增、删、查、改
/* 顺序表元素: 1.查(可以使用查找算法: 1.顺序查找 2.二分法查找) 2.改 3.增(增加到前面、中间、后面)------知识点补充:扩容函数:realloc(需要扩容的指针"*p",扩容后总的大小) 4.删 */
认识链表
/* 1.链表: 1.链表是通过指针,将不连续的内存连接起来,实现链式存储的 2.内存实际上是不同时机申请的,地址不一定连续,但是可以通过指针联系起来 3.链表是数据结构中线性表的一种,其中的每个元素实际上是一个“单独的结构体变量”, 所有变量都“通过”每个元素中的“指针”连接在一起。 4.以结构体为节点,将一个结构体看成“数据域”和“指针域”两个部分, “数据域”用于“存储数据”,“指针域”用于“连接下一个节点”,链表中每个结构体对象叫做节点, 其中,第一个数据节点,叫做链表的“首元结点”。 5.如果第一个节点不用于存储数据,只用于代表链表的起始点,则这个结点称为链表的“头结点”。 2.链表特点: 1.没有固定长度 2.可以快速的插入和删除链表中的节点 3.链表分很多种,单链表是其中最简单的一种(如下图) */

单链表
/* <单链表> 1.链表节点一般是自定义的结构体类型 2.结构体一般包含两部分:数据、指针 数据:当前节点里面需要的数据 指针:指向下一个节点(最后一个节点置空 为“尾节点”) */

创建单链表 [Go]

源代码如下
// main.c # include <stdio.h> # include "myList.h" int main() { Node* pList=CreateList(5); // 创建一个可以存储5个东西的链表,并将返回值“地址”赋值给变量 pList showList(pList); // 展示链表 return 0; }
// myList.c # include <stdio.h> # include "myList.h" # include <stdlib.h> // 申请内存时候要用 /* 创建链表 参 数:长度 返回值:头指针 */ Node* CreateList(int length) { // 判断长度 if (length <= 0) { printf("Length Error!\n"); return NULL; } // 开始创建链表 // 1.创建头指针和尾指针 Node *phead, *ptail; phead = ptail = NULL; // 2.申请内存:头结点 phead = (Node*)malloc(sizeof(Node)); // 3.处理异常情况 if (NULL == phead) { perror("malloc failed!"); exit(EXIT_FAILURE); } // 4.给头结点初值 phead->pnext = NULL; // 等价于 (*phead).pnext = NULL; phead->num = 0; // 5.尾指针 ptail = phead; // 6.向头结点后面添加结点 Node* p; DataType n; for (int i = 0; i < length; i++) { // 6.1 申请一个结点,检测,给值 p= (Node*)malloc(sizeof(Node)); if (NULL == p) { perror("malloc failed!"); exit(EXIT_FAILURE); } p->pnext = NULL; printf("请输入数值>>>"); scanf("%d", &n); p->num = n; // 6.2 将新申请的结点添加到链表中 ptail->pnext = p; ptail = p; // 更新尾结点 } return phead; // 9.返回头指针 } /* 遍历链表 参 数:头指针 返回值:空 */ void showList(const Node* const p) { // 从首元结点开始遍历,而不是头结点(因为我们不使用头结点去存储值) Node* temp = p->pnext; if (NULL == temp) { printf("List is NULL!\n"); return ; } printf("\n*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\n"); printf("当前链表数据:\n"); while (temp) { printf("%-5d", temp->num); temp = temp->pnext; } printf("\n*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\n"); }
// myList.h #ifndef _MYLIST_ // 防止重复定义 #define _MYLIST_ typedef int DataType; // 可以灵活改变数据类型 struct node { struct node* pnext; // 指针域 DataType num; // 数据域 }; typedef struct node Node; // 给结构体类型取别名 /* 创建链表 参 数:长度 返回值:头指针 */ Node* CreateList(int length); /* 遍历链表 参 数:头指针 返回值:空 */ void showList(const Node* const p); #endif // _MYLIST_ 定义结束
单链表的查、改、增、删
/* 单链表的查、改、增、删 1.查:确定查找方式,查找之后一般会返回“结点首地址”或者返回 NULL 2.改:找到目标元素,直接修改该元素的值 3.增:一定注意不能丢失指针指向 4.删:记得释放内存 [Go] */
浙公网安备 33010602011771号