1、插入排序算法
1.直接插入排序数组
2.折半插入排序数据结构
3.希尔排序spa
2、交换类排序.net
1.冒泡排序3d
2.快速排序blog
3、选择类排序排序
1.简单选择排序 索引
2.堆排序内存
4、归并排序
二路归并排序
归并排序
public static void insertionSort(int[] a) {
int tmp;
for (int i = 1; i < a.length; i++) {
for (int j = i; j > 0; j--) {
if (a[j] < a[j - 1]) {
tmp = a[j - 1];
a[j - 1] = a[j];
a[j] = tmp;
}
}
}
}
寻找插入的位置采用折半查找法
希尔(Shell)排序又称为缩小增量排序,它是一种插入排序。它是直接插入排序算法的一种威力增强版。
把记录按步长 gap 分组,对每组记录采用直接插入排序方法进行排序。随着步长逐渐减少,所分红的组包含的记录愈来愈多,当步长的值减少到 1 时,整个数据合成为一组,构成一组有序记录,则完成排序。gap1 = N / 2 ,gapk = gap(k-1) / 2
public static void bubbleSort(int[] a) {
int flag;
int temp;
for (int i = a.length-1; i > 0; --i) {
flag = 0;
for (int j = 1; j <= i; ++j) {
if (a[j] < a[j - 1]) {
temp = a[j];
a[j] = a[j - 1];
a[j - 1] = temp;
flag = 1;
}
}
if(flag == 0)
return;
}
}
public static void partition(int []array,int lo,int hi){
//固定的切分方式
int key=array[lo];
while(lo<hi){
while(array[hi]>=key&&hi>lo){
hi--;
}
array[lo]=array[hi];
while(array[lo]<=key&&hi>lo){
lo++;
}
array[hi]=array[lo];
}
array[hi]=key;
partition(int []array,lo, hi-1);
partition(int []array, lo, hi+1);
}
public void selectionSort(int[] list) {
// 须要遍历得到最小值的次数
// 要注意一点,当要排序 N 个数,已经通过 N-1 次遍历后,已是有序数列
for (int i = 0; i < list.length - 1; i++) {
int temp = 0;
int index = i; // 用来保存最小值得索引
// 寻找第i个小的数值
for (int j = i + 1; j < list.length; j++) {
if (list[index] > list[j]) {
index = j;
}
temp = list[index];
list[index] = list[i];
list[i] = temp;
printAll(list);
}
}
① 先将初始文件R[1..n]建成一个大根堆,此堆为初始的无序区
② 再将关键字最大的记录R[1](即堆顶)和无序区的最后一个记录R[n]交换,由此获得新的无序区R[1..n-1]和有序区R[n],且知足R[1..n-1].keys≤R[n].key
③因为交换后新的根R[1]可能违反堆性质,故应将当前无序区R[1..n-1]调整为堆。而后再次将R[1..n-1]中关键字最大的记录R[1]和该区间的最后一个记录R[n-1]交换,由此获得新的无序区R[1..n-2]和有序区R[n-1..n],且仍知足关系R[1..n-2].keys≤R[n-1..n].keys,一样要将R[1..n-2]调整为堆。
……
直到无序区只有一个元素为止。
public class HeapSort {
/**
* 构建大顶堆 数组下标从1开始
*/
public static void adjustHeap(int[] a, int i, int len) {
int temp, j;
temp = a[i];
for (j = 2 * i; j <= len; j *= 2) {// 沿关键字较大的孩子结点向下筛选
if (j < len && a[j] < a[j + 1])
++j; // j为关键字中较大记录的下标
if (temp >= a[j])
break;
a[i] = a[j];
i = j;
}
a[i] = temp;
}
public static void heapSort(int[] a) {
int i;
for (i = a.length / 2; i > 0; i--) {// 构建一个大顶堆
adjustHeap(a, i, a.length);
}
for (i = a.length; i > 1; i--) {// 将堆顶记录和当前未经排序子序列的最后一个记录交换
int temp = a[1];
a[1] = a[i];
a[i] = temp;
adjustHeap(a, 1, i - 1);// 将a中前i-1个记录从新调整为大顶堆
}
}
public static void main(String[] args) {
int a[] = { 51, 46, 20, 18, 65, 97, 82, 30, 77, 50 };
heapSort(a);
System.out.println(Arrays.toString(a));
}
}
外部排序指的是大文件的排序,即待排序的记录存储在外存储器上,待排序的文件没法一次装入内存,须要在内存和外部存储器之间进行屡次数据交换,以达到排序整个文件的目的。外部排序最经常使用的算法是多路归并排序,即将原文件分解成多个可以一次性装入内存的部分,分别把每一部分调入内存完成排序。而后,对已经排序的子文件进行归并排序。
过程 :
1.初始归并段生成
将文件分段输入内存并排序,排序完的文件称归并段,将其写入外存,这样就造成了许多初始归并段。
置换-选择排序
文件输入记录,当填满缓冲区后,选择最小记录输出,空缺位置由下个输入记录取代,输出记录即为初始归并段的一部分。(新填充的记录若是不能成为当前归并段的一部分,也就是说比当前归并段最大记录小,那么等待下一个归并段提供选择)
2.最佳归并树创建
二路归并即用哈夫曼树,I/O次数 = 带权路径长度*2。
平均状况
快速排序、希尔排序、堆排序、归并排序 O(log2n)
其余的为O(n平方)
最坏状况
快排为O(n平方),越无序越好
其余和平均状况同样
最好状况
有序的状况下,直接插入排序和冒泡排序为O(n)
快排为O(log2n)
归并排序为O(n)
快速排序、希尔排序、简单选择排序、堆排序为不稳定的
其他为稳定的