Java中常见的排序算法
most important and common
sorting techniques. Each algorithm has particular strengths and weaknesses and in many cases the best thing to do is just use the built-in sorting function qsort. For times when this isn't an
option or you just need a quick and dirty sorting algorithm, there are a variety of choices.
Most sorting algorithms work by comparing the data being sorted. In some cases, it may be desirable to sort a large chunk of data (for instance, a struct containing a name and address) based on only
a portion of that data. The piece of data actually used to determine the sorted order is called the key.
Sorting algorithms are usually judged by their efficiency. In this case, efficiency refers to the algorithmic efficiency as the size of the input grows large and is generally based on the number of
elements to sort. Most of the algorithms in use have an algorithmic efficiency of either O(n^2) or O(n*log(n)). A few special case algorithms (one example is mentioned in Programming
Pearls) can sort certain data sets faster than O(n*log(n)). These algorithms are not based on comparing the items being sorted and rely on tricks. It has been shown that no key-comparison algorithm
can perform better than O(n*log(n)).
Many algorithms that have the same efficiency do not have the same speed on the same input. First, algorithms must be judged based on their average case, best case, and worst case efficiency. Some
algorithms, such as quick sort, perform exceptionally well for some inputs, but horribly for others. Other algorithms, such as merge sort, are unaffected by the order of input data. Even a modified version of bubble sort can finish in O(n) for the most favorable
inputs.
A second factor is the "constant term". As big-O notation abstracts away many of the details of a process, it is quite useful for looking at the big picture. But one thing that gets dropped out is
the constant in front of the expression: for instance, O(c*n) is just O(n). In the real world, the constant, c, will vary across different algorithms. A well-implemented quicksort should have a much smaller constant multiplier than heap sort.
A second criterion for judging algorithms is their space requirement -- do they require scratch space or can the array be sorted in place (without additional memory beyond a few variables)? Some algorithms
never require extra space, whereas some are most easily understood when implemented with extra space (heap sort, for instance, can be done in place, but conceptually it is much easier to think of a separate heap). Space requirements may even depend on the
data structure used (merge sort on arrays versus merge sort on linked lists, for instance).
A third criterion is stability -- does the sort preserve the order of keys with equal values? Most simple sorts do just this, but some sorts, such as heap sort, do not.
The following chart compares sorting algorithms on the various criteria outlined above; the algorithms with higher constant terms appear first, though this is clearly an implementation-dependent concept
and should only be taken as a rough guide when picking between sorts of the same big-O efficiency.
| Time | ||||||
|---|---|---|---|---|---|---|
| Sort | Average | Best | Worst | Space | Stability | Remarks |
| Bubble sort | O(n^2) | O(n^2) | O(n^2) | Constant | Stable | Always use a modified bubble sort |
| Modified Bubble sort | O(n^2) | O(n) | O(n^2) | Constant | Stable | Stops after reaching a sorted array |
| Selection Sort | O(n^2) | O(n^2) | O(n^2) | Constant | Stable | Even a perfectly sorted input requires scanning the entire array |
| Insertion Sort | O(n^2) | O(n) | O(n^2) | Constant | Stable | In the best case (already sorted), every insert requires constant time |
| Heap Sort | O(n*log(n)) | O(n*log(n)) | O(n*log(n)) | Constant | Instable | By using input array as storage for the heap, it is possible to achieve constant space |
| Merge Sort | O(n*log(n)) | O(n*log(n)) | O(n*log(n)) | Depends | Stable | On arrays, merge sort requires O(n) space; on linked lists, merge sort requires constant space |
| Quicksort | O(n*log(n)) | O(n*log(n)) | O(n^2) | Constant | Stable | Randomly picking a pivot value (or shuffling the array prior to sorting) can help avoid worst case scenarios such as a perfectly sorted array. |



