题目 长度为n的数组乱序存放着0至n-1. 现在只能进行0与其他数的swap,请设计并实现排序。
【分析】
从相似问题中寻找类似信息
传统的排序算法在这里用不上,但可以借鉴相同的东西。排序的关键是比较,即要确定a与b的位置,需要比较a与b的大小,然后交换。现在只能0与其他数交换,可不可以将0看做一个中介,即作为中转站呢?
将复杂问题简单化,具体化
首先将问题简单化、具体化,可以看到解决问题的思路。将0与3和4排序(初始顺序为2|0|1),如何排序呢?这个情况大家很容易想到,因为最终位置是(0|1|2),我们第一个目的是将2放在最右边,所以需要先将0与1互换,结果为(2|1|0),然后0再与2互换,结果为(0|1|2)。既然我们能排序好一个位置,我们就理由排序好所有数据,剩下的排序与这个步骤一样,所有我们想到可以用递归实现。
回归原问题,总结思路并求解
现在,总结一下上述步骤,使问题一般化:
1)先排序好数组最右边的位置,记为currentIndex,需要做一下事情:2)在排序好数组最右边位置好,就可以排序下一个最大值,即currentIndex-1位置的数字,可以用递归实现,直至currentIndex=0排序结束。
代码实现
在写实现代码前,让我们在看一下题目,看能否找到更多信息,或者这个题目是否有其特殊性。我们看到数组存放的是0至n-1的数字,想到最后排序好的结果是0|1|2|3...,想到什么没?有没有感觉有一种哈希表的类似情况,即排序好的数组下标i放的数字正好是数字i,也就是如果i刚好在数组i处,就不用交换了,因为它已经在它所在的位置处了。从这里我们可以看到做事情的过程中要想着我们当初做这个事情的目的到底是什么?因为很多人在做事情做就了,就会忘记自己的初始目的,而走弯路。
//-----------------------------------------------------------------------------
public Class SwapSort{
private int[] arr; //定义一个要排序的数组的全局变量
//构造函数
public SwapSort(int[] arr){
this.arr=arr;
}//end SwapSort()
public int[] sort(){
//输入控制
if(arr==null)
return null;
//因为该排序算法,至少需要3个数才能排序,如果数组只有2个数,直接排序就可以了
int length=arr.length;
if(length<3){
sortSmall();
}//end if
else{
sort(0,length);
}//end else
return all;
}//end sort()
//-------------------------------------------------
//private method
//-------------------------------------------------
/**
*只排序少于3个元素数组
*/
private void sortSmall(){
if(arr.length==1)
return arr;
if(arr.length==2){
if(arr[0]>arr[1]){
int temp=arr[0];
arr[0]=arr[1];
arr[1]=temp;
}//end if
}//end if
}//end sortSmall()
/**
* 排序多于3个元素的数组
* @parm currentIndex 当前需要排序的数字的位置,zeroIndex所在数组的位置
*/
private void sort(int currentIndex,int zeroIndex){
//base case
if(currentIndex==1)
return arr;
if(arr[currentIndex]==currentIndex) //如果i刚好在i处,就不用交换了
swap(currentIndex-1,zeroIndex);
else{
int maxIndex=getMaxIndex(currentIndex); //获取当前最大值的位置
zeroIndex=swap(zeroIndex,maxIndex,currentIndex,); //交换后记录下0所在的位置,注意JAVA是值传递,函数内部对形参zeroIndex的修改不会传给实参zeroIndex,这里通过返回值保存修改后zeroIndex的值
sort(currentIndex-1,zeroIndex); //递归
}//end else
}//end sort()
/**
* 获取数组[0,currentIndex]中最大的那个数字位置
* @return 返回最大值所在位置
*/
private int maxIndex(int curretIndex){
int maxIndex=currentIndex;
for(int i=0;i<currentIndex;i++){
if(a[maxIndex]<arr[i])
maxIndex=i;
}//end for
return maxIndex;
}//end maxIndex()
/**
* 用0作为中介进行交换
* @zeroIndex 0所在位置
* @maxIndex 数组[0,currentIndex]中最大的那个数字位置
*/
private int swap(int zeroIndex,int maxIndex,int currentIndex){
//swap zero with current
arr[currentIndex]=arr[zeroIndex];
arr[currentIndex]=0;
//swap current with max
arr[currentIndex]=arr[maxIndex];
arr[maxIndex]=0;
return maxIndex; //返回0所在的位置
}//end swap()
}//end class
//-----------------------------------------------------------------------------
google2013校招第三道程序设计题