Day24.C提高(数据结构01)

Day24.C提高(数据结构01)

001.动态数组简单实现

#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<stdlib.h>
#include<string.h>

//1.先把所需要的数据信息结构定义下来
struct DynamicArray
{
	//数组存储元素的空间的首地址
	void** addr;
	//存储数据的内存中最大能够容纳多少元素
	int capacity;//容量
	//当前存储数据的内存中有多少个元素
	int size;
};

//初始化数组
int Init_DynamicArray(int capacity, struct DynamicArray** arr)
{
	if (capacity == NULL)
	{
		return -1;
	}
	if (arr == NULL)
	{
		return -1;
	}
	struct DynamicArray* buf = malloc(sizeof(struct DynamicArray));
	buf->capacity = capacity;
	buf->addr = malloc(sizeof(void*) * buf->capacity);
	buf->size = 0;
	*arr = buf;
}
//插入元素
void Insert_DynamicArray(struct DynamicArray* arr, int pos, void* data)
{
	if (NULL == arr)
	{
		return;
	}
	if (NULL == data)
	{
		return;
	}
	if (pos > arr->size || pos < 0)
	{
		pos = arr->size;
	}
	//判断空间是否足够
	if (arr->size >= arr->capacity)
	{
		//1.申请一块更大的内存空间
		int newcapacity = arr->capacity * 2;
		void** newspace = malloc(sizeof(void*) * newcapacity);
		//2.将原来空间的数据拷贝到新空间
		memcpy(newspace, arr->addr, sizeof(void*) * arr->capacity);
		//3.释放原来的内存空间
		if (NULL != arr->addr)
		{
			free(arr->addr);
			arr->addr = NULL;
		}
		//4.更新addr指向,以及动态数组的容量
		arr->addr = newspace;
		arr->capacity = newcapacity;
	}
	//移动元素,给pos位置空出位置来
	for (int i = arr->size - 1; i >= pos; --i)
	{
		arr->addr[i + 1] = arr->addr[i];
	}
	//将新元素插入到pos位置
	arr->addr[pos] = data;
	arr->size++;

}
//遍历
void Foreach_DynamicArray(struct DynamicArray* arr, void(*_callback)(void*))
{
	if (NULL == arr)
	{
		return;
	}
	if (NULL == _callback)
	{
		return;
	}
	for (int i = 0; i < arr->size; ++i)
	{
		_callback(arr->addr[i]);
	}

}

//按位置删除
void RemoveByPos_DynamicArray(struct DynamicArray* arr, int pos)
{
	if (NULL == arr)
	{
		return;
	}
	if (pos<0 || pos>arr->size - 1)
	{
		return;
	}
	for (int i = pos; i < arr->size - 1; ++i)
	{
		arr->addr[i] = arr->addr[i + 1];
	}
	arr->size--;
}

//按值删除
void RemoveByValue_DynamicArray(struct DynamicArray* arr, void* data,int(*MYCOMPARE)(void*,void*))
{
	if (NULL == arr)
	{
		return;
	}
	if (NULL == data)
	{
		return;
	}
	if (NULL == MYCOMPARE)
	{
		return;
	}

	for (int i = 0; i < arr->size; ++i)
	{
		if (MYCOMPARE(arr->addr[i], data))
		{
			//找到了(调用按位置删除)
			RemoveByPos_DynamicArray(arr, i);
			break;
		}
	}

}

//销毁数组
void Destroy_DynamicArray(struct DynamicArray* arr)
{
	if (NULL == arr)
	{
		return;
	}
	if (arr->addr != NULL)
	{
		free(arr->addr);
		arr->addr = NULL;
	}
	free(arr);
	arr = NULL;
}

struct Person
{
	char name[64];
	int age;
};

void myPrintf(void* data)
{
	struct Person* person = (struct Person*)data;
	printf("Name:%s Age:%d\n", person->name, person->age);
}

