考研数据结构之线性表(1.6)——逆置问题(C表示)

题目

将数组中的元素(X1,X2,...,Xn-1)经过移动后变为(Xp,Xp+1,...,Xn-1,X0,X1,..,Xp-1),即循环左移p(0<p<n)个位置。设计算法来解决这个问题。

分析

如有数组[1,2,3,4,5,6,7]将其循环左移3个位置后变成[4,5,6,7,1,2,3]

下面是上面图片的代码实现:


#include <stdio.h>

/* 将数组指定个元素逆序 */
/* a[]指的是是要逆置的数组;left指的是起始下标;right指的是结束下标;k指的是要逆置的数组元素个数 */
void reverse(int a[],int left,int right,int k) {
	int temp,count=0;// 临时变量,用来临时存储数组中的变量值
//	for(int i=left,j=right;i<left+k&&i<j;i++,j--){ // 这是参考书上的写法,感觉理解有些困难
	for(int i=left,j=right; count<k/2; i++,j--,count++) { // 这种写法理解起来相对容易些
		temp=a[j];
		a[j]=a[i];
		a[i]=temp;
	}
}

void printArray(int a[],int n) {
	printf("\n");
	for(int i=0; i<n; i++) {
		printf("%d\t",a[i]);
	}
	printf("\n");
}

/* 主函数:测试结果 */
int main() {
	/* 创建一个测试数组 */
	int a[]= {1,2,3,4,5,6,7};
	printArray(a,7);

	/* 首先翻转123 */
	reverse(a,0,2,3);
	printArray(a,7);

	/* 接着翻转4567 */
	reverse(a,3,6,4);
	printArray(a,7);

	/* 最后翻转整个数组 */
	reverse(a,0,6,7);
	printArray(a,7);

	return 0;
}

运行效果如下:

总结

给定一个线性表,将其中的元素逆置:设置两个整型变量i和j,i指向第一个元素,j指向最后一个元素,边交换i和j的元素,边让i和j相向而行,直到相遇。核心代码如下:

for(int i=left,j=right; i<j; i++,j--) {
		temp=a[j];
		a[j]=a[i];
		a[i]=temp;
	}

不过本题的代码整理总结如下:


#include <stdio.h>

/* 将数组指定个元素逆序 */
/* a[]指的是是要逆置的数组;left指的是起始下标;right指的是结束下标;k指的是要逆置的数组元素个数 */
void reverse(int a[],int left,int right,int k) {
	int temp,count=0;// 临时变量,用来临时存储数组中的变量值。其中temp是用来临时保存i或j的,其中count是计数器,记录循环次数
//	for(int i=left,j=right;i<left+k&&i<j;i++,j--){ // 这是参考书上的写法,理解有些困难
	for(int i=left,j=right; count<k/2; i++,j--,count++) { // 感觉这样写理解容易些,两句效果一样
		// 交换a[i]和a[j]的值
		temp=a[j];
		a[j]=a[i];
		a[i]=temp;
	}
}

/* 打印数组元素 */
/* a[]指的是要被打印输出的数组;n指的是数组中的元素个数 */
void printArray(int a[],int n) {
	printf("\n");
	for(int i=0; i<n; i++) {
		printf("%d\t",a[i]);
	}
	printf("\n");
}

/* 主函数:测试结果 */
int main() {
	int num,move;// 两个变量,num用来保存用户输入的数组长度,move用来保存用户输入的移动几个位置
	printf("请输入数组元素的个数:");
	scanf("%d",&num); // 获取用户输入的num
	int a[num];
	for(int i=0; i<num; i++) { // 循环输入数组元素
		scanf("%d",&a[i]);
	}
	printArray(a,num);// 打印数组

	printf("请输入循环左移多少个位置:");
	scanf("%d",&move); // 获取用户输入的move
	if(move<0||move>=num) { // 判断用户输入的move是否合法
		printf("输入的移动位置不合法!");
	} else {
		reverse(a,0,move-1,move);// 逆置a[0]-a[move-1]
		reverse(a,move,num-1,num-move);// 逆置a[move]-a[num-1]
		reverse(a,0,num-1,num);// 逆置a[0]-a[num-1]
	}
	printArray(a,num);// 打印逆置后的数组

	return 0;
}

测试效果如下:

我觉得使用while循环更好理解些,代码更加易懂。

#include <stdio.h>

void printArray(int a[],int n) {
	printf("\n");
	for(int i=0; i<n; i++) {
		printf("%d\t",a[i]);
	}
	printf("\n");
}

/***** 核心代码 0  *****/ 
// 逆置数组中指定范围内的元素,其中arr指的是是要进行操作的数组,start是开始下标,end是结束下标 
void reverse(int arr[],int start, int end)
{
	int temp;
	while(start<end)
	{
		temp=arr[start];
		arr[start]=arr[end];
		arr[end]=temp;
		start++;
		end--;
	}
}
/***** 核心代码 1  *****/ 

int main()
{
	// 循环左移k个位置
	int arr[]={1, 2, 3, 4, 5, 6, 7};
	int length=7;
	int k=1;
	printArray(arr,length);
	
	/***** 核心代码 0  *****/ 
	reverse(arr,0,k-1);
	reverse(arr,k,length-1);
	reverse(arr,0,length-1);
	/***** 核心代码 1  *****/ 
	printArray(arr,length);

	return 0;	
} 

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值