Java之美[从菜鸟到高手演变]之常见的几种排序算法-插入、选择、冒泡、快排、堆排等 .

Java面试宝典系列之基础排序算法

作者:egg

邮箱:xtfggef@gmail.com

微博:http://weibo.com/xtfggef

博客:http://blog.csdn.net/zhangerqing(转载请说明出处)


本文就是介绍一些常见的排序算法。排序是一个非常常见的应用场景,很多时候,我们需要根据自己需要排序的数据类型,来自定义排序算法,但是,在这里,我们只介绍这些基础排序算法,包括:插入排序、选择排序、冒泡排序、快速排序(重点)、堆排序、归并排序等等。看下图:


给定数组:int data[] = {9,2,7,19,100,97,63,208,55,78}

一、直接插入排序(内部排序、O(n2)稳定)

原理:从待排序的数中选出一个来,插入到前面的合适位置。

  1. package com.xtfggef.algo.sort;  
  2.   
  3. public class InsertSort {  
  4.   
  5.     static int data[] = { 9271910097632085578 };  
  6.   
  7.     public static void insertSort() {  
  8.         int tmp, j = 0;  
  9.         for (int k = 0; k < data.length; k++) {//-----1-----  
  10.             tmp = data[k];  
  11.             j = k - 1;  
  12.             while (j >= 0 && tmp < data[j]) {//-----2-----  
  13.                 data[j + 1] = data[j];  
  14.                 j--;  
  15.             }  
  16.             data[j + 1] = tmp;//------3-------  
  17.         }  
  18.     }  
  19.   
  20.     public static void main(String[] args) {  
  21.         print();  
  22.         System.out.println();  
  23.         insertSort();  
  24.         System.out.println();  
  25.         print();  
  26.     }  
  27.   
  28.     static void print() {  
  29.         for (int i = 0; i < data.length; i++) {  
  30.             System.out.print(data[i] + " ");  
  31.         }  
  32.     }  
  33.   
  34. }  
package com.xtfggef.algo.sort;

public class InsertSort {

	static int data[] = { 9, 2, 7, 19, 100, 97, 63, 208, 55, 78 };

	public static void insertSort() {
		int tmp, j = 0;
		for (int k = 0; k < data.length; k++) {//-----1-----
			tmp = data[k];
			j = k - 1;
			while (j >= 0 && tmp < data[j]) {//-----2-----
				data[j + 1] = data[j];
				j--;
			}
			data[j + 1] = tmp;//------3-------
		}
	}

	public static void main(String[] args) {
		print();
		System.out.println();
		insertSort();
		System.out.println();
		print();
	}

	static void print() {
		for (int i = 0; i < data.length; i++) {
			System.out.print(data[i] + " ");
		}
	}

}
我简单的讲解一下过程:思路上从待排序的数据中选出一个,插入到前面合适的位置,耗时点在插入方面,合适的位置意味着我们需要进行比较找出哪是合适的位置,举个例子:对于 9,2,7,19,100,97,63,208,55,78这组数,第一个数9前面没有,不做操作,当第一个数完后,剩下的数就是待排序的数,我们将要从除去9开始的书中选出一个插入到前面合适的位置,拿到2后,放在tmp上,进行注释中的2处的代码,2处的代码就是通过循环找出这个合适的位置,发现比tmp大的数,立即将该数向后移动一位(这样做的目的是:前面需要空出一位来进行插入),最后通过注释3处的代码将数插入。

 

 

 

 

 

 

 

 

本排序适合:基本有序的数据

二、选择排序(O(n2)、不稳定)
与直接插入排序正好相反,选择排序是从待排序的数中选出最小的放在已经排好的后面,这个算法选数耗时。

  1. package com.xtfggef.algo.sort;  
  2.   
  3. public class SelectSort {  
  4.   
  5.     static int data[] = { 9271910097632085578 };  
  6.   
  7.     public static void selectSort() {  
  8.         int i, j, k, tmp = 0;  
  9.         for (i = 0; i < data.length - 1; i++) {  
  10.             k = i;  
  11.             for (j = i + 1; j < data.length; j++)  
  12.                 if (data[j] < data[k])  
  13.                     k = j;  
  14.             if (k != i) {  
  15.                 tmp = data[i];  
  16.                 data[i] = data[k];  
  17.                 data[k] = tmp;  
  18.             }  
  19.         }  
  20.     }  
  21.     public static void main(String[] args) {  
  22.         print();  
  23.         System.out.println();  
  24.         selectSort();  
  25.         System.out.println();  
  26.         print();  
  27.     }  
  28.   
  29.     static void print() {  
  30.         for (int i = 0; i < data.length; i++) {  
  31.             System.out.print(data[i] + " ");  
  32.         }  
  33.     }  
  34.   
  35. }  
package com.xtfggef.algo.sort;

public class SelectSort {

	static int data[] = { 9, 2, 7, 19, 100, 97, 63, 208, 55, 78 };

	public static void selectSort() {
		int i, j, k, tmp = 0;
		for (i = 0; i < data.length - 1; i++) {
			k = i;
			for (j = i + 1; j < data.length; j++)
				if (data[j] < data[k])
					k = j;
			if (k != i) {
				tmp = data[i];
				data[i] = data[k];
				data[k] = tmp;
			}
		}
	}
	public static void main(String[] args) {
		print();
		System.out.println();
		selectSort();
		System.out.println();
		print();
	}

	static void print() {
		for (int i = 0; i < data.length; i++) {
			System.out.print(data[i] + " ");
		}
	}

}

通过循环,找出最小的数的下标,赋值于k,即k永远保持待排序数据中最小的数的下标,最后和当前位置i互换数据即可。

三、快速排序(O(nlogn)、不稳定)

