快捷搜索:  汽车  科技

c语言单链表使用方法(C语言中链表的使用方法)

c语言单链表使用方法(C语言中链表的使用方法)#define _CRT_SECURE_NO_WARNINGS #include<stdio.h> #include<string.h> #include<stdlib.h> #include "02_linklist.h" static void test01() { //初始化链表 struct LinkNode* pHeader = init_LinkList(); //遍历链表 printf("遍历链表的结果为\n"); foreach_LinkList(pHeader); //插入数据 // 100 10 200 20 30 300 insert_LinkList(pHeader 10 100); insert_LinkList(pHeader 20 200); inser

1.链表的概念

链表也叫链式存储结构或单链表,它用于存储逻辑关系为 "一对一" 的数据。

使用链表存储的数据元素,其物理存储位置是随机的。

链表中每个数据元素在存储时都配备一个指针,用于指向自己的直接后继元素。

链表中的节点包含有:数据域和指针域

顾名思义,数据域就是存放数据的,指针域用于存放后继元素地址

c语言单链表使用方法(C语言中链表的使用方法)(1)

链表分为:静态链表和动态链表

#define _CRT_SECURE_NO_WARNINGS #include<stdio.h> #include<stdlib.h> #include<string.h> #include<time.h> //1、静态链表 //节点的声明 struct LinkNode { int num; struct LinkNode* next;//指针域 }; static void test01() { //创建节点 struct LinkNode node1 = { 10 NULL }; struct LinkNode node2 = { 20 NULL }; struct LinkNode node3 = { 30 NULL }; struct LinkNode node4 = { 40 NULL }; struct LinkNode node5 = { 50 NULL }; //建立关系 node1.next = &node2; node2.next = &node3; node3.next = &node4; node4.next = &node5; //如何遍历这个链表 struct LinkNode* pCurrent = &node1; while (pCurrent != NULL) { printf("%d\n" pCurrent->num); pCurrent = pCurrent->next; } } //2、动态链表 static void test02() { struct LinkNode* node1 = malloc(sizeof(struct LinkNode)); struct LinkNode* node2 = malloc(sizeof(struct LinkNode)); struct LinkNode* node3 = malloc(sizeof(struct LinkNode)); struct LinkNode* node4 = malloc(sizeof(struct LinkNode)); struct LinkNode* node5 = malloc(sizeof(struct LinkNode)); node1->num = 10; node2->num = 20; node3->num = 30; node4->num = 40; node5->num = 50; //建立关系 node1->next = &node2; node2->next = &node3; node3->next = &node4; node4->next = &node5; node5->next = NULL; //遍历链表 struct LinkNode* pCurrent = node1; while (pCurrent != NULL) { printf(":::%d\n" pCurrent->num); pCurrent = pCurrent->next; } //释放节点 free(node1); free(node2); free(node3); free(node4); free(node5); } int main01() { //test01(); test02(); return 0; }

2.链表的基础使用

#define _CRT_SECURE_NO_WARNINGS #include<stdio.h> #include<string.h> #include<stdlib.h> #include "02_linklist.h" static void test01() { //初始化链表 struct LinkNode* pHeader = init_LinkList(); //遍历链表 printf("遍历链表的结果为\n"); foreach_LinkList(pHeader); //插入数据 // 100 10 200 20 30 300 insert_LinkList(pHeader 10 100); insert_LinkList(pHeader 20 200); insert_LinkList(pHeader -1 300); printf("插入数据后,遍历链表的结果为\n"); foreach_LinkList(pHeader); //测试 删除 delete_LinkList(pHeader 30); delete_LinkList(pHeader 100); delete_LinkList(pHeader 1000); // 10 200 20 300 printf("删除数据后,遍历链表的结果为\n"); foreach_LinkList(pHeader); //清空链表 clear_LinkList(pHeader); printf("清空数据后,遍历链表的结果为\n"); foreach_LinkList(pHeader); insert_LinkList(pHeader 111 111); insert_LinkList(pHeader 222 222); insert_LinkList(pHeader 333 333); printf("清空后再次使用链表,遍历链表的结果为\n"); foreach_LinkList(pHeader); //销毁链表 destroy_LinkList(pHeader); pHeader = NULL; } int main02() { test01(); system("pause"); return EXIT_SUCCESS; }

