数组 信息管理系统重构预热(1)基本逻辑使用线性连续结构该如何写?

此篇为重构之前的练习

使用线性连续存储结构来写一个信息管理程序
要求要尽量提高复用性,其次因为使用的这种存储结构的劣势约束,在这里使用动态内存分配来进行一定的弥补
功能:功能包括:初始化,追加数据,从某位置插入数据,删除数据,判断数据是否为空,为数据排序,遍历输出数据,将数据进行倒置

代码展示:

预备工作
一开始首先要初始化数据,我在初始话之前先定义了一个结构体(类)其中包含三个成员,分别是:

struct Arr
{
	int* pBase; //存储的是数组第一个元素的首地址
	int len; //数组所能容纳的最大元素的个数
	int cnt; //当前数组有效元素的个数
	//int increment; //自动增长因子
};

定义这个结构体的目的是为了让我更好的对数组进行操作,后面慢慢说。
初始化

void init_arr(struct Arr* parr,int len) //初始化结构体
{
	//parr->len=99;
	parr->pBase = (int*)malloc(sizeof(int) * len);
	if (NULL == parr->pBase)
	{									
		printf("动态内存分配失败");
		exit(-1);  //终止
	}
	else
	{
		parr->cnt = 0;
		parr->len = len;
	}
	return;
}

其实初始化就是要用户给出一个用户需要的数组长度,在内存中动态开辟出空间,这样就初始化完毕了,在这里需要判断内存是否开辟成功,及判断返回的地址是否为空,如果为空那就是没有成功,否则的话我们就把结构体中的长度和有效元素个数初始化就可以了

遍历输出数据

我比较懒,觉得这个功能比较简单所以先写这个了,当然先写后写没什么区别了

void show_arr(struct Arr* parrshow) //输出数组
{
	if (is_empty(parrshow))
		printf("数组为空\n");
	else
	{
		//printf("%d %d %s", parrshow->cnt, parrshow->len, parrshow->pBase);
		for (int i = 0; i < parrshow->cnt; ++i)
		{
			//printf("%d", *(parrshow[i].pBase));
			printf("%d\t", (parrshow->pBase)[i]);
			//printf("%d", parrshow->pBase[i]);--ok
		}
	}
	printf("\n");
}

遍历输出数组,这个不要太简单,不做详解,不过就是要注意,我们遍历输出前先要判断数组是否为空,我们虽然已经按用户要求创建好了数组在输出前内部还都是垃圾值,所以先要判断内部是否有有效数组,机判断是否为空
判断数组是否为空

bool is_empty(struct Arr* parrempty)//判断是否为空
{
	if (0 == parrempty->cnt)
		return true;
	else
		return false;
}

追加数据
添加数据有两种方式,一种是追加数据,一种是插入数据两种方式不太一样,我们先来个简单的——在数据的最后的有效数据后在添加数据,这时需要考虑的是数组是否已经满,再一个需要考虑的地方是,添加元素有可能会成功或者失败,所以我们需要返回一个布尔值来提醒用户是否添加成功

bool append_arr(struct Arr* parr, int val)//往数组中追加数据 
{
	//满时返回false
	if (is_full(parr))
		return false;
	else//不满时追加     
	{
		parr->pBase[parr->cnt] = val;
		parr->cnt ++;
		return true; //表示往里面添加元素成功
	}
}

判断数组是否满
这个比较简单,当然涉及到返回布尔值,那就是代表程序可以偷懒了
下面是偷懒(完美)的写法

bool is_full(struct Arr* parr)//判断数组是否满
{
	return(parr->cnt == parr->len);
}

还有不偷懒(不完美)的写法:

bool is_full(struct Arr* parr)//判断数组是否满
{
	//不够好的代码
	if (parr->cnt == parr->len)
			return true;
	else
			return false;

	
}

我当然是选择上种。
插入数据
结合着追加数据的热度,我们开始思考如何再数组中插入数据
首先就是要判断数据是否已满,慢的话就不能插入了呗。
其次就是要明白数据不能乱插,只能查在有效数据个数+1的位置之前,比如你这个数组中只有两个元素,但是你想插在下标为4的位置,那就不行了
再其次如果你插入的话,要把插入位置及以后的有效数据都往后移动一位
最后用户给的位置可能不合法,这个也要想到
看成果:

bool insert_arr(struct Arr* parr, int pos, int val)
{
	if (is_full(parr) || pos<1 || pos>parr->cnt+1) //
		return false;
	else
	{
		int i;
		for (i = parr->cnt - 1;i>=pos-1;--i)
		{
			parr->pBase[i+1] = parr->pBase[i];
		}
		parr->pBase[pos - 1] = val;
		parr->cnt++;
		return true;
	}
}