QuickSort(高速):
i = j才确定的。如有不懂请看一下后面的代码部分);
|
66
|
55
|
88
|
11
|
44
|
22
|
99
|
33
|
77 |
选择头元素66(下标i = 0)作为比較的基准,与尾元素77(下标j = 8)作比較:
= 1)作比較了);@ 否则不换位置( j--【注意咯】),那么下一次与33(下标 j=
7)作比較了,就是我们这样的情况);【记住啦:产生交换就j--;否则i++】
(i = 0, j = 7)
| 33 |
55
|
88
|
11
|
44
|
22
|
99
|
66
|
77 |
(i = 1, j = 7)
|
33
|
55
|
88
|
11
|
44
|
22
|
99
|
66
|
77 |
(i = 2, j = 7)
|
33
|
55
|
66
|
11
|
44
|
22
|
99
|
88 | 77 |
(i = 2, j = 6)
|
33
|
55
|
66
|
11
|
44
|
22
|
99
|
88
|
77 |
|
33
|
55
|
22
|
11
|
44
|
66
|
99
|
88
|
77 |
(i = 4, j = 5)
|
33
|
55
|
22
|
11
|
44
|
66 |
99
|
88
|
77 |
|
33
|
55
|
22
|
11
|
44
|
66
|
99
|
88
|
77 |
55 88 11 44 22 99 33 77 最初位置
33 55 22 11 44 66 99 88 77
1
33 55 22 11 44 66 77 88 99
2
33 55 22 11 44 66 77 88 99
3
11 22 33 55 44 66 77 88 99
4
11 22 33 44 55 66 77 88 99
5
11 22 33 44 55 66 77 88 99
6
// 高速排序
private static void quickSort(int[] array, int start, int end) {
if (start >= end) {
return;
}
int i = start;
int j = end;
boolean isrun = true; // 思路一的逻辑代码
while (i != j) {
if (array[i] > array[j]) { swap(array, i, j);
isrun = (isrun == true) ? false : true; }
if (isrun) {
j--;
} else {
i++;
}
time++;
}
print(array);
i--;
j++; quickSort(array, j, end);
quickSort(array, start, i);
}
= 0,当中下标i相应的元素是待插入的目标元素。每一轮过后,下标i前面的元素将会顺序排列。
= 0 和 right = i - 1(为什么要减1,由于i是我们待插入的元素下标)。每次採用折中的办法找到所相应元素的下标mid;
< array[mid]
= mid - 1;(>同理)。
> right)时就能确定插入的位置,【记住:下标i之前的元素都已经排好序的,故仅仅要总体往后挪动一个单位就可以】。
|
66
|
55
|
88
|
11
|
44
|
22
|
|
66
|
55
|
88
|
11
|
44
|
22
|
|
55
|
66
|
88
|
11
|
44
|
22
|
|
55
|
66
|
88
|
11
|
44
|
22
|
|
11
|
55
|
66
|
88
|
44
|
22
|
|
11
|
44
|
55
|
66
|
88
|
22
|
|
11
|
22
|
44
|
55
|
66
|
88
|
// 二分法排序
private static void binaryCheck(int[] array) {
for (int i = 0; i < array.length; i++) {
int key = array[i];
int left = 0;
int right = i - 1;
int mid = 0; // 每一轮查找的逻辑代码
while (left <= right) {
mid = (right + left) / 2;
if (key < array[mid]) {
right = mid - 1;
} else {
left = mid + 1;
}
time++;
}
// 区间[left,i-1]总体往后挪动一个单位
for (int j = i - 1; j >= left; j--) {
array[j + 1] = array[j];
}
// 将目标元素插入指定位置
if (left != i) {
array[left] = key;
}
print(test);
}
}

