常用排序算法简介与java实现(冒泡、插入、选择、希尔、归并、快排)
2016-09-25 17:04
639 查看
本文介绍六大常用算法的基本思路,以及相应的java函数实现。
本文的eclipse工程源代码可到以下链接下载:
http://download.csdn.net/detail/nostandby/9639511
下面将按照以下顺序进行介绍:
1、冒泡排序、冒泡排序的两种改进。
2、插入排序。
3、选择排序。
4、希尔排序。
5、归并排序。
6、快速排序。
1、冒泡排序:
相邻两个元素进行比较,如果反序就交换
冒泡排序改进1:
如果某一轮排序过程中没有发生交换,说明所有数据都已经有序,排序可以停止。
冒泡排序改进2:
在改进1的基础上,记录每一轮停止时的索引,这个索引表明:该索引之后的元素都已排好。
那么下一轮到这一位置停止即可
2、插入排序
思想:将一个元素插入到一个有序序列中。
实现思路是:从索引为1 的位置遍历“数组”,将每个元素插入到它前面的有序序列中。
理解它的关键在于:待插入元素之前的元素都是有序的。
3、选择排序
思想:
(1)、从待排序列中先找到最小的元素,放到第一个位置。
(2)、再从剩余元素中找最小的,放到第二个位置。……
(3)、以此类推,直到所有元素都找到了自己的位置。
选择排序是固定位置,找元素;冒泡排序和插入排序是固定元素找位置。
4、希尔排序(缩小增量排序)
可以认为是插入排序的一种变形。
思路:
先将整个待排元素序列分割成若干子序列(由相隔某个“增量”的元素组成的)分别进行直接插入排序
然后依次缩减增量再进行排序
待整个序列中的元素基本有序(增量足够小)时,再对全体元素进行一次直接插入排序(增量为1)。
其时间复杂度为O(n^3/2),要好于直接插入排序的O(n^2)
5、归并排序
分而治之,之后合并
6、快速排序
通过一趟排序将要排序的数据分割成独立的两部分,其中一部分的所有数据都比另外一部分的所有数据都要小,然后再按此方法对这两部分数据分别进行快速排序,整个排序过程可以递归进行,以此达到整个数据变成有序序列。时间复杂度为O(nlogn)
关于堆排序,桶排序,计数排序,基数排序等其他排序,时间问题,笔者目前还没有写出源代码。
以上内容仅代表笔者个人理解。如有错误欢迎交流指正。
参考资料:
1、《数据结构与算法分析(C++版)》
2、《算法导论》
3、http://www.open-open.com/lib/view/open1420372620468.html
本文的eclipse工程源代码可到以下链接下载:
http://download.csdn.net/detail/nostandby/9639511
下面将按照以下顺序进行介绍:
1、冒泡排序、冒泡排序的两种改进。
2、插入排序。
3、选择排序。
4、希尔排序。
5、归并排序。
6、快速排序。
1、冒泡排序:
相邻两个元素进行比较,如果反序就交换
public void bubbleSort1(List<Integer> nums) { for (int i = nums.size(); i > 0; i--) { for (int j = 0; j < i - 1; j++) { if (nums.get(j).intValue() > nums.get(j + 1).intValue()) { swap(nums, j, j + 1); } } } }
冒泡排序改进1:
如果某一轮排序过程中没有发生交换,说明所有数据都已经有序,排序可以停止。
public void bubbleSort2(List<Integer> nums) { boolean continueflag = true; for (int i = nums.size(); continueflag && i > 0; i--) { continueflag = false; for (int j = 0; j < i - 1; j++) { if (nums.get(j).intValue() > nums.get(j + 1).intValue()) { swap(nums, j, j + 1); continueflag = true; } } } }
冒泡排序改进2:
在改进1的基础上,记录每一轮停止时的索引,这个索引表明:该索引之后的元素都已排好。
那么下一轮到这一位置停止即可
public void bubbleSort3(List<Integer> nums) { int flag; for (int i = nums.size(); i > 0; i = flag) { flag = 0; 4000 for (int j = 0; j < i - 1; j++) { if (nums.get(j).intValue() > nums.get(j + 1).intValue()) { swap(nums, j, j + 1); flag = j + 1; } } } }
2、插入排序
思想:将一个元素插入到一个有序序列中。
实现思路是:从索引为1 的位置遍历“数组”,将每个元素插入到它前面的有序序列中。
理解它的关键在于:待插入元素之前的元素都是有序的。
public void insertionSort(List<Integer> nums) { int length = nums.size(); for (int i = 1; i < length; i++) { for (int j = i; j > 0 && nums.get(j - 1).intValue() > nums.get(j).intValue(); j--) { swap(nums, j, j - 1); } } }
3、选择排序
思想:
(1)、从待排序列中先找到最小的元素,放到第一个位置。
(2)、再从剩余元素中找最小的,放到第二个位置。……
(3)、以此类推,直到所有元素都找到了自己的位置。
选择排序是固定位置,找元素;冒泡排序和插入排序是固定元素找位置。
public void selectionSort(List<Integer> nums) { for (int i = 0; i < nums.size(); i++) { int lowindex = i; for (int j = i + 1; j < nums.size(); j++) { if (nums.get(j).intValue() < nums.get(lowindex).intValue()) { lowindex = j; } } swap(nums, i, lowindex); } }
4、希尔排序(缩小增量排序)
可以认为是插入排序的一种变形。
思路:
先将整个待排元素序列分割成若干子序列(由相隔某个“增量”的元素组成的)分别进行直接插入排序
然后依次缩减增量再进行排序
待整个序列中的元素基本有序(增量足够小)时,再对全体元素进行一次直接插入排序(增量为1)。
其时间复杂度为O(n^3/2),要好于直接插入排序的O(n^2)
public void shellSort(List<Integer> nums) { int length = nums.size(); for (int i = length / 2; i > 2; i /= 2) { for (int j = 0; j < i; j++) { inssort(nums, i); } } inssort(nums, 1); } private void inssort(List<Integer> nums, int incr) { for (int i = incr; i < nums.size(); i += incr) { for (int j = i; j >= incr && nums.get(j - incr).intValue() > nums.get(j).intValue(); j -= incr) { swap(nums, j, j - incr); } } }
5、归并排序
分而治之,之后合并
public void mergeSort(List<Integer> nums) { mergeSort(nums, 0, nums.size() - 1); } public void mergeSort(List<Integer> nums, int start, int end) { if (start == end) return; int mid = (start + end) / 2; mergeSort(nums, start, mid); mergeSort(nums, mid + 1, end); List<Integer> temp = new LinkedList<Integer>(); for (int i = start; i <= end; i++) { temp.add(new Integer(nums.get(i).intValue())); } int i1 = 0, i2 = mid - start + 1; for (int curr = start; curr <= end; curr++) { if (i1 == mid + 1) nums.set(curr, temp.get(i2++)); else { if (i2 > end - start) nums.set(curr, temp.get(i1++)); else { if (temp.get(i1).intValue() < temp.get(i2).intValue()) nums.set(curr, temp.get(i1++)); else nums.set(curr, temp.get(i2++)); } } } }
6、快速排序
通过一趟排序将要排序的数据分割成独立的两部分,其中一部分的所有数据都比另外一部分的所有数据都要小,然后再按此方法对这两部分数据分别进行快速排序,整个排序过程可以递归进行,以此达到整个数据变成有序序列。时间复杂度为O(nlogn)
public void qsort(List<Integer> nums) { qsort(nums, 0, nums.size() - 1); } public void qsort(List<Integer> nums, int start, int end) { if (start > end) return; int q = partition(nums, start, end); qsort(nums, start, q - 1); qsort(nums, q + 1, end); } private int partition(List<Integer> nums, int start, int end) { int keyIndex = end; int left = start, right = end - 1; while (left < right) { while (left < right && nums.get(left).intValue() < nums.get(keyIndex).intValue()) left++; while (left < right && nums.get(right).intValue() > nums.get(keyIndex).intValue()) right--; swap(nums, left, right); } swap(nums, left, keyIndex); return left; }
关于堆排序,桶排序,计数排序,基数排序等其他排序,时间问题,笔者目前还没有写出源代码。
以上内容仅代表笔者个人理解。如有错误欢迎交流指正。
参考资料:
1、《数据结构与算法分析(C++版)》
2、《算法导论》
3、http://www.open-open.com/lib/view/open1420372620468.html
相关文章推荐
- 《冒泡,选择,插入,归并,希尔,快速》排序算法java实现一览
- 常用排序算法的js实现(冒泡、选择、插入、归并、希尔、快排)
- Java语言实现九大排序算法(快速、归并、堆、选择、插入、计数、基数、希尔、冒泡)
- Java-十种内部排序实现(选择,冒泡,插入,希尔,堆,归并,快速,基数,计数,桶)及代码下载
- Java实现的排序算法及比较 [冒泡,选择,插入,归并,希尔,快排]
- java实现七大排序(插入,冒泡,选择,快速,堆,希尔,归并)
- 常用排序算法的c++实现(冒泡,选择,插入,堆,shell,快速,归并 )与sort()对比 - coder_xia的专栏 - 博客频道 - CSDN.NET
- 常用排序算法的c++实现(冒泡,选择,插入,堆,shell,快速,归并 )与sort()对比
- 常见排序算法C++实现(冒泡,直接插入,希尔,堆,归并,简单选择,快排)
- C++实现各种基础排序(冒泡、选择、快排、插入、堆排、希尔、归并)
- 基础排序算法 java 实现(冒泡、选择、插入、快排、归并、堆排)
- 常见排序算法总结与实现(冒泡、插入、选择、希尔、堆排序、归并、快排)
- 常见排序算法总结与实现(冒泡、插入、选择、希尔、堆排序、归并、快排)
- Java实现数组排序总结篇(冒泡,选择,插入,希尔)
- 七大排序算法(冒泡,选择,插入,二分法排序,希尔,快速,合并,堆排序)的java实现
- Java 基础排序算法(冒泡,比较,插入,选择,希尔,堆,归并)
- java实现常见排序(选择,冒泡,插入,快速,希尔,堆)
- 常见排序算法总结与实现(冒泡、插入、选择、希尔、堆排序、归并、快排)
- 常用排序算法总结(插入、冒泡、快速,堆、选择、希尔、归并)
- 常用排序算法--冒泡,插入,选择,希尔,归并,快速