删除指定位置数据
删除数据跟插入数据需要考虑的问题类似

bool delete_arr(struct Arr* parr, int pos, int* pval)
{
	if (is_empty(parr) || pos<1 || pos>parr->cnt)
		return false;
	else
	{
		*pval = parr->pBase[pos - 1];
		for (int i = pos; i < parr->cnt; ++i)
		{
			parr->pBase[i - 1] = parr->pBase[i];

		}
		parr->cnt--;
		return true;
	}
}

数据倒置

void inversion_arr(struct Arr* parr)
{	
	int i = 0;
	int j = parr->cnt - 1;
	int t;
	while (i < j)
	{
		t = parr->pBase[i];
		parr->pBase[i] = parr->pBase[j];
		parr->pBase[j] = t;
		++i;
		--j;
	}
	return;
}

这个在之前介绍过了,很简单不多说

排序
无论是简单选择还是冒泡抑或是简单+冒泡都可以,

void sort_arr(struct Arr* parr)
{	
	int i, j,t;
	for (i = 0; i < parr->cnt-1; ++i)
	{
		for (j = i+1; j <= parr->cnt-1;++j)
		{
			if (parr->pBase[i] > parr->pBase[j])
			{
			t = parr->pBase[i];
			parr->pBase[i] = parr->pBase[j];
			parr->pBase[j] = t;
			}
		}
	}
}
//void sort_arr(struct Arr* parr)
//{
//	int i, j, t;
//	for (i = 0; i < parr->cnt - 1; ++i)
//	{
//		for (j = i; j < parr->cnt - 1-i; ++j)
	//	{
	//		if (parr->pBase[i] > parr->pBase[j+1])
	//		{
	//			t = parr->pBase[i];
	//			parr->pBase[i] = parr->pBase[j+1];
	//			parr->pBase[j+1] = t;
//			}
	//	}
//	}
//}
//void sort_arr(struct Arr* parr)
//{
	//int i, j, t;
//	for (i = 0; i < parr->cnt - 1; ++i)
	//{
	//	for (j = 0; j < parr->cnt - 1 - i; ++j)
	//	{
	//		if (parr->pBase[j] > parr->pBase[j + 1])
	//		{
//				t = parr->pBase[j];
	//			parr->pBase[j] = parr->pBase[j + 1];
	//			parr->pBase[j + 1] = t;
	//		}
	//	}
	//}
//}

这个以前的文章中也有,不多说

源码

#include<stdio.h>
#include<malloc.h>
#include<iostream>
#include<ostream>
#include<stdlib.h> //包含了exit函数

struct Arr
{
	int* pBase; //存储的是数组第一个元素的首地址
	int len; //数组所能容纳的最大元素的个数
	int cnt; //当前数组有效元素的个数
	//int increment; //自动增长因子
};
void init_arr(struct Arr * parr,int len);//初始化
bool append_arr(struct Arr * parr,int val);//追加
bool insert_arr(struct Arr* parr, int pos,int val);//插入  pos的值从1开始
bool delete_arr(struct Arr* parr, int pos,int*pval);//删除  考率
bool is_empty(struct Arr* parrempty);//判断是否为空
bool is_full(struct Arr* parr);//判断是否满
void sort_arr(struct Arr* parr);//排序
void show_arr(struct Arr*parrshow);//输出
void inversion_arr(struct Arr* parr);//倒置