void myComepare_1(void* d1, void* d2)
{
	struct Person* p1 = (struct Person*)d1;
	struct Person* p2 = (struct Person*)d2;

	return strcmp(p1->name, p2->name) == 0 && p1->age == p2->age;
}

void test101()
{
	//创建动态数组
	struct DynamicArray* da;
	Init_DynamicArray(5, &da);
	struct Person p1 = { "aaa",10 };
	struct Person p2 = { "bbb",20 };
	struct Person p3 = { "ccc",30 };
	struct Person p4 = { "ddd",40 };
	struct Person p5 = { "eee",50 };
	struct Person p6 = { "fff",60 };

	//动态数组添加元素
	Insert_DynamicArray(da, 0, &p1);
	Insert_DynamicArray(da, 0, &p2);
	Insert_DynamicArray(da, 0, &p3);
	Insert_DynamicArray(da, 1, &p4);
	Insert_DynamicArray(da, 1, &p5);//3 5 4 2 1
	printf("容量:%d\n", da->capacity);
	Insert_DynamicArray(da, 100, &p6);//3 5 4 2 1 6
	printf("容量:%d\n", da->capacity);

	//遍历打印
	Foreach_DynamicArray(da, myPrintf);

	//按位置删除
	RemoveByPos_DynamicArray(da, 2);//3 5 2 1 6
	//遍历打印
	printf("----------------\n");
	Foreach_DynamicArray(da, myPrintf);

	//按值删除
	struct Person pDel = { "aaa",10 };
	RemoveByValue_DynamicArray(da, &pDel, myComepare_1);

	//遍历打印
	printf("----------------\n");
	Foreach_DynamicArray(da, myPrintf);

	//销毁
	Destroy_DynamicArray(da);
}

int main(void)
{
	test101();

	system("pause");
	return EXIT_SUCCESS;
}

002.单向链表(版本一)

LinkList.h

#pragma once
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<stdlib.h>

#ifdef __cplusplus
extern "C" {
#endif

	//链表结点数据类型
	struct LinkNode
	{
		void* data;
		struct LinkNode* next;
	};

	//链表数据类型
	struct LList
	{
		struct LinkNode header;
		int size;
	};

	//函数指针变量
	typedef void(*FOREACH)(void*);
	typedef int(*COMPARE)(void*, void*);

	typedef void* LinkList;
	//初始化链表
	LinkList Init_LinkList();
	//插入结点(按位置插入)
	void insert_LinkList(LinkList list, int pos, void* data);
	//遍历链表
	void Foreach_LinkList(LinkList list, FOREACH myforeach);
	//按位置删除
	void RemoveByPos_LinkList(LinkList list, int pos);
	//按值删除
	void RemoveByVal_LinkList(LinkList list, void* data, COMPARE compare);
	//清空链表
	void Clear_LinkList(LinkList list);
	//大小
	int Size_LinkList(LinkList list);
	//销毁链表
	void Destroy_LinkList(LinkList list);


#ifdef __cplusplus
}
#endif

LinkList.c

#include"LinkList.h"

//初始化链表(给链表分配内存)
LinkList Init_LinkList()
{
	struct LList* list = malloc(sizeof(struct LList));
	if (NULL == list)
	{
		return NULL;
	}
	list->header.data = NULL;
	list->header.next = NULL;
	list->size = 0;

	return list;
}
//插入结点(按位置插入)
void insert_LinkList(LinkList list, int pos, void* data) 
{
	if (NULL == list)
	{
		return;
	}
	if (NULL == data)
	{
		return;
	}
	struct LList* mylist = (struct LList*)list;
	if (pos < 0 || pos > mylist->size)
	{
		pos = mylist->size;
	}

	//查找插入位置
	struct LinkNode* pCurrent = &(mylist->header);
	for (int i = 0; i < pos; ++i)
	{
		pCurrent = pCurrent->next;
	}
	//创建新节点
	struct LinkNode* newnode = malloc(sizeof(struct LinkNode));
	newnode->data = data;
	newnode->next = NULL;

	//新节点插入到链表中
	newnode->next = pCurrent->next;
	pCurrent->next = newnode;

	mylist->size++;
}
//遍历链表
void Foreach_LinkList(LinkList list, FOREACH myforeach)/*回调函数*/
{
	if (NULL == list)
	{
		return;
	}
	if (NULL == myforeach)
	{
		return;
	}

	struct LList* mylist = (struct LList*)list;
	struct LinkNode* pCurrent = mylist->header.next;

	while (pCurrent != NULL)
	{
		myforeach(pCurrent->data);
		pCurrent = pCurrent->next;
	}
}