#include "02_linklist.h" //初始化链表 struct LinkNode* init_LinkList() { struct LinkNode* pHeader = malloc(sizeof(struct LinkNode)); if (pHeader == NULL) { return NULL; } //pHeader->num = -1; 头节点不维护数据域 pHeader->next = NULL; //头节点初始化指针域为NULL //创建一个尾节点,利用后期添加新的数据 struct LinkNode* pTail = pHeader; int val = -1; while (1) { printf("请插入数据 -1代表输入结束:\n"); scanf("%d" &val); if (val == -1) { break; } //创建新节点 struct LinkNode* newNode = malloc(sizeof(struct LinkNode)); newNode->num = val; newNode->next = NULL; //建立关系 pTail->next = newNode; //更新新的尾节点 pTail = newNode; } return pHeader; } //遍历链表 void foreach_LinkList(struct LinkNode* pHeader) { if (pHeader == NULL) { return; } //pCurrent 起始指向的是第一个有真实数据的节点 struct LinkNode* pCurrent = pHeader->next; while (pCurrent != NULL) { printf("%d\n" pCurrent->num); pCurrent = pCurrent->next; } } //插入链表 void insert_LinkList(struct LinkNode* pHeader int oldVal int newVal) { if (pHeader == NULL) { return; } //创建两个辅助指针变量 struct LinkNode* pPrev = pHeader; struct LinkNode* pCurrent = pHeader->next; while (pCurrent != NULL) { if (pCurrent->num == oldVal) //找到插入位置 { break; } //如果没有找到位置,让辅助指针后移 pPrev = pCurrent; pCurrent = pCurrent->next; } //创建新节点 struct LinkNode* newNode = malloc(sizeof(struct LinkNode)); newNode->num = newVal; newNode->next = NULL; //建立关系 更新指针的指向 newNode->next = pCurrent; pPrev->next = newNode; } //删除链表 void delete_LinkList(struct LinkNode* pHeader int val) { if (pHeader == NULL) { return; } //创建两个辅助指针变量 struct LinkNode* pPrve = pHeader; struct LinkNode* pCurrent = pHeader->next; while (pCurrent != NULL) { if (pCurrent->num == val) { break; } pPrve = pCurrent; pCurrent = pCurrent->next; } //无效数据 就直接return if (pCurrent == NULL) { return; } //更改指针的指向 pPrve->next = pCurrent->next; //删除节点 free(pCurrent); pCurrent = NULL; } //清空链表 void clear_LinkList(struct LinkNode* pHeader) { if (pHeader == NULL) { return; } //创建临时指针 struct LinkNode* pCurrent = pHeader->next; while (pCurrent != NULL) { //先保存住待删除节点的后面的节点 struct LinkNode* nextNode = pCurrent->next; free(pCurrent); pCurrent = nextNode; } //头节点的next置空 pHeader->next = NULL; } //销毁链表 void destroy_LinkList(struct LinkNode* pHeader) { if (pHeader == NULL) { return; } //先清空链表 clear_LinkList(pHeader); //再释放头节点 free(pHeader); pHeader = NULL; }

#pragma once #define _CRT_SECURE_NO_WARNINGS #include<stdio.h> #include<string.h> #include<stdlib.h> //节点声明 struct LinkNode { int num; struct LinkNode* next; }; //初始化链表 struct LinkNode* init_LinkList(); //遍历链表 void foreach_LinkList(struct LinkNode* pHeader); //插入链表 void insert_LinkList(struct LinkNode* pHeader int oldVal int newVal); //删除链表 void delete_LinkList(struct LinkNode* pHeader int val); //清空链表 void clear_LinkList(struct LinkNode* pHeader); //销毁链表 void destroy_LinkList(struct LinkNode* pHeader);

3.函数指针的定义

