- 长度为n的数组可以分为两段,前面k个元素为一段,后面n-k个元素为另一段。编程交换两组元素的位置,交换之后每一组内部元素的相应位置保持不变。
- 例如: a ={1,2,3,4,5,6,7,8} , k=3, 两组交换之后的数组变成:
- a = {4,5,6,7,8,1,2,3}
算法1:使用临时数组
1、将数组a中的第一段 (用a[0 ~ k-1]表示)拷贝到临时数组 t 中。
for(i = 0; i < k; i++)
t[i] = a[i];
2、把数组a中的第二段 (用a[k ~ n-1] 表示)向前移动 k 个元素。
for(i = k; i < n; i++)
a[i-k] = a[i];
3、把数组 t 的元素拷贝到数组a的后面k个位置(a[k ~ n-1])
for(i = 0; i < k; i++)
a[n-k+i] = t[i];
使用函数封装:
//算法1:使用临时数组
void array_swap1(int a[], int n, int k)
{
int t[50]; //临时数组
int i;
for(i = 0; i < k; i++)
t[i] = a[i];
for(i = k; i < n; i++)
a[i-k] = a[i];
for(i = 0; i < k; i++)
a[n-k+i] = t[i];
}
算法2:数组元素逆序法
对数组a={1,2,3,4,5,6,7,8},以k=3为分界点,分成两段,对第一段和第二段分别逆序。
对第一段,第二段进行逆序: a1= {3,2,1,8,7,6,5,4}
再对a1整体进行逆序得: a2 = {4,5,6,7,8,1,2,3}
所以,首先需要 实现 逆序数组 a 中指定区间a[l] ~ a[h]的元素。
//功能:逆序数组a中指定区间a[l]~a[h]的元素
void array_reverse(int a[], int l, int h)
{
int t;
while(l < h)
{
t = a[l];
a[l] = a[h];
a[h] = t;
l++;
h--;
}
}
//算法2:数组元素逆序法
void array_swap2(int a[], int n, int k)
{
array_reverse(a, 0, k-1); //对第一段逆序
array_reverse(a, k, n-1); //对第二段逆序
array_reverse(a, 0, n-1); //对整个数组逆序
}
全部代码如下:
#include <stdio.h>
#include <stdlib.h>
//算法1:使用临时数组
void array_swap1(int a[], int n, int k)
{
int t[50]; //临时数组
int i;
for(i = 0; i < k; i++)
t[i] = a[i];
for(i = k; i < n; i++)
a[i-k] = a[i];
for(i = 0; i < k; i++)
a[n-k+i] = t[i];
}
//功能:逆序数组a中指定区间a[l]~a[h]的元素
void array_reverse(int a[], int l, int h)
{
int t;
while(l < h)
{
t = a[l];
a[l] = a[h];
a[h] = t;
l++;
h--;
}
}
//算法2:数组元素逆序法
void array_swap2(int a[], int n, int k)
{
array_reverse(a, 0, k-1); //对第一段逆序
array_reverse(a, k, n-1); //对第二段逆序
array_reverse(a, 0, n-1); //对整个数组逆序
}
int main()
{
int a[8] = {1,2,3,4,5,6,7,8};
int i;
//array_swap1(a, 8, 3);
//array_swap2(a, 8, 3);
for (i = 0; i < 8; i++)
printf("%d ", a[i]);
return 0;
}