77 --------原始序列
77 1
99
99
99 2
99 ----------EXP
99
[d = array.length/2];
[d = (array.length/2)/2];
= array.length/2];当d<0时。排序结束;
= 3)和22(下标i
= 4)后,22的下标(i = 1,而不是 i = 3,这种替换),
// 希尔排序
private static void shellSort(int[] array, int len) {
int j;
int d = len / 2;
int temp = 0;
while (d > 0) {
for (int i = d; i < len; i++) {
j = i - d;
while (j >= 0 && array[j + d] < array[j]) {
temp = array[j];
array[j] = array[j + d];
array[j + d] = temp;
j = j - d;
time++; }
print(test);
}
d = d / 2;
}
}
--------3。
4 + 5次;
// 归并排序
private static void myMerge(int[] array,int first,int sStart,int sEnd){
int[] temp = new int[sEnd - first + 1];
int i = first,j = sStart,k = 0; while(i < sStart && j <= sEnd){ //由于每一轮归并后,产生的数组中元素将会顺序排列,若A中的第一个元素大于B中的
//最后一个元素,那么A中的其它元素无需比較,直接转移
if(array[i] <= array[j]){
temp[k] = array[i];
i++;
k++;
}else{
temp[k] = array[j];
k++;
j++;
}
} while(i < sStart){
temp[k] = array[i];
k++;
i++;
}
while(j <= sEnd){
temp[k] = array[j];
k++;
j++;
}
System.arraycopy(temp, 0, array, first, temp.length);
} private static void mySort(int[] array,int start,int len){
int size = 0; //计算归并的第一组元素的起始位置
int length = array.length;
int mtime = length/(2*len); //归并的数组个数
int rest = length & (2*len - 1); //统计归并的最后一个数组(当数组元素的个数为奇数时,那么在归并的过程中最后一个数组元素个数是奇数)
// 假设在归并过程中数组的个数刚好是偶数那么rest = 0;
if(mtime == 0){
return;
} for(int i = 0;i < mtime;i ++){
size = 2*i*len;
myMerge(array, size, size + len, size + 2*len - 1);
} if(rest != 0){
myMerge(array, length - rest - 2*len, length - rest, length - 1);
}
//下一轮归并
mySort(array, 0, 2*len);
}
Java中常见的排序算法的更多相关文章
- Java中常见的排序方法
本博主要介绍Java中几种常见的排序算法: /* 排序方法的演示1)插入排序(直接插入排序.希尔排序)2)交换排序(冒泡排序.快速排序)3)选择排序(直接选择排序.堆排序)4)归并排序5)分配排序(基 ...
- Java实现常见的排序算法
一.排序算法 常见的排序算法主要分为下面几类: 选择排序 堆排序 冒泡排序 快速排序 插入排序 希尔排序 归并排序 桶式排序 基数排序 本文主要介绍选择排序.堆排序.冒泡排序.快速排序和归并排序的原理 ...
- Java中几种排序算法
1.冒泡排序算法 通过多次比较(相邻两个数)和交换来实现排序 public class bubble { public static void bubbleSort(int[] a) { int te ...
- Java中常见的分页算法
在查询数据的时候或者展示数据的时候经常会使用分页,介绍几种简单的分页算法: //总的页数 int total = 30: //每页个数 int pageSize = 6; 1.one int ...
- Java中常见的排序方式-快速排序(升序)
[基本思想] 快速排序在元素较多的情况下,排序效率是相当高的.其基本思想是这样: 假设数组为int[] arr = { 49, 38, 65, 97, 76, 13, 27, 22, 26, 41, ...
- Java中常见的排序方式-选择排序(升序)
[基本思想] 假设数组为int[] a = { 49, 38, 65, 97, 76, 13, 27 },数组元素个数为7个. 第1轮比较:先是a[0]与a[1]比较,大于则先交换,再比较a[0]和a ...
- Java中常见的排序方式-冒泡排序(升序)
[基本思想] 假设数组为int[] a = { 49, 38, 65, 97, 76, 13, 27 },数组元素个数为7个. 第1轮比较:先是a[0]与a[1]比较,大于则先交换,再比较a[1]和a ...
- java编程之常见的排序算法
java常见的排序算法 第一种:插入排序 直接插入排序 1, 直接插入排序 (1)基本思想:在要排序的一组数中,假设前面(n-1)[n>=2] 个数已经是排 好顺序的,现在要把第n个数插到前面的 ...
- java讲讲几种常见的排序算法(二)
java讲讲几种常见的排序算法(二) 目录 java讲讲几种常见的排序算法(一) java讲讲几种常见的排序算法(二) 堆排序 思路:构建一个小顶堆,小顶堆就是棵二叉树,他的左右孩子均大于他的根节点( ...
随机推荐
- 把特征网络换成resnet-50
从RFCN来看,Resnet-50和Resnet-101到最后一层卷积都是缩小到原来尺寸的16分之一,并且都用的7x7的格子去roi pooling. 看paper可以知道:resnet-50核心是由 ...
- [LOJ] 分块九题 5
区间开平方,区间查询. lazy标记改为区间是否全是1或者0,这样的区间是没有更新价值的. //Stay foolish,stay hungry,stay young,stay simple #inc ...
- openjdk-alpine镜像无法打印线程堆栈和内存堆栈问题
基于openjdk:8u171-alpine构建的java镜像,使用jstack命令打印线程的时候会提示以下错误: /opt # ps -ef PID USER TIME COMMAND 1 root ...
- ubuntu中执行docker info出现警告信息WARNING: No memory limit support 或 WARNING: No swap limit support
docker info 指令报若下错误:WARNING: No memory limit support 或WARNING: No swap limit support 解决方法: 1.打开/etc/ ...
- python之多线程与多进程
1. 多进程与多线程 (1)背景:为何需要多进程或者多线程:在同一时间里,同一个计算机系统中如果允许两个或者两个以上的进程处于运行状态,这便是多任务.多任务会带来的好处例如用户边听歌.边上网.边打印, ...
- Haproxy的安装与配置
一.Haproxy概念 Haproxy提供高可用性.负载均衡以及基于TCP和HTTP应用的代理,支持虚拟主机,它是免费.快速并且可靠的一种解决方案.Haproxy特别适用于那些负载特大的web站点,这 ...
- reactNative 介绍
React Native (简称RN)是Facebook于2015年4月开源的跨平台移动应用开发框架,是Facebook早先开源的UI框架 React 在原生移动应用平台的衍生产物,目前支持iOS和安 ...
- XV6第一个进程
第一个进程 本章通过第一个进程的创建来解释 xv6 是如何开始运行的,让我们得以一窥 xv6 提供的各个抽象是如何实现和交互的.xv6 尽量复用了普通操作的代码来建立第一个进程,避免单独为其撰写代码. ...
- php基础 数组 遍历
//参数默认值// function abc($a,$b,$c=0){// echo $a,$b,$c;// }// abc(1,3); //可变参数//function def(){// $arr= ...
- 【数据传输 2】批量导入的前奏:将Excel表中的数据转换为DataTable类型
导读:我们知道,在数据库中,数据集DataSet是由多张DataTable表组成.所以,如果我们需要将数据从外部导入到数据库中,那么要做的很重要的一步是将这些数据转换为数据库可以接受的结构.今天在用S ...