【C 语言之项目实战】循环移动数组(详细版)

目录

1.项目要求
2.定义模块函数
3.各模块函数实现
4.项目源代码

1. 项目要求

1.1 循环移动数组,循环左移一个元素,循环右移一个元素。

1.2 循环左移 k 个元素 ,循环右移 k 个元素。

2. 定义模块函数

2.1 主函数:main()

2.2 打印函数:Print_Array()

2.3 循环左移:Left_Move_Array()

2.4 循环右移:Right_Move_Array()

2.5 逆置法:ReserveArray()

3. 各模块函数实现

3.1 打印函数:Print_Array()

/** 打印函数 */
void Print_Array(int* br, int n)
{
	assert(br != nullptr);
	for (int i = 0; i < n; ++i)
	{
		printf("%4d ", br[i]);
		if ((i + 1) % 10 == 0)			// 10 个元素换行
		{
			printf("\n");
		}
	}
	printf("\n");
}

3.2 逆置法:ReserveArray()

     ①. 算法思想: 逆置法,记录数组的起始位置 left ; 记录数组的末尾位置 right ; left 与 right 互换; 将 left 与 right 进行位置更新,left++,right - -。

     ②. 源程序

/** 交换函数 指针传递 进行交换*/
void Sweap_Int(int* ap, int* bp)
{
	assert(ap != nullptr && bp != nullptr);
	int tmp = *ap;
	*ap = *bp;
	*bp = tmp;
}

/** 逆置法 */
void ReserveArray(int* br, int left, int right)
{
	assert(br != nullptr);
	while (left < right)
	{
		Sweap_Int(&br[left], &br[right]);		// 调用交换函数 进行交换
		left++;
		right--;
	}
	
}

3.3 循环左移:Left_Move_Array()

     ①. 循环左移一位:Left_Move_Array()

     1)算法思想:数组中的数据元素依次向左移动一位,取出第一个元素,循环左移一位,最后将原数组中第一个元素放入到数组末端。

     2)源程序

/** 循环左移一个数据元素 */
void Left_Move_Array(int* br, int n)
{
	assert(br != nullptr && n > 1);		// 数据元素大于 1 进行左移
	int tmp = br[0];					// 取出第一个元素
	for (int i = 0; i < n - 1; ++i)
	{
		br[i] = br[i + 1];				// 循环左移
	}
	br[n - 1] = tmp;					// 将第一个元素放置到数组末端
}

     ②. 循环左移 k 位:Left_Move_Array_k()

     1)算法思想:方法一,调用循环移动一位函数进行移动,此方法算法时间复杂度较高,故采用方法二,通过逆置法进行移动。循环左移 k 个元素,数组前一部分(0 … k - 1)进行逆置,数组后一部分(k … n - 1)进行逆置,最后数组(0 … n - 1)整体逆置。(方法一代码详见项目全部源码,可提供调试,此处不在展示)

     2)源程序

/** 方法二:逆置法 循环左移 k 个元素 */
void Left_Move_Array_k(int* br, int n, int k)
{
	assert(br != nullptr && n > 1);
	ReserveArray(br, 0, k - 1);				// 数组前一部分 0 -- (k - 1) 逆置
	ReserveArray(br, k, n - 1);				// 数组后一部分 k -- (n - 1) 逆置
	ReserveArray(br, 0, n - 1);				// 数组整体逆置
}

3.4 循环右移:Right_Move_Array()

     ①. 循环右移一位:Right_Move_Array()

     1)算法思想:数组中的数据元素依次向右移动一位,取出最后一个元素,循环右移一位,最后将原数组中最后一个元素放入到数组首元素位置。

     2)源程序

/** 循环右移一个数据元素 */
void Right_Move_Array(int* br, int n)
{
	assert(br != nullptr && n > 1);
	int tmp = br[n - 1];				// 取出最后一个元素
	for (int i = n - 1; i > 0; --i)
	{
		br[i] = br[i - 1];				// 循环右移一个元素
	}
	br[0] = tmp;						// 将最后一个元素放置到数组首元素位置
}

     ②. 循环右移 k 位:Right_Move_Array_k()

     1)算法思想:方法一,调用循环移动一位函数进行移动,此方法算法时间复杂度较高,故采用方法二,通过逆置法进行移动。循环右移 k 个元素,数组前一部分(0 … n - k - 1)进行逆置,数组后一部分(n - k … n - 1)进行逆置,最后数组(0 … n - 1)整体逆置。(方法一代码详见项目全部源码,可提供调试,此处不在展示)

     2)源程序

/** 逆置法 循环右移 k 个元素 */
void Right_Move_Array_k(int* br, int n, int k)
{
	assert(br != nullptr && n > 1);			// 数组前一部分 0 -- (n - k - 1) 逆置
	ReserveArray(br, 0, n - k - 1);			// 数组后一部分 (n - k) -- (n - 1) 逆置
	ReserveArray(br, n - k, n - 1);			// 数组整体逆置
	ReserveArray(br, 0, n - 1);
}

3.5 主函数

/** 主函数 */
int main()
{
	const int n = 10;				// 常整型 只可读不可写
	int ar[] = { 12, 23, 34, 45, 56, 67, 78, 89, 90, 100 };

	printf("循环移动之前:\n");
	Print_Array(ar, n);				// 调用打印函数 进行输出打印

	printf("循环左移一位元素之后:\n");
	Left_Move_Array(ar, n);			// 调用左移一位函数 进行数组循环左移一位
	Print_Array(ar, n);

	printf("循环右移一位元素之后:\n");
	Right_Move_Array(ar, n);		// 调用右移一位函数 进行循环数组右移一位
	Print_Array(ar, n);

	printf("循环左移 k 位元素之后:\n");
	Left_Move_Array_k(ar, n, 6);	// 调用左移 k 位函数 进行循环数组左移 6 位
	Print_Array(ar, n);

	printf("循环右移 k 位元素之后:\n");
	Right_Move_Array_k(ar, n, 3);	// 调用右移 k 位函数 进行循环数组右移 3 位
	Print_Array(ar, n);
	return 0;
}

