数据结构基础(C语言实现)

  • 简介
  • 概念:程序 = 数据结构 + 算法
  • 数据结构学什么:各结构的创建,增,删,改,查,5个操作。
  • 动态数组
  • 1.创建一个结构体
  • 2.初始化
  • 3.首先“增”操作
  • 4.尾添加
  • 5.中间添加
  • 删除操作:1.删除尾部数据
  • 删除操作:2.删除全部元素(同理尾部删除)
  • 删除操作:3.释放动态数组
  • 删除操作: 4.删除中间元素
  • 查看:输出


简介

概念:程序 = 数据结构 + 算法

物理结构 :就是在内存上的结构
逻辑结构:代码中的结构,思想上的
数据结构的四种类型:集合型结构,线性结构,树型结构,图型结构

c 数据结构与算法库 c 数据结构教程_数据结构

c 数据结构与算法库 c 数据结构教程_动态数组_02

数据结构学什么:各结构的创建,增,删,改,查,5个操作。

动态数组

1.创建一个结构体
struct DongShuzu
{
	int* ShuZuTou;				//首地址
	unsigned int iRongLang;		//容量
	unsigned int iShuLiang;		//已存储的数量 	
};
2.初始化
**//初始化**
void ChuShiHua(struct DongShuzu* pStshuzu)
{
	pStshuzu->iRongLang = 5;
	pStshuzu->ShuZuTou = (int*)malloc(sizeof(int) * pStshuzu->iRongLang);
	pStshuzu->iShuLiang = 0;
}
3.首先“增”操作
//增加空间
void ZengJiaKongJian(struct DongShuzu* pStshuzu)
{
	参数合法性检测   
	if (NULL == pStshuzu)
	{
		printf("动态数组参数错误");
		return;
	}
	if (pStshuzu != NULL)
	{
		//判断数组是否满了
		if (pStshuzu->iShuLiang == pStshuzu->iRongLang)
		{
			//容量变大
			pStshuzu->iRongLang += 10;
			//申请空间
			int* ptemp = (int*)malloc(sizeof(int) * pStshuzu->iRongLang);
			if (NULL != ptemp)
			{
				memset(ptemp, 0, sizeof(int) * pStshuzu->iRongLang);
				//将原数据复制到新空间
				unsigned int i = 0;
				for (i = 0; i < pStshuzu->iShuLiang; i++)
				{
					ptemp[i] = pStshuzu->ShuZuTou[i];
				}		
				//释放原空间
				free(pStshuzu->ShuZuTou);
				//将数组头指向新空间
				pStshuzu->ShuZuTou = ptemp;
			}
		}
	}
}
4.尾添加
//尾部增加
void ZengJia(struct DongShuzu* pStshuzu, int iShuJu)
{
	参数合法性检测   
	if (NULL == pStshuzu)
	{
		printf("动态数组参数错误");
		return;
	}
	//判断是否满了,并增加空间
	ZengJiaKongJian(pStshuzu);
	//装数据
	pStshuzu->ShuZuTou[pStshuzu->iShuLiang] = iShuJu;
	//已存储数量++
	pStshuzu->iShuLiang++;
}
5.中间添加
void ZengJiaZhong(struct DongShuzu* pStshuzu, unsigned int iShuJu, unsigned int iXiaBiao)
{
	参数合法性检测   
	if (NULL == pStshuzu)
	{
		printf("动态数组参数错误");
		return;
	}
	//判断是否满了,并增加空间
	ZengJiaKongJian(pStshuzu);
	//下标大于数量
	if (iXiaBiao >= pStshuzu->iShuLiang)
	{
		iXiaBiao = pStshuzu->iShuLiang;
	}
	//向后挪
	for (unsigned int i = pStshuzu->iShuLiang; i > iXiaBiao; i--)
	{
		pStshuzu->ShuZuTou[i] = pStshuzu->ShuZuTou[i - 1];
	}
	//数据赋值到指定的位置
	pStshuzu->ShuZuTou[iXiaBiao] = iShuJu;
	//数量加1
	pStshuzu->iShuLiang++;
	
}
删除操作:1.删除尾部数据
//删除尾部数据
void ShanChuWei(struct DongShuzu* pStshuzu)
{
	参数合法性检测   
	if (NULL == pStshuzu)
	{
		printf("动态数组参数错误");
		return;
	}
	pStshuzu->iShuLiang -= 1;
}

因为是数组,所以只需要将数量减一 ,不读取这个数,便是删除,下次添加直接覆盖尾部这个数据即可;

