数组换位问题-比较容易理解的解法

上一篇数组换位问题的博客,是网上搜的,自己虽然过了一遍,但是还是理解起来有困难。上次上机课,老师给我们提示了另一新颖的解法,自己下来实现了,发此博客记录一下。

算法一:三次反转算法

主要思想:设a[0, k-1]位U,a[k, n-1]为V,换位算法要求将UV变为VU。三次反转先将U反转为U¯¹,再将V反转为V¯¹,最后将U¯¹V¯¹反转为VU。

    例如:1 2 3 4 5 6 7 阶段为位置k=2,所以,左边互换为2 1,右边互换为7 6 5 4 3,最后整体互换为3 4 5 6 7 1 2.

代码如下:

#include <stdio.h>

void swap(int *a, int *b) {
	int temp;
	
	temp = *a;
	*a = *b;
	*b = temp;
}

void reverse(int a[], int i, int j) {
	while(i < j) {
		swap(&a[i], &a[j]);
		i++;
		j--;
	}
}

void move(int a[], int n, int k) {
	reverse(a, 0, k-1);
	reverse(a, k, n-1);
	reverse(a, 0, n-1);
}

int main() {
    int i;
    int k;
    int n;

	scanf("%d", &n);	//输入数组长度 
	int a[n];
    for(i = 0; i < n; i++) {
    	scanf("%d", &a[i]);		//输入数组元素 
    }
	scanf("%d", &k);	//输入截断位置

	move(a, n, k);
    
    printf("\n");
	for(i = 0; i < n; i++) {
    	printf("%d ", a[i]);
    }
    
    return 0;
}



算法二:循环换位算法(平移法)

主要思想:如果k左边的元素个数少于右边的元素个数,则向前循环换位。否则,向后循环换位。

代码如下:

#include <stdio.h>

int temp;
//向前循环换位 
void forward(int a[], int n, int k) {
	int i, j;
	
	for(i = 0; i < k; i++) {
		temp = a[0];
		for(j = 1; j < n; j++) {
			a[j-1] = a[j];
		}
		a[n-1] = temp;
	}
}

//向后循环换位 
void backward(int a[], int n, int k) {
	int i, j;
	
	for(i = k; i < n; i++) {
		temp = a[n-1];
		for(j = n-1; j > 0; j--) {
			a[j] = a[j-1];
		}
		a[0] = temp;
	}
}

//选择移动较少的数组块进行循环
void move(int a[], int n, int k) {
	if(k > n-k) backward(a, n, k);
	else forward(a, n, k);
} 

int main() {
	int i, n, k;
	
    scanf("%d", &n);	//输入数组长度 
	int a[n];
    for(i = 0; i < n; i++) {
    	scanf("%d", &a[i]);		//输入数组元素 
    }
	scanf("%d", &k);	//输入截断位置
	
	move(a, n, k);
	
	printf("\n");
	for(i = 0; i < n; i++) {
    	printf("%d ", a[i]);
    }
	
    return 0;
}

在最坏的情况下,算法所需的元素移动次数为min{k, n-k}×(n+1)。算法进用到一个辅助空间temp。

猜你喜欢

转载自blog.csdn.net/weixin_38214171/article/details/79875448