郝斌数据结构-线性表之顺序表程序

前言

以下代码来自于郝斌老师数据结构视频,加以自己的理解作了注释,用于学习和复习,欢迎大家指正错误。
代码的运行环境:DEV-C++ 6.3版本,创建源文件为.cpp文件即可编译运行。

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

//定义了一个数据类型,该数据类型含有三个成员
struct ARR{	
	int *pBase;		//存储数组第一个元素的地址,可以通过下标遍历数组内的每一个元素
	int len;		//数组长度,最大元素个数
	int cnt;		//当前数组有效元素的个数
	//int increment;//自动增长因子、牺牲部分内存,提高存储效率
};

/******************************************************************************************/
/**********---------------------------函数声明部分----------------------------*************/

/******************************************************************************************/
void init_arr(struct ARR *pArr,int length);			//初始化顺序表
bool append_arr(struct ARR *pArr,int val);			//追加数据
bool insert_arr(struct ARR *pArr,int pos,int val);	//插入数据
bool delete_arr(struct ARR *pArr,int pos,int *pVal);//删除指定位置数据
//bool get();
bool is_empty(struct ARR *pArr);		//判断数组是否空
bool is_full(struct ARR *pArr);			//判断数组是否满
void sort_arr(struct ARR *pArr);		//排序数组元素(升序排序)
void show_arr(struct ARR *pArr);		//打印数组元素
void inversion_arr(struct ARR *pArr);	//倒置元素函数(全部倒置)


int main(void){
	struct ARR a;//尚未创建顺序表
	int val;
	
	init_arr(&a,7);//初始化7个数据空间的数组
	//show_arr(&a);
	append_arr(&a,1);
	append_arr(&a,2);
	append_arr(&a,3);
	append_arr(&a,7);
	insert_arr(&a,2,99);
	show_arr(&a);
	if(delete_arr(&a,3,&val)){
		printf("删除成功!\n%d被删除\n",val);
	}
	else{
		printf("删除失败!\n");
	}

//	insert_arr(&a,3,26);
//	if(append_arr(&a,4))
//		printf("追加成功\n");
//	else
//		printf("追加失败\n");
	show_arr(&a);
	inversion_arr(&a);
	show_arr(&a);
	sort_arr(&a);
	show_arr(&a);
	//printf("%d\n",a.len);
}

/******************************************************************************************/
/**********---------------------------函数定义部分----------------------------*************/