删除操作:2.删除全部元素(同理尾部删除)
//删除全部元素
void ShanChuQuanBu(struct DongShuzu* pStshuzu)
{
	参数合法性检测   
	if (NULL == pStshuzu)
	{
		printf("动态数组参数错误");
		return;
	}
	pStshuzu->iShuLiang = 0;
}
删除操作:3.释放动态数组
//释放动态数组
void ShiFang(struct DongShuzu* pStshuzu)
{
	参数合法性检测   
	if (NULL == pStshuzu)
	{
		printf("动态数组参数错误");
		return;
	}
	pStshuzu->iShuLiang = 0;
	pStshuzu->iRongLang = 0;
	free(pStshuzu->ShuZuTou);
	pStshuzu->ShuZuTou = NULL;
}
删除操作: 4.删除中间元素
//删除中间元素
void ShanChuZhongJian(struct DongShuzu* pStshuzu, unsigned int iWeiZhi)
{
	参数合法性检测   
	if (NULL == pStshuzu|| iWeiZhi > pStshuzu->iShuLiang)
	{
		printf("动态数组参数错误");
		return;
	}
	//后边的往前移动
	for (unsigned int i = iWeiZhi - 1; i < pStshuzu->iShuLiang - 1; i++)
	{
		pStshuzu->ShuZuTou[i] = pStshuzu->ShuZuTou[i + 1];
	}
	//数量减一
	pStshuzu->iShuLiang -= 1;
}
查看:输出
//输出
void Shuchu(struct DongShuzu* pStshuzu)
{
	if (NULL == pStshuzu)
	{
		printf("参数错误");
		return;
	}
	printf("容量; %u   已存储数量:%u\n", pStshuzu->iRongLang, pStshuzu->iShuLiang);
	printf("数据: ");
	for (unsigned int i = 0; i < pStshuzu->iShuLiang; i++)
	{
		printf("%d ", pStshuzu->ShuZuTou[i]);
	}
	printf("\n");
}

完整动态数组代码

