目录
一,动态数组
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
//动态数组结构体
struct dynamicArray
{
//真实在堆区开辟数组的指针
void** pAddr;
//数组容量
int m_Capacity;
//数组大小
int m_Size;
};
//初始化数组
struct dynamicArray* init_dynamicArray(int capacity)
{
if (capacity <= 0)
{
return NULL;
}
//给数组分配内存
struct dynamicArray* arr = malloc(sizeof(struct dynamicArray));
if (arr == NULL)
{
return NULL;
}
//给属性初始化
arr->pAddr = malloc(sizeof(void*) * capacity);
//容量初始化
arr->m_Capacity = capacity;
//大小初始化
arr->m_Size = 0;
return arr;
}
//插入数组
void insert_dynamicArray(struct dynamicArray* arr, void* data,int pos)
{
if (arr == NULL)
{
return;
}
if (data == NULL)
{
return;
}
if (pos<0 || pos>arr->m_Size)
{
//尾插
pos = arr->m_Size;
}
//判断数组是否满了
if (arr->m_Size == arr->m_Capacity)
{
//1.计算新内存空间大小
int newCapacity = arr->m_Capacity * 2;
//2.开辟新空间
void** newSpace = malloc(sizeof(void*) * newCapacity);
//3.将原空间下数据拷贝到新空间下
memcpy(newSpace, arr->pAddr, sizeof(void*) * arr->m_Capacity);
//4.释放原空间
free(arr->pAddr);
//5.更改指针指向
arr->pAddr = newSpace;
//6.更新新容量
arr->m_Capacity = newCapacity;
}
//将新元素插入到数组中指定位置
for (int i = arr->m_Size - 1; i >= pos; i--)
{
arr->pAddr[i + 1] = arr->pAddr[i];
}
//将新元素插入到指定位置
arr->pAddr[pos] = data;
//更新数组大小
arr->m_Size++;
}
//遍历
void foreach_dynamicArray(struct dynamicArray* arr, void(*myPrint)(void*))
{
if (arr == NULL)
{
return;
}
for (int i = 0; i < arr->m_Size; i++)
{
myPrint(arr->pAddr[i]);
}
}
//删除数组
//按照位置删除数据
void removeByPos_dynamicArray(struct dynamicArray* arr, int pos)
{
if (arr == NULL)
{
return;
}
if (pos < 0 || pos < arr->m_Size - 1)
{
//无效位置return
return;
}
//删除指定位置的元素 从前往后移动
for (int i = pos; i < arr->m_Size; i++)
{
arr->pAddr[i] = arr->pAddr[i + 1];
}
//更新数组大小
arr->m_Size--;
}
//按值方式删除数据
void removeByValue(struct dynamicArray* arr, void* data,int(*myCompare)(void*,void*))
{
if (arr == NULL)
{
return;
}
if (data==NULL)
{
return;
}
for (int i = 0; i < arr->m_Size; i++)
{
//if(arr->pAddr[i]==data)
//利用回调函数 让用户自己告诉我们如何对比数据
if (myCompare(arr->pAddr[i], data))
{
removeByPos_dynamicArray(arr, i);
break;
}
}
}
//销毁数组
void destroy_dynamicArray(struct dynamicArray* arr)
{
if (arr = NULL)
{
return;
}
//内部维护在堆区的数组指针先释放
if(arr->pAddr!=NULL)
{
free(arr->pAddr);
arr->pAddr = NULL;
}
free(arr);
arr = NULL;
}
//回调函数 对比打印数据
void printPerson(void* data)
{
struct Person* person = data;
printf("姓名:%s 年龄:%d\n", person->name, person->age);
}
//回调函数 对比删除数据
int comparePerson(void * data1, void * data2)
{
struct Person* p1 = data1;
struct Person* p2 = data2;
return strcmp(p1->name, p2->name) == 0 && p1->age == p2->age;
}
struct Person
{
char name[64];
int age;
};
二,链表
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
//节点结构体
struct LinkNode
{
//数据域
void* data;
//指针域
struct LindNode* next;
};
//链表结构体
struct LList
{
struct LinkNode pHeader; //头节点
int m_Size; //链表长度
};
//void*别名
typedef void * LinkList;
//初始化链表
LinkList init_LinkList()
{
//分配内存
struct LList* mylist = malloc(sizeof(struct LList));
if (mylist == NULL)
{
return;
}
//给头节点属性初始化
mylist->pHeader.data = NULL;
mylist->pHeader.next = NULL;
mylist->m_Size = 0;
return mylist;
}
//插入节点
void insert_LinkList(LinkList list, int pos, void* data)
{
if (list == NULL)
{
return;
}
if (data == NULL)
{
return;
}
struct LList* mylist = list;
if (pos<0 || pos>mylist->m_Size)
{
//无效位置
pos = mylist->m_Size;
}
//创捷临时节点 通过循环找到待插入位置的前驱节点的位置
struct LinkNode* pCurrent = &mylist->pHeader;
for (int i = 0; i < pos; i++)
{
pCurrent = pCurrent->next;
}
//此时pCurrent就是插入位置的前驱节点
//创捷新节点
struct LinkNode* newNode = malloc(sizeof(struct LinkNode));
newNode->data = data;
newNode->next = NULL;
//建立节点的关系
newNode->next = pCurrent->next;
pCurrent->next = newNode;
//更新链表长度
mylist -> m_Size++;
}
void foreach_LinkList(LinkList list,void(*myPrint)(void*))
{
if (list == NULL)
{
return;
}
//还原链表真实结构体
struct LList *mylist=list;
struct LinkNode* pCurrent = mylist->pHeader.next;
for (int i = 0; i < mylist->m_Size; i++)
{
myPrint(pCurrent->data);
pCurrent = pCurrent->next;
}
}
//回调函数打印
void printPerson(void* data)
{
struct Person* person = data;
printf("姓名:%s 年龄:%d\n", person->name, person->age);
}
//删除链表节点 按位置删除
void removeByPos_LinkList(LinkList list, int pos)
{
if (list == NULL)
{
return;
}
struct LList* mylist = list;
if (pos<0 || pos>mylist->m_Size - 1)
{
//无效位置
return;
}
//找到待删除的位置的前驱节点的位置
struct LinkNode* pCurrent = &mylist->pHeader;
for (int i = 0; i < pos; i++)
{
pCurrent = pCurrent->next;
}
//pCurrent就是待删除节点的前驱节点的位置
//利用指针记录待删除节点
struct LinkNode* pDel = pCurrent->next;
//更改指针指向
pCurrent->next = pDel->next;
//释放待删除的节点
free(pDel);
pDel = NULL;
//更新链表的长度
mylist->m_Size--;
}
//删除链表节点 按值删除
void removeByValue_LinkList(LinkList list, void* data,int(*myCompare)(void*,void*))
{
if (list == NULL)
{
return;
}
if (data == NULL)
{
return;
}
//将list还原真实链表结构体
struct LList* mylist = list;
//创捷俩个辅助指针变量
struct LinkNode* pPrev = &mylist->pHeader;
struct LinkNode* pCurrent = mylist->pHeader.next;
//遍历链表 找用户要删的数据
for (int i = 0; i < mylist->m_Size; i++)
{
//if (data == pCurrent->data)
if (myCompare(data, pCurrent->data))
{
//找到要删除的数据,开始删除
//更改指针指向
pPrev->next = pCurrent->next;
//释放节点
free(pCurrent);
pCurrent = NULL;
//更新链表长度
mylist->m_Size--;
break;
}
//辅助指针向后移动
pPrev = pCurrent;
pCurrent = pCurrent->next;
}
}
//回调函数 删除对比
int ComparePerson(void* data1, void* data2)
{
struct Person* p1 = data1;
struct Person* p2 = data2;
return (strcmp(p1->name, p2->name) == 0) && p1->age == p2->age;
}
//返回链表长度
int size_LinkList(LinkList list)
{
if (list == NULL)
{
return -1;
}
//将list还原真实链表结构体
struct LList* mylist = list;
return mylist->m_Size;
}
//清空链表
void clear_LinkList(LinkList list)
{
if (list == NULL)
{
return;
}
//将list还原真实链表结构体
struct LList* mylist = list;
struct LinkNode* pCurrent = mylist->pHeader.next;
for (int i = 0; i < mylist->m_Size; i++)
{
//记录下一个节点位置
struct LinkNode* pNext = pCurrent->next;
free(pCurrent);
pCurrent = pNext;
}
mylist->pHeader.next = NULL;
mylist->m_Size = 0;
}
//销毁链表
void destory_LinkList(LinkList list)
{
if (list == NULL)
{
return;
}
//先清空链表,再销毁头节点
clear_LinkList(list);
free(list);
list = NULL;
}
三,心得
能吃苦 , 能耐得住寂寞积累 , 能承担风险 , 能专注于做事情 ,