4. 项目源代码

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

/**
* 要求:
* 循环移动数组
* 循环左移一个元素 循环右移一个元素
* 循环左移 k 个元素  循环右移 k 个元素
* 方法一:调用循环移动一位函数进行移动
* 方法二:逆置法 进行移动(提高算法时间复杂度)
*/

/** 循环左移一个数据元素 */
void Left_Move_Array(int* br, int n)
{
	assert(br != nullptr && n > 1);		// 数据元素大于 1 进行左移
	int tmp = br[0];					// 取出第一个元素
	for (int i = 0; i < n - 1; ++i)
	{
		br[i] = br[i + 1];				// 循环左移
	}
	br[n - 1] = tmp;					// 将第一个元素放置到数组末端
}

/** 循环右移一个数据元素 */
void Right_Move_Array(int* br, int n)
{
	assert(br != nullptr && n > 1);
	int tmp = br[n - 1];				// 取出最后一个元素
	for (int i = n - 1; i > 0; --i)
	{
		br[i] = br[i - 1];				// 循环右移一个元素
	}
	br[0] = tmp;						// 将最后一个元素放置到数组首元素位置
}

/** 方法一:效率较低
// 循环左移 k 个元素
void Left_Move_Array_k(int* br, int n, int k)
{
	assert(br != nullptr && n > 1);
	k = k % n;							// 循环左移 3 个元素和循环左移 13 个元素相同
	if (k >= 0)
	{
		while (k--)						// k 大于 0 左移
		{
			Left_Move_Array(br, n);		// 调用循环左移一位函数 进行循环左移 k 个元素
		}
	}
	else								// k 小于 0 右移
	{
		while (k++)
		{
			Right_Move_Array(br, n);    // 调用循环右移一位函数 进行循环右移 k 个元素
		}
	}
}

//循环右移 k 个数据元素
void Right_Move_Array_k(int* br, int n, int k)
{
	assert(br != nullptr && n > 1);
	Left_Move_Array_k(br, n, -k);		// 调用循环左移 k 个元素, k 小于 0 右移 ,k 大于 0 左移
}
*/

/** 交换函数 */
void Sweap_Int(int* ap, int* bp)
{
	assert(ap != nullptr && bp != nullptr);
	int tmp = *ap;
	*ap = *bp;
	*bp = tmp;
}

/** 逆置法 */
void ReserveArray(int* br, int left, int right)
{
	assert(br != nullptr);
	while (left < right)
	{
		Sweap_Int(&br[left], &br[right]);		// 调用交换函数 进行交换
		left++;
		right--;
	}
	
}

/** 方法二:逆置法 循环左移 k 个元素 */
void Left_Move_Array_k(int* br, int n, int k)
{
	assert(br != nullptr && n > 1);
	ReserveArray(br, 0, k - 1);				// 数组前一部分 0 ... (k - 1) 逆置
	ReserveArray(br, k, n - 1);				// 数组后一部分 k ... (n - 1) 逆置
	ReserveArray(br, 0, n - 1);				// 数组整体逆置
}

/** 方法二:逆置法 循环右移 k 个元素 */
void Right_Move_Array_k(int* br, int n, int k)
{
	assert(br != nullptr && n > 1);			// 数组前一部分 0 ... (n - k - 1) 逆置
	ReserveArray(br, 0, n - k - 1);			// 数组后一部分 (n - k) ... (n - 1) 逆置
	ReserveArray(br, n - k, n - 1);			// 数组整体逆置
	ReserveArray(br, 0, n - 1);
}

/** 打印函数 */
void Print_Array(int* br, int n)
{
	assert(br != nullptr);
	for (int i = 0; i < n; ++i)
	{
		printf("%4d ", br[i]);
		if ((i + 1) % 10 == 0)			// 10 个元素换行
		{
			printf("\n");
		}
	}
	printf("\n");
}

/** 主函数 */
int main()
{
	const int n = 10;				// 常整型 只可读不可写
	int ar[] = { 12, 23, 34, 45, 56, 67, 78, 89, 90, 100 };

	printf("循环移动之前:\n");
	Print_Array(ar, n);				// 调用打印函数 进行输出打印

	printf("循环左移一位元素之后:\n");
	Left_Move_Array(ar, n);			// 调用左移一位函数 进行数组循环左移一位
	Print_Array(ar, n);

	printf("循环右移一位元素之后:\n");
	Right_Move_Array(ar, n);		// 调用右移一位函数 进行循环数组右移一位
	Print_Array(ar, n);

	printf("循环左移六位元素之后:\n");
	Left_Move_Array_k(ar, n, 6);	// 调用左移 k 位函数 进行循环数组左移 6 位
	Print_Array(ar, n);

	printf("循环右移三位元素之后:\n");
	Right_Move_Array_k(ar, n, 3);	// 调用右移 k 位函数 进行循环数组右移 3 位
	Print_Array(ar, n);
	return 0;
}

运行结果
在这里插入图片描述
     循环移动数组改进版《【C 语言之项目实战】循环移动数组(结构体实现)必看》,请点击此处查阅…

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值