#include<stdio.h>
 #include<stdlib.h>
 #include<string.h>
 #include<malloc.h>
 struct DongShuzu
 {
 int* ShuZuTou; //首地址
 unsigned int iRongLang; //容量
 unsigned int iShuLiang; //已存储的数量 
 };
 //初始化
 void ChuShiHua(struct DongShuzu* pStshuzu);
 //增加空间
 void ZengJiaKongJian(struct DongShuzu* pStshuzu);
 //尾部增加
 void ZengJia(struct DongShuzu* pStshuzu, int iShuJu);
 //中间插入
 void ZengJiaZhong(struct DongShuzu* pStshuzu, unsigned int iShuJu, unsigned int iXiaBiao);
 //删除尾部数据
 void ShanChuWei(struct DongShuzu* pStshuzu);
 //删除中间元素
 void ShanChuZhongJian(struct DongShuzu* pStshuzu, unsigned int iWeiZhi);
 //删除全部数据
 void ShanChuQuanBu(struct DongShuzu* pStshuzu);
 //释放动态数组
 void ShiFang(struct DongShuzu* pStshuzu);
 //输出
 void Shuchu(struct DongShuzu* pStshuzu);
 int main()
 {
 struct DongShuzu stDhuzu;
 //初始化
 ChuShiHua(&stDhuzu);
 //增加
 ZengJia(&stDhuzu, 1);
 ZengJia(&stDhuzu, 2);
 ZengJia(&stDhuzu, 3);
 ZengJia(&stDhuzu, 4);
 ZengJia(&stDhuzu, 5);
 //ZengJia(&stDhuzu, 6);
 //中间插入
 ZengJiaZhong(&stDhuzu, 8, 8);
 ZengJiaZhong(&stDhuzu, 9, 8);
 ZengJiaZhong(&stDhuzu, 10, 8);
 //删除尾部元素
 //ShanChuWei(&stDhuzu);
 //ShanChuWei(&stDhuzu);
 //ShanChuWei(&stDhuzu);
 //删除中间元素
 ShanChuZhongJian(&stDhuzu, 5);
 //删除全部数据
 //ShanChuQuanBu(&stDhuzu);
 //输出
 Shuchu(&stDhuzu);
 //释放动态数组
 //ShiFang(&stDhuzu);
 free(stDhuzu.ShuZuTou);
 return 0;
 }
 //初始化
 void ChuShiHua(struct DongShuzu* pStshuzu)
 {
 pStshuzu->iRongLang = 5;
 pStshuzu->ShuZuTou = (int*)malloc(sizeof(int) * pStshuzu->iRongLang);
 pStshuzu->iShuLiang = 0;
 }
 //增加空间
 void ZengJiaKongJian(struct DongShuzu* pStshuzu)
 {
 参数合法性检测
 if (NULL == pStshuzu)
 {
 printf(“动态数组参数错误”);
 return;
 }
 if (pStshuzu != NULL)
 {
 //判断是否满了
 if (pStshuzu->iShuLiang == pStshuzu->iRongLang)
 {
 //容量变大
 pStshuzu->iRongLang += 10;
 //申请空间
 int* ptemp = (int*)malloc(sizeof(int) * pStshuzu->iRongLang);
 if (NULL != ptemp)
 {
 memset(ptemp, 0, sizeof(int) * pStshuzu->iRongLang);
 //将原数据复制到新空间
 unsigned int i = 0;
 for (i = 0; i < pStshuzu->iShuLiang; i++)
 {
 ptemp[i] = pStshuzu->ShuZuTou[i];
 } 
 //释放原空间
 free(pStshuzu->ShuZuTou);
 //将数组头指向新空间
 pStshuzu->ShuZuTou = ptemp;
 }
 }
 }
 }
 //尾部增加
 void ZengJia(struct DongShuzu* pStshuzu, int iShuJu)
 {
 参数合法性检测
 if (NULL == pStshuzu)
 {
 printf(“动态数组参数错误”);
 return;
 }
 //判断是否满了,并增加空间
 ZengJiaKongJian(pStshuzu);
 //装数据
 pStshuzu->ShuZuTou[pStshuzu->iShuLiang] = iShuJu;
 //已存储数量++
 pStshuzu->iShuLiang++;
 }
 //中间插入
 void ZengJiaZhong(struct DongShuzu* pStshuzu, unsigned int iShuJu, unsigned int iXiaBiao)
 {
 参数合法性检测
 if (NULL == pStshuzu)
 {
 printf(“动态数组参数错误”);
 return;
 }
 //判断是否满了,并增加空间
 ZengJiaKongJian(pStshuzu);
 //下标大于数量
 if (iXiaBiao >= pStshuzu->iShuLiang)
 {
 iXiaBiao = pStshuzu->iShuLiang;
 }
 //向后挪
 for (unsigned int i = pStshuzu->iShuLiang; i > iXiaBiao; i–)
 {
 pStshuzu->ShuZuTou[i] = pStshuzu->ShuZuTou[i - 1];
 }
 //数据赋值到指定的位置
 pStshuzu->ShuZuTou[iXiaBiao] = iShuJu;
 //数量加1
 pStshuzu->iShuLiang++;
 }
 //删除尾部数据
 void ShanChuWei(struct DongShuzu* pStshuzu)
 {
 参数合法性检测
 if (NULL == pStshuzu)
 {
 printf(“动态数组参数错误”);
 return;
 }
 pStshuzu->iShuLiang -= 1;
 }
 //删除全部元素
 void ShanChuQuanBu(struct DongShuzu* pStshuzu)
 {
 参数合法性检测
 if (NULL == pStshuzu)
 {
 printf(“动态数组参数错误”);
 return;
 }
 pStshuzu->iShuLiang = 0;
 }
 释放动态数组
 void ShiFang(struct DongShuzu* pStshuzu)
 {
 参数合法性检测
 if (NULL == pStshuzu)
 {
 printf(“动态数组参数错误”);
 return;
 }
 pStshuzu->iShuLiang = 0;
 pStshuzu->iRongLang = 0;
 free(pStshuzu->ShuZuTou);
 pStshuzu->ShuZuTou = NULL;
 }
 //删除中间元素
 void ShanChuZhongJian(struct DongShuzu* pStshuzu, unsigned int iWeiZhi)
 {
 参数合法性检测
 if (NULL == pStshuzu|| iWeiZhi > pStshuzu->iShuLiang)
 {
 printf(“动态数组参数错误”);
 return;
 }
 //后边的往前移动
 for (unsigned int i = iWeiZhi - 1; i < pStshuzu->iShuLiang - 1; i++)
 {
 pStshuzu->ShuZuTou[i] = pStshuzu->ShuZuTou[i + 1];
 }
 //数量减一
 pStshuzu->iShuLiang -= 1;
 }
 //输出
 void Shuchu(struct DongShuzu* pStshuzu)
 {
 if (NULL == pStshuzu)
 {
 printf(“参数错误”);
 return;
 }
 printf(“容量; %u 已存储数量:%u\n”, pStshuzu->iRongLang, pStshuzu->iShuLiang);
 printf(“数据: “);
 for (unsigned int i = 0; i < pStshuzu->iShuLiang; i++)
 {
 printf(”%d “, pStshuzu->ShuZuTou[i]);
 }
 printf(”\n”);
 }