/******************************************************************************************/
//结构体变量不能加减乘除,但能相互赋值
/*-------------------------------------
函数功能:初始化数组,分配内存
参数:*pArr---指向结构体数组的指针,存放顺序表(数组)首地址
	length---数组长度(分配内存大小)
	完成动态内存分配
--------------------------------------*/
void init_arr(struct ARR *pArr,int length){
	pArr->pBase = (int *)malloc(sizeof(int)*length);//分配失败malloc会给pBase一个NULL,成功会返回开辟空间的首地址
	//如果动态分配失败,说明pBase是NULL
	if(NULL == pArr->pBase){
		printf("动态分配内存失败!\n");
		exit(-1);//终止整个程序
	}
	else{
		pArr->len = length;
		pArr->cnt = 0;//线性表中有效元素个数为0
	}
	return;//无返回值是告知维护者函数到此终止
}
/*----------------------------------
函数功能:判断数组是否为空
参数:*pArr---指向结构体数组的指针,存放顺序表首地址
	通过有效计数cnt来判断数组是否为空
----------------------------------*/
bool is_empty(struct ARR *pArr){
	if(0 == pArr->cnt)
		return true;
	else
		return false;
}
/*----------------------------------
函数功能:判断数组是否为满
参数:*pArr---
	判断条件;有效计数cnt是否等于数组长度len
----------------------------------*/
bool is_full(struct ARR *pArr){
	//此时说明分配的每个空间都被数据填满
	if(pArr->cnt == pArr->len)
		return true;
	else 
		return false;
}
/*-------------------------------------
函数功能:打印数组内容
参数:*pArr---
-------------------------------------*/
void show_arr(struct ARR *pArr){//取地址操作,pArr已经是顺序表的地址了
	if(is_empty(pArr))//这里填pArr?*pArr?&pArr?第二第三个不对,第二个是地址的指针,不对;第三个对地址再取地址,显然不对
	{
		printf("array is empty!\n");
	}
	else
	{
		for (int i=0;i<pArr->cnt;++i)
			printf("%d ",pArr->pBase[i]);
		printf("\n");
	}	
}
/*------------------------------------------
函数功能:在数组的最后一个有效元素后添加数据
参数:*pArr---
	val---要添加的数据
-------------------------------------------*/
bool append_arr(struct ARR *pArr,int val){
	if(is_full(pArr))//满返回false
		return false;
		//不满时追加
	pArr->pBase[pArr->cnt] = val;	//让结构体中的第cnt个指针地址赋值val
	pArr->cnt++;					//结构体中的cnt++有效个数自增一,不然添加元素不显示
	return 0;
}
/*------------------------------------------------------
函数功能:插入数据
参数:*pArr---结构体指针
		pos---插入位置
		val---插入数据
	注意:在插入数据的位置,
		其后面的所有数据下标增1,移动顺序,末尾的数据先动,依次跟上
--------------------------------------------------------*/
bool insert_arr(struct ARR *pArr,int pos,int val){
	int i;
	if(is_full(pArr)){
		return false;
	}
	if(pos<1||pos>pArr->cnt+1){//+1是因为pos可以设置有效位数的最后一位插入,显然是在数组没有满的前提下
		return false;
	}
	for(i=pArr->cnt-1;i>=pos-1;--i){//在第pos个位置插入数据,对应数组下标pos-1
		pArr->pBase[i+1] = pArr->pBase[i];
	}//先移动,把插入位置的空间腾出来
	pArr->pBase[pos-1] = val;//再赋值,完成数据插入
	pArr->cnt++;			//最后不要忘了有效个数的改变,不然插入一位就会丢失一位
	return true;
}	
/*--------------------------------------
函数功能:删除并返回被删除的数据
参数:*pArr---
		pos---删除位置
	  *pVal---被删除的数据,返回到主函数
----------------------------------------*/
bool delete_arr(struct ARR *pArr,int pos,int *pVal){
	int i;
	if(is_empty(pArr)){//判断数组是否空,要删除的肯定不能是空数组
		return false;
	}
	if(pos<1||pos>pArr->cnt){//删除的只能是已有数据,不能在有效计数外删除
		return false;		//这一点和插入有区别
	}
	//主函数中的实参val等价于pVal形参
	*pVal = pArr->pBase[pos-1];//pos-1为要删除的数据数组下标
	for(i=pos;i<pArr->cnt;++i){
		pArr->pBase[i-1] = pArr->pBase[i];
	}
	pArr->cnt--;
	//删除完之后数组有效个数-1,不然会有一个多余数据
	return true;
}
/*---------------------------
函数功能:倒置元素(逆序输出)
参数:*pArr---
----------------------------*/
void inversion_arr(struct ARR *pArr){
	int i=0;
	int t=0;//中间变量用于过渡
	int j = pArr->cnt-1;//最后一个有效值所在的数组下标
	/*数组个数为奇数,交换到最后一位时i=j
	数组个数为偶数,交换到最后一位时i>j
	取退出循环的条件为i<j*/
	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;
	int t=0;
	for(i=0;i<pArr->cnt;++i){
		for(j=i+1;j<pArr->cnt;++j){
			if(pArr->pBase[i]>pArr->pBase[j]){
				t = pArr->pBase[i];
				pArr->pBase[i] = pArr->pBase[j];
				pArr->pBase[j] = t;
			}
		}
	}	
}
	
	
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值