int main(void)
{
	struct Arr arr;
	int len = 6;
	int val;

	init_arr(&arr,len);
	show_arr(&arr);//输出
	//printf("%d", arr.len);
	append_arr(&arr, 44);
	append_arr(&arr, 21);
	append_arr(&arr, 111);
	append_arr(&arr, 3);
	//append_arr(&arr, 5);
	if (append_arr(&arr, 66))
		printf("追加成功\n");
	else
		printf("追加失败\n");
	//插入
	insert_arr(&arr, 1, 99);

	if (append_arr(&arr, 7))
		printf("追加成功\n");
	else
		printf("追加失败\n");
	insert_arr(&arr, 3, 199);
	if (delete_arr(&arr, 1, &val))
	{
		printf("删除成功,,您删除的元素是%d\n",val);
	}
	else
		printf("删除失败了个球的\n");
	if (delete_arr(&arr, 5, &val))
	{
		printf("删除成功,,您删除的元素是%d\n", val);
	}
	else
		printf("删除失败了个球的\n");
	if (delete_arr(&arr, 5, &val))
	{
		printf("删除成功,,您删除的元素是%d\n", val);
	}
	else
		printf("删除失败了个球的\n");
	//append_arr(&arr, 7);
	show_arr(&arr);//输出
	inversion_arr(&arr);//倒置
	show_arr(&arr);//输出
	sort_arr(&arr);//排序
	show_arr(&arr);//输出
	return 0;
}
void init_arr(struct Arr* parr,int len) //初始化结构体
{
	//parr->len=99;
	parr->pBase = (int*)malloc(sizeof(int) * len);
	if (NULL == parr->pBase)
	{									
		printf("动态内存分配失败");
		exit(-1);  //终止整个程序
	}
	else
	{
		parr->cnt = 0;
		parr->len = len;
	}
	return;
}
void show_arr(struct Arr* parrshow) //输出数组
{
	if (is_empty(parrshow))
		printf("数组为空\n");
	else
	{
		//printf("%d %d %s", parrshow->cnt, parrshow->len, parrshow->pBase);
		for (int i = 0; i < parrshow->cnt; ++i)
		{
			//printf("%d", *(parrshow[i].pBase));
			printf("%d\t", (parrshow->pBase)[i]);
			//printf("%d", parrshow->pBase[i]);--ok
		}
	}
	printf("\n");
}
bool is_empty(struct Arr* parrempty)//判断是否为空
{
	if (0 == parrempty->cnt)
		return true;
	else
		return false;
}
bool append_arr(struct Arr* parr, int val)//往数组中追加数据 
{
	//满时返回false
	if (is_full(parr))
		return false;
	else//不满时追加     
	{
		parr->pBase[parr->cnt] = val;
		parr->cnt ++;
		return true; //表示往里面添加元素成功
	}
}
bool is_full(struct Arr* parr)//判断数组是否满
{
	//不够好的代码
	//if (parr->cnt == parr->len)
	//		return true;
	//else
	//		return false;

	return(parr->cnt == parr->len);
}
bool insert_arr(struct Arr* parr, int pos, int val)
{
	if (is_full(parr) || pos<1 || pos>parr->cnt+1) //
		return false;
	else
	{
		int i;
		for (i = parr->cnt - 1;i>=pos-1;--i)
		{
			parr->pBase[i+1] = parr->pBase[i];
		}
		parr->pBase[pos - 1] = val;
		parr->cnt++;
		return true;
	}
}
bool delete_arr(struct Arr* parr, int pos, int* pval)
{
	if (is_empty(parr) || pos<1 || pos>parr->cnt)
		return false;
	else
	{
		*pval = parr->pBase[pos - 1];
		for (int i = pos; i < parr->cnt; ++i)
		{
			parr->pBase[i - 1] = parr->pBase[i];

		}
		parr->cnt--;
		return true;
	}
}
void inversion_arr(struct Arr* parr)
{	
	int i = 0;
	int j = parr->cnt - 1;
	int t;
	while (i < j)
	{
		t = parr->pBase[i];
		parr->pBase[i] = parr->pBase[j];
		parr->pBase[j] = t;
		++i;
		--j;
	}
	return;
}
//冒泡排序的三种写法(实质两种)
void sort_arr(struct Arr* parr)
{	
	int i, j,t;
	for (i = 0; i < parr->cnt-1; ++i)
	{
		for (j = i+1; j <= parr->cnt-1;++j)
		{
			if (parr->pBase[i] > parr->pBase[j])
			{
			t = parr->pBase[i];
			parr->pBase[i] = parr->pBase[j];
			parr->pBase[j] = t;
			}
		}
	}
}
//void sort_arr(struct Arr* parr)
//{
//	int i, j, t;
//	for (i = 0; i < parr->cnt - 1; ++i)
//	{
//		for (j = i; j < parr->cnt - 1-i; ++j)
	//	{
	//		if (parr->pBase[i] > parr->pBase[j+1])
	//		{
	//			t = parr->pBase[i];
	//			parr->pBase[i] = parr->pBase[j+1];
	//			parr->pBase[j+1] = t;
//			}
	//	}
//	}
//}
//void sort_arr(struct Arr* parr)
//{
	//int i, j, t;
//	for (i = 0; i < parr->cnt - 1; ++i)
	//{
	//	for (j = 0; j < parr->cnt - 1 - i; ++j)
	//	{
	//		if (parr->pBase[j] > parr->pBase[j + 1])
	//		{
//				t = parr->pBase[j];
	//			parr->pBase[j] = parr->pBase[j + 1];
	//			parr->pBase[j + 1] = t;
	//		}
	//	}
	//}
//}




  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值