重学java-6.常用的数组排序【1】

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/euzmin/article/details/88595610

常用的数组排序

这一篇主要讲 基础 的交换排序、选择排序、插入排序。

如果文字描述使我们迷惑,直接看代码或许是个更为明智的选择。

排序算法比较表格

在这里插入图片描述
图片来自 该博文,里面有算法实现的gif图,向大家安利一下。
该博文 关于各类算法的时间复杂度讲得比较细。

基础交换排序-冒泡排序

  • 思路:

假设一个无序的array数组含n个元素,使其变为升序。

我们只需要遍历 n - 1 次数组,每次遍历时,比较第 j 个数与第 j + 1 个数的大小,若array[j] > array[j + 1],则交换二者的值。

因而每一次遍历的效果就是把最大值放在了最后面。这样,经过n - 1 次遍历,就完成了数组从小到大的排序。

举个生活中例子:

给我们5张无序的卡片,上面分别写着1,2,3,4,5这五个数字。将其从小到大排列。
1. 我们从左向右观察这5张卡片。
2. 比较第一张卡片与第二张卡片。如果第一张比第二张卡片大,我们就调换这两张卡片的顺序,否则不动。
3. 继续向右观察观察第二张卡片与第三张卡片,重复2的操作。直到第一次观察结束,最后一张卡片一定是5。
4. 再观察前四张卡片,重复上述行为后,第四张卡片一定是4。
5. 重复上述行为,则完成排序。

  • 核心代码:
public static void bubSort(int array[]) { // 冒泡排序
		for(int i = 0; i < array.length - 1; ++i) {
			for(int j = 0; j < array.length - i - 1; ++j) {
				if(array[j] > array[j + 1]) {
					swap(array, j, j + 1);
				}	
			}
		}
		print(array);
	}
public static void swap(int array[], int i, int j) {
		if(i == j) return ;
		array[i] ^= array[j];
		array[j] ^= array[i];
		array[i] ^= array[j];
	}
	public static void print(int array[]) {
		System.out.println(Arrays.toString(array));
	}
  • 测试代码:
public static void main(String[] args) {
		int array[] = new int[] {7, 3, 4, 5, 1, 2, 6, 9 ,8, 0};
		bubSort(array);
	}
  • 输出结果:
    在这里插入图片描述
  • 简单优化
    上述的冒泡排序,最优的时间复杂度也是O( n 2 n^2 ),我们可以进行一个简单的优化,设置一个flag,如果第一遍内部循环发现没有进行交换,说明数组本身就已经是有序的,直接break就行。这时的最优时间复杂度就是O(n)了。
    因为比较简单,在这里不给出代码实现。

基础选择排序

  • 思路:
    假设一个无序的array数组含n个元素,使其变为升序。

我们只需要遍历 n - 1 次数组,每次遍历时,找到它们的最大值,将最大值的位置与最后面的数的位置交换。
因而每一次遍历的效果就是把最大值放在了最后面。这样,经过n - 1 次遍历,就完成了数组从小到大的排序。

举个生活中例子:

给我们5张无序的卡片,上面分别写着1,2,3,4,5这五个数字。将其从小到大排列。

  1. 首先,我取出第一张卡片,放在手里。
  2. 然后,我取出第二张卡片,比较其与第一张卡片的值,将较小者放置一边,较大者拿在手中。
  3. 重复2操作,直到所有卡都被比较了一遍,而这时握在手里的肯定是5。
  4. 我们把手中的5当做已经排好顺序的卡片,放在最右边,再从剩下的4张卡中抽出一张卡拿在手中,重复上述操作后,新筛出来的卡一定是4。把4放在5的左边。这时,我们已经完成了4与5的排序。
  5. 重复上述操作,即可完成5张卡片的排序。
  • 核心代码:
public static void selectSort(int array[]) {
		for(int i = 0; i < array.length - 1; ++ i) {
			int minn = i;
			for(int j = i + 1; j < array.length; ++ j) {
				if(array[minn] > array[j]) {
					minn = j;
				}
			}
			if(minn != i) {
				swap(array, minn, i);
			}
			
		}
		print(array);
	}
public static void swap(int array[], int i, int j) {
		if(i == j) return ;
		array[i] ^= array[j];
		array[j] ^= array[i];
		array[i] ^= array[j];
	}
	public static void print(int array[]) {
		System.out.println(Arrays.toString(array));
	}
  • 测试代码:
public static void main(String[] args) {
		int array[] = new int[] {7, 3, 4, 5, 1, 2, 6, 9 ,8, 0};
		selectSort(array);
	}
  • 输出结果:
    在这里插入图片描述

直接插入排序

  • 思路:
    插入排序的思路和我们平时斗地主时捋牌的思路是完全一样的。
    比如现在我手里的牌为4,6,7,5。
    要让他顺序排列的话,我会把5抽出来,让6和7往后稍稍,给5腾出位置,再把5插进去。
    这就是插入排序的一次循环。
    而放在计算机中实现,就是外层一个for循环,表示当前要插入的值x,内层的for循环,遍历x的前面,比x大的都后移一位,给x腾出位置,遇到比x小的,就停止循环,把x插在比其小的值后面。

  • 核心代码:

public static void insertionSort(int array[]) {
		for(int i = 1; i < array.length; i += 1) {
			int u = array[i], j;
			for(j = i - 1; j >= 0 && array[j] > u; j -= 1) {
				array[j + 1] = array[j];
			}
			array[j + 1] = u;
		}
		print(array);
	}
  • 测试代码:
public static void main(String[] args) {
		int array[] = new int[] {7, 3, 4, 5, 1, 2, 6, 9 ,8, 0};
		insertionSort(array);
	}
  • 输出结果:
    在这里插入图片描述
  • 注意:
    在插入排序时,有将当前值插入到一个有序数列的过程,这个时候我们应该可以想到二分。但因为优化有限,这里不展开篇幅去描述,感兴趣的可以试试。

计数排序

该博客 用漫画描述该算法非常生动,安利一波。

前人之述备矣,我暂时想不到别的讲解方法,在这里就只贴代码了(建议看完上面博客后再看代码)。

public static void main(String[] args) {
		int a[] = {1,5,4};
		int minn = a[0], maxx = a[0];
		
		for(int i = 0; i < a.length; ++i) {//找到最大值和最小值
			minn = Math.min(a[i], minn);
			maxx = Math.max(a[i], maxx);
		}
		int len = maxx -minn + 1;//[最大值,最小值]这个区间的长度足以记录所有的数
		
		int count[] = new int[len];//定义一个数组,count[i]表示值为minn+i的数在排序后的最末排名。
		//比如1 2 4 4 ,count[3] 就表示值为4的数在排序后的最末排名
		for(int i = 0; i < a.length; ++i) {//先求出每个数出现的次数
			++count[a[i]-minn];
		}
	
		for(int i = 1; i < count.length; ++i) {//求出前缀和
			count[i] += count[i - 1];
		}
		
		int ans[] = new int[a.length];//记录排序后的数组
		
		for(int i = a.length - 1; i >= 0; --i) {//倒序输出,排序稳定
			
			int pos = count[a[i] - minn] - 1;//注意位置是排名+1
//			/System.out.println(pos);
			ans[pos] = a[i];
			--count[a[i]-minn];
		}
		System.out.println(Arrays.toString(ans));
	}

猜你喜欢

转载自blog.csdn.net/euzmin/article/details/88595610
今日推荐