插入排序:
直接插入排序,时间复杂度
。稳定,最好情况是O(n)
折半插入排序,仅仅少了比较元素的次数,约为
,时间复杂度
。比较次数与待排序的初始状态无关,仅与表中的元素个数n有关
希尔排序,最差情况下为
。不稳定
交换排序:
冒泡排序,时间复杂度
稳定,最好情况是O(n)
最小比较次数n-1,移动次数0个
最大比较次数n(n-1)/2。
最大移动次数
快速排序
空间复杂度:平均
,最差O(n)
时间效率:平均
,最差(基本有序或基本逆序)
不稳定
简单选择排序:
比较次数与初态无关,始终是n(n-1)/2次
不稳定
堆排序:
建堆时间:O(n)
时间效率:
不稳定
归并排序
空间复杂度:O(n)
时间效率:
稳定
基数排序:
稳定
**
关键字比较次数与初态无关:
二分插入、简单选择排序、基数排序、堆排序
排序趟数与初态无关:直接插入,简单选择,基数排序
排序趟数与初态有关:
冒泡,没交换就一次
快速排序
直接插入排序
public void insertSort(int[] elem) {
int i, j;
for (i = 2; i < elem.length; i++) {
if(elem[i] < elem[i - 1]) { //需要将elem[i]插入到有序子表
elem[0] = elem[i]; //设置哨兵
for (j = i - 1; elem[j] > elem[0]; j--) elem[j + 1] = elem[j];
elem[j + 1] = elem[0]; //插入到正确位置
}
}
}
折半插入排序
private static void f(int[] a) {
for (int i = 2; i < a.length; ++i) {
a[0] = a[i];
int low = 1;
int height = i - 1;
while (low <= height) {
int m = (height + low) / 2;
if (a[m] < a[0]) low = m + 1;
else height = m - 1;
}
for (int j = i - 1; j > height; --j) a[j + 1] = a[j];
a[low] = a[0];
}
}
希尔排序
public static void shellSort(int[] arr){
//inc是增量
int temp = 0;
int j = 0;
//增量默认是长度的一半,每次变为之前的一半,直到最终数组有序
for(int inc=arr.length/2 ; inc>=1 ; inc/=2){
for(int i=inc ; i<arr.length; i++){
temp = arr[i];
//将当前的数与减去增量之后位置的数进行比较,如果大于当前数,将他后移
for(j=i-inc; j>=0;j-=inc){
if(arr[j]>temp) arr[j+inc] = arr[j];
else break;
}
//将当前数放到空出来的位置
arr[j+inc]=temp;
}
}
}
冒泡排序
public static int[] bubbleSort(int[] arr) {
for (int i = 0; i < arr.length; i++) {
int tem = 0;
for (int j = i + 1; j < arr.length; j++) {
if (arr[i] > arr[j]) arr = swap(arr,i,j);
}
}
return arr;
}
int[] swap(int[] a,int i,int j){
int temp;
temp=a[i];
a[i]=a[j];
a[j]=temp;
return a;
}
快速排序
public static void quickSort(int[] arr, int low, int high) {
int i,j,temp,t;
if (low > high) return;
i = low;
j = high;
temp = arr[low];
while (i < j) {
while (temp <= arr[j] && i < j) j--;
while (temp >= arr[i] && i < j) i++;
if (i < j) arr = swap(arr,i,j);
}
arr[low] = arr[i];
arr[i] = temp;
quickSort(arr, low, j - 1);
quickSort(arr, j + 1, high);
}
int[] swap(int[] a,int i,int j){
int temp;
temp=a[i];
a[i]=a[j];
a[j]=temp;
return a;
}
简单选择排序
public static void simpleSelectSort(int[] array) {
if (null == array || array.length <= 1) return;
for (int i = 0; i < array.length - 1; i++) {
int temp;
int index = i;
for (int j = i + 1; j < array.length; j++) {
if (array[index] > array[j]) index = j;
}
temp = array[index];
array[index] = array[i];
array[i] = temp;
}
}
堆排序
public static void heapSort(int[] array) {
if (array == null || array.length == 1) return;
buildArrayToHeap(array);
for (int i = array.length - 1; i >= 1; i--) {
swap(array, 0, i);
buildMaxHeap(array, i, 0);
buildMinHeap(array, i, 0);
}
}
// 构建堆
public static void buildArrayToHeap(int[] array) {
if (array == null || array.length == 1) return;
int cursor = array.length / 2;
for (int i = cursor; i >= 0; i--) {
//buildMaxHeap(array, array.length, i);
buildMinHeap(array, array.length, i);
}
}
//大顶堆
public static void buildMaxHeap(int[] array, int heapSieze, int index) {
int left = index * 2 + 1; // 左子节点
int right = index * 2 + 2; // 右子节点
int maxValue = index; // 暂时定在Index的位置就是最大值
if (left < heapSieze && array[left] > array[maxValue]) {
maxValue = left;
}
if (right < heapSieze && array[right] > array[maxValue]) {
maxValue = right;
}
if (maxValue != index) {
swap(array, index, maxValue);
buildMaxHeap(array, heapSieze, maxValue);
}
}
//小顶堆
public static void buildMinHeap(int[] array, int heapSieze, int index) {
int left = index * 2 + 1; // 左子节点
int right = index * 2 + 2; // 右子节点
int maxValue = index; // 暂时定在Index的位置就是最小值
if (left < heapSieze && array[left] < array[maxValue]) {
maxValue = left;
}
if (right < heapSieze && array[right] < array[maxValue]) {
maxValue = right;
}
if (maxValue != index) {
swap(array, index, maxValue); // 就要交换位置元素
buildMinHeap(array, heapSieze, maxValue);
}
}
//调整为最小堆
void AdjustUp(int a[],int k){
int temp=a[k];
int i=k,j=i/2;
while(j>=0 && a[j]<=temp){
a[i]=a[j];
i=j;
j=j/2;
}
a[i]=temp;
}
归并排序
void _MergeSort(int *a, int left, int right, int *tmp)
{
if (left >= right)
return;
if (right - left + 1 < 20)
{
InsertSort(a + left, right - left + 1);//小区间优化:当数据个数(闭区间需要加1)小于20时,直接插入排序
return;
}
int mid = left + (right - left) / 2;
_MergeSort(a, left, mid, tmp);//将左边划分为有序
_MergeSort(a, mid + 1, right, tmp);//将右边划分语序
int begin1 = left, end1 = mid;
int begin2 = mid + 1, end2 = right;
int index = left;
// begin1--end1是有序区间 begin2--end2是有序区间
//将两段有序区间合并为一段有序区间
while (begin1 <= end1 && begin2 <= end2)
{
//把小的数据放在tmp中
if (a[begin1] <= a[begin2])//等于号保证归并是稳定的
{
tmp[index] = a[begin1];
index++;
begin1++;
}
else
{
tmp[index] = a[begin2];
index++;
begin2++;
}
}
if (begin1 > end1)//说明begin2-end2还有数据
{
while (begin2 <= end2)
tmp[index++] = a[begin2++];
}
else //说明begin1 - end1还有数据
{
while (begin1 <= end1)
tmp[index++] = a[begin1++];
}
index = left;
while (index <= right)//由于tmp只是个临时数组,需要将有序数据重新放到数组a中
{
a[index] = tmp[index];
index++;
}
}
void MergeSort(int *a, int n)
{
assert(a);
int *tmp = (int *)malloc(sizeof(int)*n);
_MergeSort(a, 0, n - 1, tmp);//tmp是临时数组
free(tmp);
tmp = NULL;
}