//按位置删除
void RemoveByPos_LinkList(LinkList list, int pos)
{
	if (NULL == list)
	{
		return;
	}
	
	struct LList* mylist = (struct LList*)list;
	if (pos < 0 || pos > mylist->size - 1)
	{
		return;
	}

	//查找插入位置
	struct LinkNode* pCurrent = &(mylist->header);
	for (int i = 0; i < pos; ++i)
	{
		pCurrent = pCurrent->next;
	}
	//先保存待删除结点
	struct LinkNode* pDel = pCurrent->next;
	//重新建立待删除结点的前驱和后继节点关系
	pCurrent->next = pDel->next;
	//释放删除结点内存
	free(pDel);
	pDel = NULL;

	mylist->size--;
}
//按值删除
void RemoveByVal_LinkList(LinkList list, void* data, COMPARE compare)
{
	if (NULL == list)
	{
		return;
	}
	if (NULL == data)
	{
		return;
	}
	if (NULL == compare)
	{
		return;
	}
	struct LList* mylist = (struct LList*)list;
	//辅助指针变量
	struct LinkNode* pPrev = &(mylist->header);
	struct LinkNode* pCurrent = pPrev->next;

	while (pCurrent != NULL)
	{
		if (compare(pCurrent->data, data))
		{
			//找到待删除结点(重新建立待删除结点的前驱和后继节点关系)
			pPrev->next = pCurrent->next;
			//释放删除结点内存
			free(pCurrent);
			pCurrent = NULL;
			mylist->size--;
			break;
		}
		pPrev = pCurrent;
		pCurrent = pCurrent->next;
	}

}

//清空链表
void Clear_LinkList(LinkList list)
{
	if (NULL == list)
	{
		return;
	}
	struct LList* mylist = (struct LList*)list;
	//辅助指针变量
	struct LinkNode* pCurrent = mylist->header.next;
	while (pCurrent != NULL)
	{
		//先缓存下一个节点的地址
		struct LinkList* pNext = pCurrent->next;
		//释放当前节点
		free(pCurrent);

		pCurrent = pNext;
	}
	mylist->header.next = NULL;
	mylist->size = 0;
}
//大小
int Size_LinkList(LinkList list)
{
	if (NULL == list)
	{
		return;
	}
	struct LList* mylist = (struct LList*)list;
	return mylist->size;
}
//销毁链表
void Destroy_LinkList(LinkList list)
{
	if (NULL == list)
	{
		return;
	}
	struct LList* mylist = (struct LList*)list;
	//辅助指针变量
	struct LinkNode* pCurrent = mylist->header.next;
	while (pCurrent != NULL)
	{
		//先缓存下一个节点的地址
		struct LinkList* pNext = pCurrent->next;
		//释放当前节点
		free(pCurrent);

		pCurrent = pNext;
	}
	mylist->header.next = NULL;
	mylist->size = 0;
	free(list);
	list = NULL;
}

单向链表(版本一).c

#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include"LinkList.h"

struct Person
{
	char name[64];
	int age;
};

int myCompare(void* d1, void* d2)
{
	struct Person* p1 = (struct Person*)d1;
	struct Person* p2 = (struct Person*)d2;

	/*if (strcmp(p1->name, p2->name) == 0 && p1->age == p2->age)
	{
		return 1;
	}
	return 0;*/
	//两者等价
	return strcmp(p1->name, p2->name) == 0 && p1->age == p2->age;
}

