码迷,mamicode.com
首页 > 编程语言 > 详细

用分解的方式学算法001——选择排序

时间:2018-04-11 11:37:18      阅读:237      评论:0      收藏:0      [点我收藏+]

标签:ret   重复   rgs   思路   out   循环   rate   pac   pack   

我们在学习算法时,经常遇到的一个问题是,看的懂但是写不出来。究其原因,是没有理解到位。

那么怎么才能理解到位呢?我认为关键是“分解”,就是把算法中的节点按层次和步骤分解出来。

一步一步的实现。

今天先来分解一下排序算法中的一个算法——选择排序。

为什么叫选择排序呢?

一种最简单的排序算法是这样的:首先,找到数组中最小的那个元素,其次,将它和数组的第一个元素交换位置(如果第一个元素就是最小的元素那么它就和自己交换)。再次,在剩下的元素中找到最小的元素,将它与数组的第二个元素交换位置。如此往复,直到将整个数组排序。这种方法叫做选择排序。

可以发现,选择排序的关键点就是选择“最小值”。这个名称,就是这个算法的核心思想。我们先来看一个完整的算法的实现。

        ///选择排序
	public static void SelectSort0(int[] a){
		int min=0;
		for(int i=0;i<a.length;i++){
			min=i;
			for(int j=i+1;j<a.length;j++){
				if(a[min]>a[j]){
					min=j;
				}
			}
			int tmp=0;
			tmp=a[i];
			a[i]=a[min];
			a[min]=tmp;
		}
		
		for(int i=0;i<a.length;i++){
			System.out.print(a[i] + " ");
		}
	}

 这个算法,看完之后比较容易懂,但是不好记。下面我就用分解的方式来对这个算法进行拆解。

第一步:找最小值(索引)

给定一个数组,从中找到第一次出现的最小的值(其索引),这个算法要如何实现呢?

我想用一个循环就可以搞定,代码如下:

	public static int FindMinIndex(int[] a){
		int min=0;
		for(int i=0;i<a.length;i++){
			if(a[min]>a[i]){
				min=i;
			}
		}
		return min;
	}

 

选择排序的思想就是每次遍历,找到当先序列的最小的索引,和当前的起始索引的元素进行交换。

因此我们需要一个可以自己指定“起始索引”的重载版本:

	public static int FindMinIndex(int[] a,int beginIndex){
		int min=beginIndex;
		for(int i=beginIndex;i<a.length;i++){
			if(a[min]>a[i]){
				min=i;
			}
		}
		return min;
	}

 其中,第二个参数,是数组a的起始遍历的索引。

 

第二步:交换索引元素

这个很简单,直接上代码

	public static void Exchange(int[] a,int i,int j){
		int temp=a[i];
		a[i]=a[j];
		a[j]=temp;
	}

 

第三步:进行组合

在选择排序的主方法中,对数组进行一次遍历。每次遍历,找到最小的值的元素对应的索引,和当前的起始索引的元素进行交换。遍历完毕,则数组排序完毕。

	public static void SelectSort(int[] a){
		for(int i=0;i<a.length;i++){
			int beginIndex=i;
			int min = FindMinIndex(a,beginIndex);
			Exchange(a,min,i);
		}
	}

 完整代码如下:

package asen.yang;

public class selectSort {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		int[] a={5,1,4,8,3,9,0,2,7,6,1,2,5};
		
		SelectSort(a);
		for(int i=0;i<a.length;i++){
			System.out.print(a[i]+ " ");
		}
	}
	
	
	public static int FindMinIndex(int[] a){
		int min=0;
		for(int i=0;i<a.length;i++){
			if(a[min]>a[i]){
				min=i;
			}
		}
		return min;
	}
	
	public static int FindMinIndex(int[] a,int beginIndex){
		int min=beginIndex;
		for(int i=beginIndex;i<a.length;i++){
			if(a[min]>a[i]){
				min=i;
			}
		}
		return min;
	}
	
	public static void Exchange(int[] a,int i,int j){
		int temp=a[i];
		a[i]=a[j];
		a[j]=temp;
	}
	
	public static void SelectSort(int[] a){
		for(int i=0;i<a.length;i++){
			int beginIndex=i;
			int min = FindMinIndex(a,beginIndex);
			Exchange(a,min,i);
		}
	}
	
	///选择排序
	public static void SelectSort0(int[] a){
		int min=0;
		for(int i=0;i<a.length;i++){
			min=i;
			for(int j=i+1;j<a.length;j++){
				if(a[min]>a[j]){
					min=j;
				}
			}
			int tmp=0;
			tmp=a[i];
			a[i]=a[min];
			a[min]=tmp;
		}
		
		for(int i=0;i<a.length;i++){
			System.out.print(a[i] + " ");
		}
	}

}

 在学习算法时,如果对最终的代码记不清楚,那可以尝试使用分解的方式,记住其关键点。然后再组合。

而对于向排序这样的经典算法,几乎所有的开发语言的类库中都已经实现了。我们学习的目的,并不仅仅是重复已经实现的东西,更重要的是在学习中,掌握思想。而思想,更多的体现在其中的关键点上。因此对算法进行分解,找准关键点,理解核心思想,才是学习算法时,所更应该重点关注的角度。

接下来会按照这个思路,进行其他算法的分解。从这个角度,在学习算法的过程中,会有更多的收获。

 

用分解的方式学算法001——选择排序

标签:ret   重复   rgs   思路   out   循环   rate   pac   pack   

原文地址:https://www.cnblogs.com/asenyang/p/8794322.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!