您的位置:首页 > 编程语言 > Java开发

常用排序算法简介与java实现(冒泡、插入、选择、希尔、归并、快排)

2016-09-25 17:04 639 查看
本文介绍六大常用算法的基本思路,以及相应的java函数实现。

本文的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
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