#define _CRT_SECURE_NO_WARNINGS #include<stdio.h> #include<stdlib.h> #include<string.h> #include<time.h> static void func() { printf("hello world\n"); } //函数指针的定义方式 static void test01() { //先定义出函数类型,再通过类型定义出函数指针 typedef void(FUNC_TYPE)(); FUNC_TYPE* pFunc = func; pFunc(); } static void test02() { //先定义出函数指针类型,再定义函数指针 typedef void(*FUNC_TYPE)(); FUNC_TYPE pFunc = func; pFunc(); } static void test03()//通常使用第三种 { //直接定义函数指针变量 void(*pFunc)() = func;//void 是func的返回值 (*pFunc)是函数名称 ()是函数参数列表 pFunc(); } //函数指针的数组 static void func1() { printf("func1的调用\n"); } static void func2() { printf("func2的调用\n"); } static void func3() { printf("func3的调用\n"); } static void test04() { //函数指针数组的定义 void(*pFunc[3])(); pFunc[0] = func1; pFunc[1] = func2; pFunc[2] = func3; for (int i = 0; i < 3; i ) { pFunc[i](); } } //函数指针 和 指针函数 的区别 //函数指针 是指向函数的指针 //指针函数 是函数的返回值是一个指针的函数 int main03() { //test01(); //test02(); test03(); return 0; }

4.函数指针作为函数参数

#define _CRT_SECURE_NO_WARNINGS #include<stdio.h> #include<string.h> #include<stdlib.h> //提供一个函数,可以将任意的数据类型 打印出来 static void printText(void* a void(*myPrint)(void*)) { myPrint(a); } static void myPrintInt(void* data) { int* num = data; printf("%d\n" *num); } static void test01() { int a = 100; printText(&a myPrintInt); } struct Person { char name[64]; int age; }; static void myPrintPerson(void* data) { struct Person* p = data; printf("姓名: %s 年龄: %d\n" p->name p->age); } static void test02() { struct Person p = { "aaa" 10 }; printText(&p myPrintPerson); } int main04() { //test01(); test02(); system("pause"); return EXIT_SUCCESS; }

5.回调函数

#define _CRT_SECURE_NO_WARNINGS #include<stdio.h> #include<string.h> #include<stdlib.h> //1、提供一个函数,可以打印任意类型的数组 static void printAllArray(void* arr int eleSize int len void(*myFunc)(void*)) { char* p = arr; for (int i = 0; i < len; i ) { char* eleAddr = p i * eleSize; //计算每个元素首地址 //printf("%d\n" *(int*)eleAddr); myFunc(eleAddr); } } static void myPrintInt(void* data) { int* num = data; printf("%d\n" *num); } static void test01() { int arr[6] = { 1 2 3 4 5 6 }; int len = sizeof(arr) / sizeof(int); printAllArray(arr sizeof(int) len myPrintInt); } struct Person { char name[64]; int age; }; static void myPrintPerson(void* data) { struct Person* p = data; printf("姓名: %s 年龄: %d\n" p->name p->age); } static void test02() { struct Person pArray[] = { { "aaa" 10 } { "bbb" 20 } { "ccc" 30 } { "ddd" 40 } }; int len = sizeof(pArray) / sizeof(struct Person); printAllArray(pArray sizeof(struct Person) len myPrintPerson); } // 参数1 数组首地址 参数2 每个元素占的内存空间 参数3 元素个数 参数4 查找的元素的地址 参数5 回调函数 int myFindPerson(void* arr int eleSize int len void* data int (*myCompare)(void* void*)) { char* p = arr; for (int i = 0; i < len; i ) { char* eleAddr = p i * eleSize; //获取每个元素的首地址 //if ( eleAddr 和 data 的元素 相等 ) if (myCompare(eleAddr data)) { return 1; } } return 0; } int myComparePerson(void* data1 void* data2) { struct Person* p1 = data1; struct Person* p2 = data2; if (strcmp(p1->name p2->name) == 0 && p1->age == p2->age) { return 1; } return 0; } static void test03() { struct Person pArray[] = { { "aaa" 10 } { "bbb" 20 } { "ccc" 30 } { "ddd" 40 } }; struct Person p = { "ccc" 30 }; int len = sizeof(pArray) / sizeof(struct Person); //查找数组中的元素,如果查找到返回1 ,找不到返回0 int ret = myFindPerson(pArray sizeof(struct Person) len &p myComparePerson); if (ret) { printf("找到了元素\n"); } else { printf("未找到元素\n"); } } int main() { //test01(); //test02(); test03(); system("pause"); return EXIT_SUCCESS; }

猜您喜欢: