c语言提高学习笔记——03-c提高08day_数据结构
在学习c语言提高-数据结构总结了笔记,并分享出来。有问题请及时联系博主:Alliswell_WP,转载请注明出处。
03-c提高08day_数据结构
目录:
1、数据结构理论
(1)数据结构概念
(2)算法的概念
2、线性表
(1)线性表基本概念
(2)线性表的顺序存储
练习1:
动态数组(+初始化、+插入、+遍历)
动态数组(+删除、+销毁)
动态数组(分文件实现)
练习2:
单向链表(版本一)——(+初始化、+插入、+遍历)
单向链表(版本一)——(+值删除、+位置删除、+大小、+清空、+销毁)
练习3:
单向链表(版本二)
1、数据结构理论
(1)数据结构概念
数据结构是计算机存储、组织数据的方式。数据结构是指相互之间存在一种或多种特定关系的数据元素的集合,通常情况下,精心选择的数据结构可以带来更高的运行或者存储效率。数据结构往往同高效的检索算法和索引技术有关。
数据结构是计算机存储、组织数据的方式。
(2)算法的概念
算法是特定问题求解步骤的描述,在计算机中表现为指令的有限序列,算法是独立存在的一种解决问题的方法和思想。
对于算法而言,语言并不重要,重要的是思想。
2、线性表
(1)线性表基本概念
线性结构是一种最简单且常用的数据结构。线性结构的基本特点是节点之间满足线性关系。本章讨论的动态数组、链表、栈、队列都屈于线性结构。他们的共同之处,是节点中有且只有一个开始节点和终端节点。按这种关系,可以把它们的所有节点排列成一个线性序列。但是,他们分别屈于几种不同的抽象数据类型实现,它们之间的区别,主要就是操作的不同。
线性表是零个或者多个数据元素的有限序列,数据元素之问是有顺序的,数据元素个数是有限的,数据元素的类型必须相同。
(2)线性表的顺序存储
通常线性表可以采用顺序存储和链式存储。这节课我们主要探讨顺序存储结构以及对应的运算算法的实现。
采用顺序存储是表示线性表最简单的方法,具体做法是:将线性表中的元素一个接一个的存储在一块连续的存储区域中,这种顺序表示的线性表也称为顺序表。
练习1:
动态数组(+初始化、+插入、+遍历)
1 #define _CRT_SECURE_NO_WARNINGS 2 #include<stdio.h> 3 #include<string.h> 4 #include<stdlib.h> 5 6 //1.先把所需要的数据信息结构定义下来 7 struct DynamicArray 8 { 9 //数组存储元素的空间的首地址 10 void** addr; 11 //存储数据的内存中最大能够容纳多少元素 12 int capacity;//容量 13 //当前存储数据的内存中有多少个元素 14 int size;//大小 15 }; 16 17 //初始化数组 18 struct DynamicArray* Init_DynamicArray(int capacity) 19 { 20 if(capacity <= 0) 21 { 22 return NULL; 23 } 24 struct DynamicArray* arr = malloc(sizeof(struct DynamicArray)); 25 if(NULL == arr) 26 { 27 return NULL; 28 } 29 arr->capacity = capacity; 30 arr->addr = malloc(sizeof(void*) * arr->capacity); 31 arr->size = 0; 32 33 return arr; 34 } 35 //插入元素 36 void Insert_DynamicArray(struct DynamicArray* arr, int pos, void* data) 37 { 38 if(NULL == arr) 39 { 40 return; 41 } 42 if(NULL == data) 43 { 44 return; 45 } 46 if(pos < 0 || pos > arr->size)//检查插入位置的合法性 47 { 48 pos = arr->size; 49 } 50 if(arr->size >= arr->capacity) 51 { 52 //1.申请一块更大的内存空间 53 int newcapacity = arr->capacity * 2; 54 void** newspace = malloc(sizeof(void*) * newcapacity); 55 56 //2.将原来空间的数据拷贝到新空间 57 memcpy(newspace, arr->addr, sizeof(void*) * arr->capacity); 58 59 //3.释放原来空间的内存 60 free(arr->addr); 61 62 //4.更新addr指向 63 arr->addr = newspace; 64 arr->capacity = newcapacity; 65 } 66 67 //移动元素,给pos位置空出位置来 68 for(int i = arr->size - 1; i >= pos; --i) 69 { 70 arr->addr[i + 1] = addr->addr[i]; 71 } 72 73 //将新元素插入到pos位置 74 arr->addr[pos] = data; 75 arr->size++; 76 } 77 //遍历 78 void Foreach_DynamicArray(struct DynamicArray* arr, void(*_callback)(void*)) 79 { 80 if(NULL == arr) 81 { 82 return; 83 } 84 if(NULL == _callback) 85 { 86 return; 87 } 88 for(int i = 0; i < arr->size; ++i) 89 { 90 _callback(arr->addr[i]); 91 } 92 } 93 94 //初始化数组 95 struct DynamicArray* Init_DynamicArray(int capacity); 96 //插入元素 97 void Insert_DynamicArray(struct DynamicArray* arr, int pos, void* data); 98 //遍历 99 void Foreach_DynamicArray(struct DynamicArray* arr, void(*_callback)(void*)); 100 101 102 struct Person 103 { 104 char name[64]; 105 int age; 106 }; 107 108 void myPrint(void* data) 109 { 110 struct Person* person = (struct Person*)data; 111 printf("Name:%s Age:%d\n", person->name, person->age); 112 } 113 114 void test() 115 { 116 //创建动态数组 117 struct DynamicArray* da = Init_DynamicArray(5); 118 //动态数组添加元素 119 struct Person p1 = {"aaa", 10}; 120 struct Person p2 = {"bbb", 20}; 121 struct Person p3 = {"ccc", 30}; 122 struct Person p4 = {"ddd", 40}; 123 struct Person p5 = {"eee", 50}; 124 struct Person p6 = {"fff", 60}; 125 126 Insert_DynamicArray(da, 100, &p1); 127 Insert_DynamicArray(da, 100, &p2); 128 Insert_DynamicArray(da, 100, &p3); 129 Insert_DynamicArray(da, 100, &p4); 130 Insert_DynamicArray(da, 100, &p5); 131 132 printf("capacity:%d\n", da->capacity);//打印容量 133 Insert_DynamicArray(da, 100, &p6);//超出空间容量,扩大一倍 134 printf("capacity:%d\n", da->capacity);//打印容量 135 136 Foreach_DynamicArray(data, myPrint); 137 } 138 139 int main(){ 140 141 test(); 142 143 system("pause"); 144 return EXIT_SUCCESS; 145 }
动态数组(+删除、+销毁)
1 #define _CRT_SECURE_NO_WARNINGS 2 #include<stdio.h> 3 #include<string.h> 4 #include<stdlib.h> 5 6 1.先把所需要的数据信息结构定义下来 7 struct DynamicArray 8 { 9 //数组存储元素的空间的首地址 10 void** addr; 11 //存储数据的内存中最大能够容纳多少元素 12 int capacity;//容量 13 //当前存储数据的内存中有多少个元素 14 int size;//大小 15 }; 16 17 //初始化数组 18 struct DynamicArray* Init_DynamicArray(int capacity) 19 { 20 if(capacity <= 0) 21 { 22 return NULL; 23 } 24 struct DynamicArray* arr = malloc(sizeof(struct DynamicArray)); 25 if(NULL == arr) 26 { 27 return NULL; 28 } 29 arr->capacity = capacity; 30 arr->addr = malloc(sizeof(void*) * arr->capacity); 31 arr->size = 0; 32 33 return arr; 34 } 35 //插入元素 36 void Insert_DynamicArray(struct DynamicArray* arr, int pos, void* data) 37 { 38 if(NULL == arr) 39 { 40 return; 41 } 42 if(NULL == data) 43 { 44 return; 45 } 46 if(pos < 0 || pos > arr->size)//检查插入位置的合法性 47 { 48 pos = arr->size; 49 } 50 51 //判断空间是否足够 52 if(arr->size >= arr->capacity) 53 { 54 //1.申请一块更大的内存空间 55 int newcapacity = arr->capacity * 2; 56 void** newspace = malloc(sizeof(void*) * newcapacity); 57 58 //2.将原来空间的数据拷贝到新空间 59 memcpy(newspace, arr->addr, sizeof(void*) * arr->capacity); 60 61 //3.释放原来空间的内存 62 free(arr->addr); 63 64 //4.更新addr指向 65 arr->addr = newspace; 66 arr->capacity = newcapacity; 67 } 68 69 //移动元素,给pos位置空出位置来 70 for(int i = arr->size - 1; i >= pos; --i) 71 { 72 arr->addr[i + 1] = addr->addr[i]; 73 } 74 75 //将新元素插入到pos位置 76 arr->addr[pos] = data; 77 arr->size++; 78 } 79 //遍历 80 void Foreach_DynamicArray(struct DynamicArray* arr, void(*_callback)(void*)) 81 { 82 if(NULL == arr) 83 { 84 return; 85 } 86 if(NULL == _callback) 87 { 88 return; 89 } 90 for(int i = 0; i < arr->size; ++i) 91 { 92 _callback(arr->addr[i]); 93 } 94 } 95 96 //位置删除 97 void RemoveByPos_DynamicArray(struct DynamicArray* arr, int pos) 98 { 99 if(NULL == arr) 100 { 101 return; 102 } 103 if(pos < 0 || pos > arr->size - 1) 104 { 105 return; 106 } 107 108 for(int i = pos; i < arr->size -1; ++i) 109 { 110 arr->addr[i] = arr->addr[i + 1]; 111 } 112 arr->size--; 113 } 114 115 //按值删除 116 void RemoveByValue(struct DynamicArray* arr, void* data, int(*compare)(void*, void*)) 117 { 118 if(NULL == arr) 119 { 120 return; 121 } 122 if(NULL == data) 123 { 124 return; 125 } 126 if(NULL == compare) 127 { 128 return; 129 } 130 131 for(int i = 0; i < arr->size; ++i) 132 { 133 if(compare(arr->addr[i], data)) 134 { 135 RemoveByPos_DynamicArray(arr, i); 136 break; 137 } 138 } 139 140 } 141 142 //销毁数组 143 void Destroy_DynamicArray(struct DynamicArray* arr) 144 { 145 if(NULL == arr) 146 { 147 return; 148 } 149 if(arr->addr != NULL) 150 { 151 free(arr->addr); 152 arr->addr = NULL; 153 } 154 free(arr); 155 arr = NULL; 156 } 157 158 //初始化数组 159 struct DynamicArray* Init_DynamicArray(int capacity); 160 //插入元素 161 void Insert_DynamicArray(struct DynamicArray* arr, int pos, void* data); 162 //遍历 163 void Foreach_DynamicArray(struct DynamicArray* arr, void(*_callback)(void*)); 164 165 166 struct Person 167 { 168 char name[64]; 169 int age; 170 }; 171 172 void myPrint(void* data) 173 { 174 struct Person* person = (struct Person*)data; 175 printf("Name:%s Age:%d\n", person->name, person->age); 176 } 177 178 int myCompare(void* d1, void* d2) 179 { 180 struct person* p1 = (struct Person*)d1; 181 struct person* p2 = (struct Person*)d2; 182 183 return strcmp(p1->name, p2->name) == 0 && p1->age == p2->age; 184 } 185 186 187 void test() 188 { 189 //创建动态数组 190 struct DynamicArray* da = Init_DynamicArray(5); 191 //动态数组添加元素 192 struct Person p1 = {"aaa", 10}; 193 struct Person p2 = {"bbb", 20}; 194 struct Person p3 = {"ccc", 30}; 195 struct Person p4 = {"ddd", 40}; 196 struct Person p5 = {"eee", 50}; 197 struct Person p6 = {"fff", 60}; 198 199 Insert_DynamicArray(da, 0, &p1); 200 Insert_DynamicArray(da, 0, &p2); 201 Insert_DynamicArray(da, 0, &p3); 202 Insert_DynamicArray(da, 1, &p4); 203 Insert_DynamicArray(da, 1, &p5); 204 205 printf("capacity:%d\n", da->capacity);//打印容量 206 Insert_DynamicArray(da, 100, &p6);//超出空间容量,扩大一倍3 5 4 2 1 6 207 printf("capacity:%d\n", da->capacity);//打印容量 208 209 Foreach_DynamicArray(data, myPrint); 210 211 printf("-----------------\n"); 212 RemoveByPos_DynamicArray(data, 2);//3 5 2 1 6 213 Foreach_DynamicArray(data, myPrint); 214 215 printf("-----------------\n"); 216 struct Person pDel = {"aaa", 10}; 217 RemoveByValue(da, &pDel, myCompare); 218 Foreach_DynamicArray(data, myPrint); 219 220 //销毁 221 Destroy_DynamicArray(da); 222 } 223 224 int main(){ 225 226 test(); 227 228 system("pause"); 229 return EXIT_SUCCESS; 230 }
动态数组(分文件实现)
动态数组.c
1 #define _CRT_SECURE_NO_WARNINGS 2 #include<stdio.h> 3 #include<string.h> 4 #include<stdlib.h> 5 #inlcude"DynamicArray.h" 6 7 8 struct Person 9 { 10 char name[64]; 11 int age; 12 }; 13 14 void myPrint(void* data) 15 { 16 struct Person* person = (struct Person*)data; 17 printf("Name:%s Age:%d\n", person->name, person->age); 18 } 19 20 int myCompare(void* d1, void* d2) 21 { 22 struct person* p1 = (struct Person*)d1; 23 struct person* p2 = (struct Person*)d2; 24 25 return strcmp(p1->name, p2->name) == 0 && p1->age == p2->age; 26 } 27 28 29 void test() 30 { 31 //创建动态数组 32 struct DynamicArray* da = Init_DynamicArray(5); 33 //动态数组添加元素 34 struct Person p1 = {"aaa", 10}; 35 struct Person p2 = {"bbb", 20}; 36 struct Person p3 = {"ccc", 30}; 37 struct Person p4 = {"ddd", 40}; 38 struct Person p5 = {"eee", 50}; 39 struct Person p6 = {"fff", 60}; 40 41 Insert_DynamicArray(da, 0, &p1); 42 Insert_DynamicArray(da, 0, &p2); 43 Insert_DynamicArray(da, 0, &p3); 44 Insert_DynamicArray(da, 1, &p4); 45 Insert_DynamicArray(da, 1, &p5); 46 47 printf("capacity:%d\n", da->capacity);//打印容量 48 Insert_DynamicArray(da, 100, &p6);//超出空间容量,扩大一倍3 5 4 2 1 6 49 printf("capacity:%d\n", da->capacity);//打印容量 50 51 Foreach_DynamicArray(data, myPrint); 52 53 printf("-----------------\n"); 54 RemoveByPos_DynamicArray(data, 2);//3 5 2 1 6 55 Foreach_DynamicArray(data, myPrint); 56 57 printf("-----------------\n"); 58 struct Person pDel = {"aaa", 10}; 59 RemoveByValue(da, &pDel, myCompare); 60 Foreach_DynamicArray(data, myPrint); 61 62 //销毁 63 Destroy_DynamicArray(da); 64 } 65 66 int main(){ 67 68 test(); 69 70 system("pause"); 71 return EXIT_SUCCESS; 72 }
DynamicArray.h
1 #pragma once 2 3 #include<stdlib.h> 4 #include<stdio.h> 5 #include<string.h> 6 7 #ifdef __cplusplus 8 extern "C"{ 9 10 1.先把所需要的数据信息结构定义下来 11 struct DynamicArray 12 { 13 //数组存储元素的空间的首地址 14 void** addr; 15 //存储数据的内存中最大能够容纳多少元素 16 int capacity;//容量 17 //当前存储数据的内存中有多少个元素 18 int size;//大小 19 }; 20 21 //初始化数组 22 struct DynamicArray* Init_DynamicArray(int capacity); 23 //插入元素 24 void Insert_DynamicArray(struct DynamicArray* arr, int pos, void* data); 25 //遍历 26 void Foreach_DynamicArray(struct DynamicArray* arr, void(*_callback)(void*)); 27 //位置删除 28 void RemoveByPos_DynamicArray(struct DynamicArray* arr, int pos); 29 //按值删除 30 void RemoveByValue(struct DynamicArray* arr, void* data, int(*compare)(void*, void*)); 31 //销毁数组 32 void Destroy_DynamicArray(struct DynamicArray* arr); 33 34 #ifdef __cplusplus 35 } 36 #endif
DynamicArray.c
1 #inlcude"DynamicArray.h" 2 3 1.先把所需要的数据信息结构定义下来 4 struct DynamicArray 5 { 6 //数组存储元素的空间的首地址 7 void** addr; 8 //存储数据的内存中最大能够容纳多少元素 9 int capacity;//容量 10 //当前存储数据的内存中有多少个元素 11 int size;//大小 12 }; 13 14 //初始化数组 15 struct DynamicArray* Init_DynamicArray(int capacity) 16 { 17 if(capacity <= 0) 18 { 19 return NULL; 20 } 21 struct DynamicArray* arr = malloc(sizeof(struct DynamicArray)); 22 if(NULL == arr) 23 { 24 return NULL; 25 } 26 arr->capacity = capacity; 27 arr->addr = malloc(sizeof(void*) * arr->capacity); 28 arr->size = 0; 29 30 return arr; 31 } 32 //插入元素 33 void Insert_DynamicArray(struct DynamicArray* arr, int pos, void* data) 34 { 35 if(NULL == arr) 36 { 37 return; 38 } 39 if(NULL == data) 40 { 41 return; 42 } 43 if(pos < 0 || pos > arr->size)//检查插入位置的合法性 44 { 45 pos = arr->size; 46 } 47 48 //判断空间是否足够 49 if(arr->size >= arr->capacity) 50 { 51 //1.申请一块更大的内存空间 52 int newcapacity = arr->capacity * 2; 53 void** newspace = malloc(sizeof(void*) * newcapacity); 54 55 //2.将原来空间的数据拷贝到新空间 56 memcpy(newspace, arr->addr, sizeof(void*) * arr->capacity); 57 58 //3.释放原来空间的内存 59 free(arr->addr); 60 61 //4.更新addr指向 62 arr->addr = newspace; 63 arr->capacity = newcapacity; 64 } 65 66 //移动元素,给pos位置空出位置来 67 for(int i = arr->size - 1; i >= pos; --i) 68 { 69 arr->addr[i + 1] = addr->addr[i]; 70 } 71 72 //将新元素插入到pos位置 73 arr->addr[pos] = data; 74 arr->size++; 75 } 76 //遍历 77 void Foreach_DynamicArray(struct DynamicArray* arr, void(*_callback)(void*)) 78 { 79 if(NULL == arr) 80 { 81 return; 82 } 83 if(NULL == _callback) 84 { 85 return; 86 } 87 for(int i = 0; i < arr->size; ++i) 88 { 89 _callback(arr->addr[i]); 90 } 91 } 92 93 //位置删除 94 void RemoveByPos_DynamicArray(struct DynamicArray* arr, int pos) 95 { 96 if(NULL == arr) 97 { 98 return; 99 } 100 if(pos < 0 || pos > arr->size - 1) 101 { 102 return; 103 } 104 105 for(int i = pos; i < arr->size -1; ++i) 106 { 107 arr->addr[i] = arr->addr[i + 1]; 108 } 109 arr->size--; 110 } 111 112 //按值删除 113 void RemoveByValue(struct DynamicArray* arr, void* data, int(*compare)(void*, void*)) 114 { 115 if(NULL == arr) 116 { 117 return; 118 } 119 if(NULL == data) 120 { 121 return; 122 } 123 if(NULL == compare) 124 { 125 return; 126 } 127 128 for(int i = 0; i < arr->size; ++i) 129 { 130 if(compare(arr->addr[i], data)) 131 { 132 RemoveByPos_DynamicArray(arr, i); 133 break; 134 } 135 } 136 137 } 138 139 //销毁数组 140 void Destroy_DynamicArray(struct DynamicArray* arr) 141 { 142 if(NULL == arr) 143 { 144 return; 145 } 146 if(arr->addr != NULL) 147 { 148 free(arr->addr); 149 arr->addr = NULL; 150 } 151 free(arr); 152 arr = NULL; 153 }
练习2:单向链表(版本一)——(+初始化、+插入、+遍历)
内存模型图如下:
单向链表(版本一).c
1 #define _CRT_SECURE_NO_WARNINGS 2 #include<stdio.h> 3 #include<string.h> 4 #include<stdlib.h> 5 #include"LinkList.h" 6 7 struct Person 8 { 9 char name[64]; 10 int age; 11 }; 12 13 void myPrint(void* data) 14 { 15 struct Person* person = (struct Person*)data; 16 printf("Name:%s Age:%d\n", person->name, person->age); 17 } 18 19 void test() 20 { 21 //创建链表 22 LinkList list = Init_LinkList(); 23 24 //创建数据 25 struct Person p1 = {"aaa", 10}; 26 struct Person p2 = {"bbb", 20}; 27 struct Person p3 = {"ccc", 30}; 28 struct Person p4 = {"ddd", 40}; 29 struct Person p5 = {"eee", 50}; 30 struct Person p6 = {"fff", 60}; 31 struct Person p7 = {"ggg", 70}; 32 33 //插入数据 34 Insert_LinkList(list, 0, &p1);//1 35 Insert_LinkList(list, 0, &p2);//2 1 36 Insert_LinkList(list, 1, &p3);//2 3 1 37 Insert_LinkList(list, 2, &p4);//2 3 4 1 38 Insert_LinkList(list, 20, &p5);//2 3 4 1 5 39 Insert_LinkList(list, 3, &p6);//2 3 4 6 1 5 40 Insert_LinkList(list, 6, &p7);//2 3 4 6 1 5 7 41 42 Foreach_LinkList(list, myPrint); 43 } 44 45 int main(){ 46 47 test(); 48 49 system("pause"); 50 return EXIT_SUCCESS; 51 }
LinkList.h
1 #pragma once 2 3 #include<stdlib.h> 4 #include<string.h> 5 #include<stdio.h> 6 7 #ifdef __cpluscplus 8 extern "C"{ 9 #endif 10 11 12 13 typedef void* LinkList; 14 typedef void(*FOREACH)(void*); 15 16 //初始化链表 17 LinkList Init_LinkList(); 18 //插入结点 19 void Insert_LinkList(LinkList list, int pos, void* data); 20 //遍历链表 21 void Foreach_LinkList(LinkList list, FOREACH myforeach); 22 23 24 #ifdef __cpluscplus 25 } 26 #endif
LinkList.c
1 #include"LinkList.h" 2 3 //链表结点数据类型 4 struct LinkNode 5 { 6 void* data; 7 struct LinkNode* next; 8 }; 9 10 //链表数据类型 11 struct LList 12 { 13 struct LinkNode header; 14 int size; 15 }; 16 17 //初始化链表 18 LinkList Init_LinkList() 19 { 20 struct LList* list = malloc(sizeof(struct LList)); 21 if(NULL == list) 22 { 23 return NULL; 24 } 25 list->header.data = NULL; 26 list->header.next = NULL; 27 list->size = 0; 28 29 return list; 30 } 31 //插入结点 32 void Insert_LinkList(LinkList list, int pos, void* data) 33 { 34 if(NULL == list) 35 { 36 return; 37 } 38 if(NULL == data) 39 { 40 return; 41 } 42 43 struct LList* mylist = (struct LList*)list; 44 45 if(pos < 0 || pos > mylist->size) 46 { 47 pos = mylist->size; 48 } 49 50 //查找插入位置 51 struct LinkNode* pCurrent = &(mylist->header); 52 for(int i = 0; i < pos; ++i) 53 { 54 pCurrent = pCurrent->next; 55 } 56 57 //创建新结点 58 struct LinkNode* newnode = malloc(sizeof(struct LinkNode)); 59 newnode->data = data; 60 newnode->next = NULL; 61 62 //新结点插入到链表中 63 newnode->next = pCurrent->next; 64 pCurrent->next = newnode; 65 66 mylist->size++; 67 } 68 //遍历链表 69 void Foreach_LinkList(LinkList list, FOREACH myforeach)//回调函数 70 { 71 if(NULL == list) 72 { 73 return; 74 } 75 if(NULL == myforeach) 76 { 77 return; 78 } 79 80 struct LList* mylist = (struct LList*)list; 81 82 struct LinkNode* pCurrent = mylist->header.next; 83 84 while(pCurrent != NULL) 85 { 86 myforeach(pCurrent->data); 87 pCurrent = pCurrent->next; 88 } 89 90 }
单向链表(版本一)——(+值删除、+位置删除、+大小、+清空、+销毁)
单向链表(版本一).c
1 #define _CRT_SECURE_NO_WARNINGS 2 #include<stdio.h> 3 #include<string.h> 4 #include<stdlib.h> 5 #include"LinkList.h" 6 7 struct Person 8 { 9 char name[64]; 10 int age; 11 }; 12 13 void myPrint(void* data) 14 { 15 struct Person* person = (struct Person*)data; 16 printf("Name:%s Age:%d\n", person->name, person->age); 17 } 18 19 int myCompare(void* d1, void* d2) 20 { 21 struct Person* p1 = (struct Person*)d1; 22 struct Person* p2 = (struct Person*)d2; 23 24 #if 0 25 if(strcmp(p1->name, p2->name) == 0 && p1->age == p2->age) 26 { 27 return 1; 28 } 29 return 0; 30 #endif 31 return strcmp(p1->name, p2->name) == 0 && p1->age == p2->age; 32 } 33 34 void test() 35 { 36 //创建链表 37 LinkList list = Init_LinkList(); 38 39 //创建数据 40 struct Person p1 = {"aaa", 10}; 41 struct Person p2 = {"bbb", 20}; 42 struct Person p3 = {"ccc", 30}; 43 struct Person p4 = {"ddd", 40}; 44 struct Person p5 = {"eee", 50}; 45 struct Person p6 = {"fff", 60}; 46 struct Person p7 = {"ggg", 70}; 47 48 //插入数据 49 Insert_LinkList(list, 0, &p1);//1 50 Insert_LinkList(list, 0, &p2);//2 1 51 Insert_LinkList(list, 1, &p3);//2 3 1 52 Insert_LinkList(list, 2, &p4);//2 3 4 1 53 Insert_LinkList(list, 20, &p5);//2 3 4 1 5 54 Insert_LinkList(list, 3, &p6);//2 3 4 6 1 5 55 Insert_LinkList(list, 6, &p7);//2 3 4 6 1 5 7 56 57 Foreach_LinkList(list, myPrint); 58 59 printf("----------\n"); 60 printf("List Size:%d\n", Size_LinkList(list)); 61 RemoveByPos_LinkList(list, 3);//2 3 4 1 5 7 62 printf("----------\n"); 63 Foreach_LinkList(list, myPrint); 64 65 struct Person pDelPerson = {"ggg", 70};//2 3 4 1 5 66 RemoveByVal_LinkList(list, &pDelPerson, myCompare); 67 printf("----------\n"); 68 Foreach_LinkList(list, myPrint); 69 70 //清空链表 71 Clear_LinkList(list); 72 printf("----------\n"); 73 Foreach_LinkList(list, myPrint); 74 75 //销毁链表 76 Destroy_LinkList(list); 77 } 78 79 int main(){ 80 81 test(); 82 83 system("pause"); 84 return EXIT_SUCCESS; 85 }
LinkList.h
1 #pragma once 2 3 #include<stdlib.h> 4 #include<string.h> 5 #include<stdio.h> 6 7 #ifdef __cpluscplus 8 extern "C"{ 9 #endif 10 11 12 13 typedef void* LinkList; 14 typedef void(*FOREACH)(void*); 15 typedef int*(*COMPARE)(void*, void*); 16 17 //初始化链表 18 LinkList Init_LinkList(); 19 //插入结点 20 void Insert_LinkList(LinkList list, int pos, void* data); 21 //遍历链表 22 void Foreach_LinkList(LinkList list, FOREACH myforeach); 23 //按位置删除 24 void RemoveByPos_LinkList(LinkList list, int pos); 25 //按值删除 26 void RemoveByVal_LinkList(LinkList list, void* data, COMPARE compare); 27 //清空链表 28 void Clear_LinkList(LinkList list); 29 //大小 30 int Size_LinkList(LinkList list); 31 //销毁链表 32 void Destroy_LinkList(LinkList list); 33 34 #ifdef __cpluscplus 35 } 36 #endif
LinkList.c
1 #include"LinkList.h" 2 3 //链表结点数据类型 4 struct LinkNode 5 { 6 void* data; 7 struct LinkNode* next; 8 }; 9 10 //链表数据类型 11 struct LList 12 { 13 struct LinkNode header; 14 int size; 15 }; 16 17 //初始化链表 18 LinkList Init_LinkList() 19 { 20 struct LList* list = malloc(sizeof(struct LList)); 21 if(NULL == list) 22 { 23 return NULL; 24 } 25 list->header.data = NULL; 26 list->header.next = NULL; 27 list->size = 0; 28 29 return list; 30 } 31 //插入结点 32 void Insert_LinkList(LinkList list, int pos, void* data) 33 { 34 if(NULL == list) 35 { 36 return; 37 } 38 if(NULL == data) 39 { 40 return; 41 } 42 43 struct LList* mylist = (struct LList*)list; 44 45 if(pos < 0 || pos > mylist->size) 46 { 47 pos = mylist->size; 48 } 49 50 //查找插入位置 51 struct LinkNode* pCurrent = &(mylist->header); 52 for(int i = 0; i < pos; ++i) 53 { 54 pCurrent = pCurrent->next; 55 } 56 57 //创建新结点 58 struct LinkNode* newnode = malloc(sizeof(struct LinkNode)); 59 newnode->data = data; 60 newnode->next = NULL; 61 62 //新结点插入到链表中 63 newnode->next = pCurrent->next; 64 pCurrent->next = newnode; 65 66 mylist->size++; 67 } 68 //遍历链表 69 void Foreach_LinkList(LinkList list, FOREACH myforeach)//回调函数 70 { 71 if(NULL == list) 72 { 73 return; 74 } 75 if(NULL == myforeach) 76 { 77 return; 78 } 79 80 struct LList* mylist = (struct LList*)list; 81 82 struct LinkNode* pCurrent = mylist->header.next; 83 84 while(pCurrent != NULL) 85 { 86 myforeach(pCurrent->data); 87 pCurrent = pCurrent->next; 88 } 89 90 } 91 92 //按位置删除 93 void RemoveByPos_LinkList(LinkList list, int pos) 94 { 95 if(NULL == list) 96 { 97 return; 98 } 99 struct LList* mylist = (struct LList*)list; 100 101 if(pos < 0 || pos > mylist->size - 1) 102 { 103 return; 104 } 105 //找位置 106 struct LinkNode* pCurrent = &(mylist->header); 107 for(int i = 0; i < pos; ++i) 108 { 109 pCurrent = pCurrent->next; 110 } 111 112 //先保存待删除结点 113 struct LinkNode* pDel = pCurrent->next; 114 //重新建立待删除结点的前驱和后继结点关系 115 pCurrent->next = pDel->next; 116 //释放删除结点内存 117 free(pDel); 118 pDel = NULL; 119 120 mylist->size--; 121 } 122 //按值删除 123 void RemoveByVal_LinkList(LinkList list, void* data, COMPARE compare) 124 { 125 if(NULL == list) 126 { 127 return; 128 } 129 if(NULL == data) 130 { 131 return; 132 } 133 if(NULL == compare) 134 { 135 return; 136 } 137 138 struct LList* mylist = (struct LList*)list; 139 //辅助指针变量 140 struct LinkNode* pPrev = &(mylist->header); 141 struct LinkNode* pCurrent = pPrev->next; 142 while(pCurrent != NULL) 143 { 144 if(compare(pCurrent->data, data)) 145 { 146 //找到了 147 pPrev->next = pCurrent->next; 148 //释放删除结点内存 149 free(pCurrent); 150 pCurrent = NULL; 151 mylist->size--; 152 break; 153 } 154 155 pPrev = pCurrent; 156 pCurrent = pCurrent->next; 157 } 158 } 159 //清空链表 160 void Clear_LinkList(LinkList list) 161 { 162 if(NULL == list) 163 { 164 return; 165 } 166 struct LList* mylist = (struct LList*)list; 167 168 //辅助指针变量 169 struct LinkNode* pCurrent = mylist->header.next; 170 171 while(pCurrent != NULL) 172 { 173 //先缓存下一个结点的地址 174 struct LinkNode* pNext = pCurrent->next; 175 //释放当前结点内存 176 free(pCurrent); 177 178 pCurrent = pNext; 179 } 180 mylist->header.next = NULL; 181 //把size更新 182 mylist->size = 0; 183 184 } 185 //大小 186 int Size_LinkList(LinkList list) 187 { 188 if(NULL == list) 189 { 190 return -1; 191 } 192 struct LList* mylist = (struct LList*)list; 193 194 return mylist->size; 195 } 196 //销毁链表 197 void Destroy_LinkList(LinkList list) 198 { 199 if(NULL == list) 200 { 201 return; 202 } 203 204 //清空链表 205 Clear_LinkList(list); 206 free(list); 207 list = NULL; 208 }
练习3:单向链表(版本二)
内存模型图如下:
1 #define _CRT_SECURE_NO_WARNINGS 2 #include<stdio.h> 3 #include<string.h> 4 #include<stdlib.h> 5 6 struct LinkNode 7 { 8 struct LinkNode* next; 9 }; 10 11 struct Person 12 { 13 struct LinkNode node;//给四个字节存地址 14 char name[64]; 15 int age; 16 }; 17 18 void test() 19 { 20 struct Person p1 = {NULL, "aaa", 10}; 21 struct Person p2 = {NULL, "bbb", 20}; 22 struct Person p3 = {NULL, "ccc", 30}; 23 struct Person p4 = {NULL, "ddd", 40}; 24 struct Person p5 = {NULL, "eee", 50}; 25 26 struct LinkNode* pp1 = (struct LinkNode*)&p1; 27 struct LinkNode* pp2 = (struct LinkNode*)&p2; 28 struct LinkNode* pp3 = (struct LinkNode*)&p3; 29 struct LinkNode* pp4 = (struct LinkNode*)&p4; 30 struct LinkNode* pp5 = (struct LinkNode*)&p5; 31 32 pp1->next = pp2; 33 pp2->next = pp3; 34 pp3->next = pp4; 35 pp4->next = pp5; 36 pp5->next = NULL; 37 38 struct LinkNode* pCurrent = pp1; 39 while(pCurrent != NULL) 40 { 41 struct Person* person = (struct Person*)pCurrent; 42 printf("Name:%s Age:%d\n", person->name, person->age); 43 44 pCurrent = pCurrent->next; 45 } 46 47 } 48 49 int main(){ 50 51 test(); 52 53 system("pause"); 54 return EXIT_SUCCESS; 55 }
在学习c语言提高-数据结构总结了笔记,并分享出来。有问题请及时联系博主:Alliswell_WP,转载请注明出处。
posted on 2020-06-09 10:12 Alliswell_WP 阅读(179) 评论(0) 编辑 收藏 举报