void myPrint(void* data)
{
	struct Person* person = (struct Person*)data;
	printf("Name:%s Age:%d\n", person->name, person->age);
}

void test201()
{
	//创建链表
	LinkList list = Init_LinkList();

	//创建数据
	struct Person p1 = { "aaa",10 };
	struct Person p2 = { "bbb",20 };
	struct Person p3 = { "ccc",30 };
	struct Person p4 = { "ddd",40 };
	struct Person p5 = { "eee",50 };
	struct Person p6 = { "fff",60 };
	struct Person p7 = { "ggg",70 };

	//插入数据
	insert_LinkList(list, 0, &p1);//p1
	insert_LinkList(list, 0, &p2);//p2 p1
	insert_LinkList(list, 1, &p3);// p2 p3 p1
	insert_LinkList(list, 2, &p4);// p2 p3 p4 p1
	insert_LinkList(list, 20, &p5);// p2 p3 p4 p1 p5
	insert_LinkList(list, 3, &p6);// p2 p3 p4 p6 p1 p5
	insert_LinkList(list, 6, &p7);// p2 p3 p4 p6 p1 p5 p7

	//遍历打印
	Foreach_LinkList(list,myPrint);

	//打印链表大小
	printf("-------------------------\n");
	printf("List Size:%d\n", Size_LinkList(list));

	//按位置删除
	RemoveByPos_LinkList(list, 3);// p2 p3 p4 p1 p5 p7
								  
	//遍历打印
	printf("-------------------------\n");
	Foreach_LinkList(list, myPrint);

	//按值删除
	struct Person pDelPerson = { "ggg",70 };
	RemoveByVal_LinkList(list, &pDelPerson, myCompare);// p2 p3 p4 p1 p5

	//遍历打印
	printf("-------------------------\n");
	Foreach_LinkList(list, myPrint);

	//清空链表
	Clear_LinkList(list);
	//打印链表大小
	printf("-------------------------\n");
	printf("List Size:%d\n", Size_LinkList(list));

	//销毁链表
	Destroy_LinkList(list);

}

int main(void)
{
	test201();

	system("pause");
	return EXIT_SUCCESS;
}

003.单向链表(版本二)思路

版本一的单向链表的缺陷:每次添加和删除元素时都需要开辟堆空间和释放堆空间

版本二思路(代码简单实现)

#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<stdlib.h>
#include<string.h>

struct LinkNode
{
	struct LinkNode* next;
};

struct Person
{
	struct LinkNode node;
	char name[64];
	int age;
};

//版本二简单思路,下次实现完整代码
void test301()
{
	struct Person p1 = { NULL,"aaa",10 };
	struct Person p2 = { NULL,"bbb",20 };
	struct Person p3 = { NULL,"ccc",30 };
	struct Person p4 = { NULL,"ddd",40 };
	struct Person p5 = { NULL,"eee",50 };

	struct LinkNode* pp1 = (struct LinkNode*)&p1;
	struct LinkNode* pp2 = (struct LinkNode*)&p2;
	struct LinkNode* pp3 = (struct LinkNode*)&p3;
	struct LinkNode* pp4 = (struct LinkNode*)&p4;
	struct LinkNode* pp5 = (struct LinkNode*)&p5;

	pp1->next = pp2;
	pp2->next = pp3;
	pp3->next = pp4;
	pp4->next = pp5;
	pp5->next = NULL;

	struct LinkNode* pCurrent = pp1;
	while (pCurrent != NULL)
	{
		struct Person* person = (struct Person*)pCurrent;
		printf("Name:%s Age:%d\n", person->name, person->age);

		pCurrent = pCurrent->next;
	}

}


int main(void)
{
	test301();
	system("pause");
	return EXIT_SUCCESS;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值