快速排序简称快排,是一种比较快的排序,适合基本无序的数据,为什么这么说呢?下面我说下快排的思路:

设置两个指针:i和j,分别指向第一个和最后一个,i像后移动,j向前移动,选第一个数为标准(一般这样做,当然快排的关键就是这个“标准”的选取),从后面开始,找到第一个比标准小的数,互换位置,然后再从前面,找到第一个比标准大的数,互换位置,第一趟的结果就是标准左边的都小于标准,右边的都大于标准(但不一定有序),分成两拨后,继续递归的使用上述方法,最终有序!代码如下:

  1. package com.xtfggef.algo.sort;  
  2.   
  3. public class QuickSortTest {  
  4.   
  5.     static class QuickSort {  
  6.   
  7.         public int data[];  
  8.   
  9.         private int partition(int array[], int low, int high) {  
  10.             int key = array[low];  
  11.             while (low < high) {  
  12.                 while (low < high && array[high] >= key)  
  13.                     high--;  
  14.                 array[low] = array[high];  
  15.                 while (low < high && array[low] <= key)  
  16.                     low++;  
  17.                 array[high] = array[low];  
  18.             }  
  19.             array[low] = key;  
  20.             return low;  
  21.         }  
  22.   
  23.         public int[] sort(int low, int high) {  
  24.             if (low < high) {  
  25.                 int result = partition(data, low, high);  
  26.                 sort(low, result - 1);  
  27.                 sort(result + 1, high);  
  28.             }  
  29.             return data;  
  30.         }  
  31.     }  
  32.   
  33.     static void print(int data[]) {  
  34.         for (int i = 0; i < data.length; i++) {  
  35.             System.out.print(data[i] + " ");  
  36.         }  
  37.     }  
  38.   
  39.     public static void main(String[] args) {  
  40.         int data[] = { 20310918699200963000 };  
  41.         print(data);  
  42.         System.out.println();  
  43.         QuickSort qs = new QuickSort();  
  44.         qs.data = data;  
  45.         qs.sort(0, data.length - 1);  
  46.         print(data);  
  47.     }  
  48. }  
package com.xtfggef.algo.sort;

public class QuickSortTest {

	static class QuickSort {

		public int data[];

		private int partition(int array[], int low, int high) {
			int key = array[low];
			while (low < high) {
				while (low < high && array[high] >= key)
					high--;
				array[low] = array[high];
				while (low < high && array[low] <= key)
					low++;
				array[high] = array[low];
			}
			array[low] = key;
			return low;
		}

		public int[] sort(int low, int high) {
			if (low < high) {
				int result = partition(data, low, high);
				sort(low, result - 1);
				sort(result + 1, high);
			}
			return data;
		}
	}

	static void print(int data[]) {
		for (int i = 0; i < data.length; i++) {
			System.out.print(data[i] + " ");
		}
	}

	public static void main(String[] args) {
		int data[] = { 20, 3, 10, 9, 186, 99, 200, 96, 3000 };
		print(data);
		System.out.println();
		QuickSort qs = new QuickSort();
		qs.data = data;
		qs.sort(0, data.length - 1);
		print(data);
	}
}


看看上面的图,基本就明白了。


四、冒泡排序(稳定、基本有序可达O(n),最坏情况为O(n2))

冒泡排序是一种很简单,不论是理解还是时间起来都比较容易的一种排序算法,思路简单:小的数一点一点向前起泡,最终有序。

  1. package com.xtfggef.algo.sort;  
  2.   
  3. public class BubbleSort {  
  4.   
  5.     static int data[] = { 9271910097632085578 };  
  6.   
  7.     public static void bubbleSort() {  
  8.         int i, j, tmp = 0;  
  9.         for (i = 0; i < data.length - 1; i++) {  
  10.             for (j = data.length - 1; j > i; j--) {  
  11.                 if (data[j] < data[j - 1]) {  
  12.                     tmp = data[j];  
  13.                     data[j] = data[j - 1];  
  14.                     data[j - 1] = tmp;  
  15.                 }  
  16.             }  
  17.         }  
  18.     }  
  19.   
  20.     public static void main(String[] args) {  
  21.         print();  
  22.         System.out.println();  
  23.         bubbleSort();  
  24.         System.out.println();  
  25.         print();  
  26.     }  
  27.   
  28.     static void print() {  
  29.         for (int i = 0; i < data.length; i++) {  
  30.             System.out.print(data[i] + " ");  
  31.         }  
  32.     }  
  33.   
  34. }  
package com.xtfggef.algo.sort;

public class BubbleSort {

	static int data[] = { 9, 2, 7, 19, 100, 97, 63, 208, 55, 78 };

	public static void bubbleSort() {
		int i, j, tmp = 0;
		for (i = 0; i < data.length - 1; i++) {
			for (j = data.length - 1; j > i; j--) {
				if (data[j] < data[j - 1]) {
					tmp = data[j];
					data[j] = data[j - 1];
					data[j - 1] = tmp;
				}
			}
		}
	}

	public static void main(String[] args) {
		print();
		System.out.println();
		bubbleSort();
		System.out.println();
		print();
	}

	static void print() {
		for (int i = 0; i < data.length; i++) {
			System.out.print(data[i] + " ");
		}
	}

}


文章最后,给大家推荐一个数据结构学习的网站,有flash演示的:http://www.tyut.edu.cn/kecheng1/site01/index.asp

本章的所有代码我已经上传到了我的资源,有需要的自己去下载:http://download.csdn.net/detail/zhangerqing/5288624 没有积分的,微博上私信我。

作者:egg

邮箱:xtfggef@gmail.com

微博:http://weibo.com/xtfggef

博客:http://blog.csdn.net/zhangerqing(转载请说明出处)

欢迎大家持续阅读本博客,同时提出好的意见和建议!

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值