C数据结构-单向链表版本一

链表和数组的区别:
两者的区别:

数组静态分配内存,链表动态分配内存。
数组在内存中是连续的,链表是不连续的。
数组利用下标定位,查找的时间复杂度是O(1),链表通过遍历定位元素,查找的时间复杂度是O(N)。
数组插入和删除需要移动其他元素,时间复杂度是O(N),链表的插入或删除不需要移动其他元素,时间复杂度是O(1)。
数组的优点
随机访问性比较强,可以通过下标进行快速定位。
查找速度快
数组的缺点
插入和删除的效率低,需要移动其他元素。
会造成内存的浪费,因为内存是连续的,所以在申请数组的时候就必须规定七内存的大小,如果不合适,就会造成内存的浪费。
内存空间要求高,创建一个数组,必须要有足够的连续内存空间。
数组的大小是固定的,在创建数组的时候就已经规定好,不能动态拓展。
链表的优点
插入和删除的效率高,只需要改变指针的指向就可以进行插入和删除。
内存利用率高,不会浪费内存,可以使用内存中细小的不连续的空间,只有在需要的时候才去创建空间。大小不固定,拓展很灵活。
链表的缺点
查找的效率低,因为链表是从第一个节点向后遍历查找。

LinkList.h代码

#pragma once

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

#ifdef __cplusplus
extern "C"{
#endif // _cplusplus


	typedef void* LinkList;
	typedef void(*FOREACH)(void *);
	//比较函数
	typedef int(*COMPARE)(void *,void *);
	//初始化链表
	LinkList Init_LinkLList();
	//插入节点
	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"


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

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


//初始化链表
LinkList Init_LinkLList()
{
	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 || data == NULL)
	{
		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 || 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 (list == NULL)
	{
		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 (list == NULL || data==NULL || compare == NULL)
	{
		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 (list == NULL)
	{
		return;
	}
	struct LList* myList = (struct LList*)list;
	//辅助指针变量
	struct LinkNode *pCurrent = myList->header.next;

	while (pCurrent!=NULL)
	{
		struct LinkNode *pNext = pCurrent->next;
		//释放当前节点内存
		free(pCurrent);
		pCurrent = pNext;
	}
	myList->header.next = NULL;
	myList->size = 0;
}
//大小
int Size_LinkList(LinkList list)
{
	if (list == NULL)
	{
		return;
	}
	struct LList* myList = (struct LList*)list;
	return myList->size;
}
//销毁链表
void Destroy_LinkList(LinkList list)
{
	if (list == NULL)
	{
		return;
	}
	//清空链表
	Clear_LinkList(list);
	free(list);
	list = NULL;
}

主函数代码

#define _CRT_SECURE_NO_WARNINGS

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

#include "LinkList.h"

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

};

void MyPrint(void *data)
{

	struct Person* person = (struct Person*)data;
	printf("Name:%s,Age:%d\n", person->name, person->age);
}
int MyComapre(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 text()
{
	//创建链表
	LinkList list = Init_LinkLList();

	//创建数据
	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);
	Insert_LinkList(list, 0, &p2);
	Insert_LinkList(list, 1, &p3);
	Insert_LinkList(list, 2, &p4);
	Insert_LinkList(list, 20, &p5);
	Insert_LinkList(list, 3, &p6);
	Insert_LinkList(list, 6, &p7);

	//遍历
	Foreach_LinkList(list, MyPrint);
	printf("-------------\n");
	printf("List Size :%d\n",Size_LinkList(list));
	RemoveByPos_LinkList(list, 3);
	//遍历
	Foreach_LinkList(list, MyPrint);
	printf("-------------\n");
	struct Person pDl = { "ggg", 70 };
	RemoveByVal_LinkList(list, &pDl, MyComapre);
	//遍历
	Foreach_LinkList(list, MyPrint);
	printf("-------------\n");
	//清空链表
	Clear_LinkList(list);
	printf("-------------\n");
	printf("List Size :%d\n", Size_LinkList(list));
}
int main()
{
	text();
	system("pause");
	return 0;
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
ava实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),可运行高分资源 Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现
C语言是一种广泛使用的编程语言,它具有高效、灵活、可移植性强等特点,被广泛应用于操作系统、嵌入式系统、数据库、编译器等领域的开发。C语言的基本语法包括变量、数据类型、运算符、控制结构(如if语句、循环语句等)、函数、指针等。下面详细介绍C语言的基本概念和语法。 1. 变量和数据类型 在C语言中,变量用于存储数据,数据类型用于定义变量的类型和范围。C语言支持多种数据类型,包括基本数据类型(如int、float、char等)和复合数据类型(如结构体、联合等)。 2. 运算符 C语言中常用的运算符包括算术运算符(如+、、、/等)、关系运算符(如==、!=、、=、<、<=等)、逻辑运算符(如&&、||、!等)。此外,还有位运算符(如&、|、^等)和指针运算符(如、等)。 3. 控制结构 C语言中常用的控制结构包括if语句、循环语句(如for、while等)和switch语句。通过这些控制结构,可以实现程序的分支、循环和多路选择等功能。 4. 函数 函数是C语言中用于封装代码的单元,可以实现代码的复用和模块化。C语言中定义函数使用关键字“void”或返回值类型(如int、float等),并通过“{”和“}”括起来的代码块来实现函数的功能。 5. 指针 指针是C语言中用于存储变量地址的变量。通过指针,可以实现对内存的间接访问和修改。C语言中定义指针使用星号()符号,指向数组、字符串和结构体等数据结构时,还需要注意数组名和字符串常量的特殊性质。 6. 数组和字符串 数组是C语言中用于存储同类型数据的结构,可以通过索引访问和修改数组中的元素。字符串是C语言中用于存储文本数据的特殊类型,通常以字符串常量的形式出现,用双引号("...")括起来,末尾自动添加'\0'字符。 7. 结构体和联合 结构体和联合是C语言中用于存储不同类型数据的复合数据类型。结构体由多个成员组成,每个成员可以是不同的数据类型;联合由多个变量组成,它们共用同一块内存空间。通过结构体和联合,可以实现数据的封装和抽象。 8. 文件操作 C语言中通过文件操作函数(如fopen、fclose、fread、fwrite等)实现对文件的读写操作。文件操作函数通常返回文件指针,用于表示打开的文件。通过文件指针,可以进行文件的定位、读写等操作。 总之,C语言是一种功能强大、灵活高效的编程语言,广泛应用于各种领域。掌握C语言的基本语法和数据结构,可以为编程学习和实践打下坚实的基础。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

和沐阳学逆向

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值