(涛菜菜)数据结构-动态数组和链表

目录

一,动态数组

二,链表

三,心得


一,动态数组

#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;
}

三,心得

能吃苦 , 能耐得住寂寞积累 , 能承担风险 , 能专注于做事情 ,

  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值