题目详情:
给定一个包含1-n的数列,我们通过交换任意两个元素给数列重新排序。求最少需要多少次交换,能把数组排成按1-n递增的顺序,其中,数组长度不超过100。
例如:
原数组是3,2,1, 我们只需要交换1和3就行了,交换次数为1,所以输出1。
原数组是2,3,1,我们需要交换2和1,变成1,3,2,再交换3和2,变为1,2,3,总共需要的交换次数为2,所以输出2。
题目解析:
要求序列结果为升序,所以序列第一个数最小,最后一个元素最大,以此类推。操作的过程中只需要循环遍历序列,把最小的数放到第一个位置,依次比较并交互元素位置即可。
操作代码:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define RET_VAL_IF_FAIL(p, val) if(!(p)) {printf("Warning: %s. %d "#p" failed\n", __func__, __LINE__); \
return(val);}
typedef enum tagRET_E
{
RET_FAIL = -1,
RET_INVALID_PARAM,
RET_OK,
RET_OOM
}RET_E;
int run(const int *a,int n)
{
int nSwapCount = 0;
int nIndex1 = 0;
int nIndex2 = 0;
int nTempVal = 0;
int nMaxIdx = 0;
RET_VAL_IF_FAIL(a != NULL && n > 0, RET_FAIL);
int *temp_array = (int*)malloc(sizeof(int) * n);
if(temp_array == NULL)
{
return (RET_FAIL);
}
memcpy(temp_array, a, sizeof(int) * n);
for(nIndex1 = n - 1; nIndex1 > 0; nIndex1--)
{
nTempVal = temp_array[nIndex1];
nMaxIdx = nIndex1;
for(nIndex2 = 0; nIndex2 < nIndex1; nIndex2++)
{
if(temp_array[nIndex2] > temp_array[nMaxIdx])
{
nMaxIdx = nIndex2;
}
}
if(nIndex1 != nMaxIdx)
{
++nSwapCount;
temp_array[nIndex1] = temp_array[nMaxIdx];
temp_array[nMaxIdx] = nTempVal;
}
}
free(temp_array);
temp_array = NULL;
return(nSwapCount);
}
int main()
{
int nIndex = 0;
int a[][3] = {{1,2,3},{3,2,1},{2,3,1}};
int nRetVal = 0;
for(nIndex = 0; nIndex < sizeof(a) / sizeof(a[0]); nIndex++)
{
nRetVal = run(a[nIndex], sizeof(a[0]) / sizeof(a[0][0]));
printf("nRetVal = %d\n", nRetVal);
}
}
测试结果:
lc@lc-Lenovo:~/work/ProgramTrain$ gcc array_sort.c
lc@lc-Lenovo:~/work/ProgramTrain$ ./a.out
nRetVal = 0
nRetVal = 1
nRetVal = 2