稳定的排序算法
冒泡排序、插入排序、归并排序和基数排序
不稳定排序算法
选择排序、快速排序、希尔排序、堆排序
插入排序 O(n*n)
直接插入排序的算法思路:
(1) 设置监视哨r[0],将待插入纪录的值赋值给r[0];
(2) 设置开始查找的位置j;
(3) 在数组中进行搜索,搜索中将第j个纪录后移,直至r[0].key≥r[j].key为止;
(4) 将r[0]插入r[j+1]的位置上。
private static void insertSort(int[] arr) {
int len = arr.length;
for (int i = 1; i < len; i++) {
int key = arr[i], j;
for (j = 0; j <= i && arr[i] > arr[j]; j++) ;
if (i != j) {
for (int k = i; k >= j + 1; k--) {
arr[k] = arr[k - 1];
}
arr[j] = key;
}
}
}
冒泡排序 O(n*n)
冒泡排序算法的运作如下:(从后往前)
比较相邻的元素。如果第一个比第二个大,就交换他们两个。
对每一对相邻元素作同样的工作,从开始第一对到结尾的最后一对。在这一点,最后的元素应该会是最大的数。
针对所有的元素重复以上的步骤,除了最后一个。
持续每次对越来越少的元素重复上面的步骤,直到没有任何一对数字需要比较。[1]
private static void swap(int a[], int x, int y) {
int tmp = a[x];
a[x] = a[y];
a[y] = tmp;
}
private static void bubbleSort(int[] arr) {
int len = arr.length;
for (int i = 0; i < len - 1; i++) {
for (int j = i; j < len - 1; j++)
if (arr[j] > arr[j + 1]) {
swap(arr, j, j + 1);
}
}
}
快速排序 O(log2(n)*n)
void QuickSort(int begin,int end)
{
int i=begin,j=end;
if(begin<end)
{
temp=b[begin];
while(i!=j)
{
while(j>i && b[j]>=temp)
j--;
b[i]=b[j];
while(i<j && b[i]<=temp)
i++;
b[j]=b[i];
}
b[i]=temp;
QuickSort(begin,i-1);
QuickSort(i+1,end);
}
}
选择排序 O(n*n)
选择排序(Selection sort)是一种简单直观的排序算法。它的工作原理是每一次从待排序的数据元素中选出最小(或最大)的一个元素,存放在序列的起始位置,直到全部待排序的数据元素排完。
private static void selectSort(int[] arr) {
int len = arr.length;
for (int i = 0; i < len - 1; i++) {
int pos = i;
for (int j = i; j < len; j++) {
if (arr[j] < arr[pos]) {
pos = j;
}
}
if (pos != i) {
int tmp = arr[i];
arr[i] = arr[pos];
arr[pos] = tmp;
}
}
print(arr);
}
希尔排序 O(n^1.2)
public class Main {
private static void print(int a[]){
for(int i=0;i<a.length;i++){
System.out.print(a[i]+" ");
}
System.out.println();
}
public static void main(String[] args) {
int a[]={592,401,874,141,348,72,911,887,820,283};
int gap=a.length/2;
while(gap>=1){
for(int i=0,j=0;(j=i+gap)<a.length;i++){
if(a[i]>a[j]){
int tmp=a[i];
a[i]=a[j];
a[j]=tmp;
}
}
gap>>=1;
}
print(a);
}
}
堆排序 O(log2(n)*n)
#include <iostream>
#include <algorithm>
using namespace std;
//若想升序,则建立最大堆
//若想降序,则建立最小堆
void print(int a[],int n)
{
for(int i=0;i<n;i++)
cout<<a[i]<<" ";
cout<<endl;
}
void MaxHeapAdjust(int a[],int start,int end)//start,end
//本函数进行调整,使H[start~end]成为一个最大堆
{
for(int i=2*start+1;i<=end;i*=2)
{
if(i+1<=end && a[i]<a[i+1])
i++;//子节点中最大的节点
if(a[i]<a[start])
break;
//a[start]>=a[i],将a[start]上移
swap(a[start],a[i]);
start=i;
}
}
void MinHeapAdjust(int a[],int start,int end)//start,end
//本函数进行调整,使H[start~end]成为一个最小堆
{
for(int i=2*start+1;i<end;i*=2)
{
if(i+1<end && a[i]>a[i+1])
i++;//子节点中最大的节点
if(a[i]>a[start])
break;
//a[start]<=a[i],将a[start]上移
swap(a[start],a[i]);
start=i;
}
}
void HeapSort(int a[],int n)
{
for(int i=n/2;i>=0;i--)//除了最后一层的节点,不断从底至上构建最大堆
MaxHeapAdjust(a,i,n);
//MinHeapAdjust(a,i,n);
for(int i=n-1;i>0;i--)
{
swap(a[0],a[i]);//将最大的元素沉底
MaxHeapAdjust(a,0,i-1);//重新调整最大堆
//MinHeapAdjust(a,0,i-1);
}
}
int main()
{
int a[]={2,9,7,6,5,8};
HeapSort(a,6);
print(a,6);
return 0;
}
内排序和外排序
内排序:指在排序期间数据对象全部存放在内存的排序。
外排序:指在排序期间全部对象太多,不能同时存放在内存中,必须根据排序过程的要求,不断在内,外存间移动的排序。
内排序又可分为插入排序、选择排序、交换排序、归并排序及基数排序等几大类。
外排序:在数据量大的情况下,只能分块排序,但块与块间不能保证有序。外排序用读/写外存的次数来衡量其效率。外归并排序