最近看了一些排序算法,在此做一些回顾
基础排序算法
一、插入排序
所谓插入排序,简单理解就是把一个数据放到已经排序的数列中某个位置,把其他数据挤跑的过程。
void InsertionSort(int data[], int n)
{
int i , j , temp;
for (i = 1; i < n; i++)
{
temp = data[i];
for (j = i; j > 0; j--)
{
if(temp < data[j - 1])
data[j] = data[j - 1];
else
{
data[j] = temp;
break;
}
}
}
}
插入排序理解的核心就是temp,temp总是可以认为一直位于data[j]的位置上。
二、选择排序
所谓选择排序,就是把数列中最大或者最小的数值选出放到排序数列的最末或者开头位置的过程。
void SelectionSort(int data[], int n)
{
int i, j, max;
for ( i = 0; i < n-1; i++)
{
for ( j = i+1,max = i; j < n && data[max] < data[j]; j++)
{
max = j;
}
if(i != max) swap(data[max], data[i]);
}
}
三、冒泡排序
所谓的冒泡排序,就是把数列想象成垂直的柱体,从低到高比较相邻的两个元素,大的元素上浮,小的元素下沉的原则,最后最大的数值就会浮在最上部。
void BubbleSort(int data[], int n)
{
int i, j;
for ( i = 0; i < n-1; i++)
{
for ( j = 1; j < n - i; j++)
{
if (data[j-1] > data[j] )
{
swap(data[j - 1], data[j]);
}
}
}
}
四、梳排序
所谓的梳排序,就是在冒泡法的基础上,通过比较彼此之间步长位置的方式先对数据进行预处理,然后使用冒泡法。
void CombSort(int data[], int n)
{
int gap = n, i, j;
while ( (gap = gap/1.3)>1 )
{
for (i = 0, j = gap; i < n - gap; i++)
{
if (data[i] > data[step+i])
{
swap(data[i], data[gap + i]);
}
}
}
bool finish = false;//冒泡法用于排序纠正
for ( i = 0; !finish && i < n; i++)
{
for (finish = true, j = 0; j < n-i; j++)
{
if (data[j-1]>data[j])
{
swap(data[j - 1], data[j]);
finish = false;
}
}
}
}
高效排序算法
一、希尔排序
希尔排序是在插入排序的基础上发展而来的,主要思想是先把整个数列按步长分组,每个组内使用插入排序,当步长为1时,完成排序
void ShellSort(int data[], int n)
{
int h, i, j, k;
int inc[20], hinc;
int tmp;
//create increment arry
for (h=1, i = 0; i < n; i++)
{
inc[i] = h;
h = h * 3 + 1;
}
//loop on different inc
for (i--; i>0; i--)
{
h = inc[i];
for ( hinc = h; hinc < 2*h; hinc++)
{//insertion sort
for ( j = hinc; j< n; )
{
tmp = data[j];
for (k = j; k>0 && tmp < data[k - h];)
{
data[k] = data[k- h];
k -= h;
}
data[k] = tmp;
j += h;
}
}
}
}
二、堆排序
堆排序在选择排序的基础上发展而来,主要分两步走:(原理分析)
1、构建堆
2、排序堆
int data[20];
int n = 20;
void HeapAdjust(int data[], int p, int size)
{
int left = p * 2;
int right = 2 * p + 1;
int max = p;
if (left <= size && data[left] > data[max])
{
max = left;
}
if (right <= size && data[right] > data[max])
{
max = right;
}
if (p != max)
{
swap(data[p], data[max]);
HeapAdjust(data, max, size);
}
}
/*data数组的数据从下标1开始算起*/
void HeapSort(int data[], int n)
{
//构建堆
int i = n / 2;
for (; i>0; i--)
{
HeapAdjust(data, i, n);
}
//排序
for ( i = n ; i > 0; i--)
{
swap(data[n], data[1]);
HeapAdjust(data, 1, i -1);
}
}
三、快速排序
快速排序采用的是一个分而治之的思想,类似于选两个筐捡橘子,拿一个橘子做标准,比它大的放一个筐,其他的放一个筐,循环往复
void QuickSort(int data[], int start, int end)
{
if (start >= end) return;
swap(data[(start + end) / 2], data[start]);
int bound = data[start];
int low = start + 1;
int up = end;
while (low <= up)
{
while (low < up && bound >= data[low])
{
low++;
}
while (low < up && bound < data[up])
{
up--;
}
if (low < up)
{
swap(data[low++], data[up--]);
}
else if(bound >= data[low])
{
low++;
}else up--;
}
swap(data[up], data[start]);
QuickSort(data, low, end);
QuickSort(data, start, up - 1);
}
归并排序的思想也是分而治之,先递归的分解数列,再合并数列就完成了归并排序。
void Merge(int data[], int start, int end, int tmp[])
{
int mid = (start + end) / 2;
int first = start;
int last = mid+1;
int i = 0;
while (first<=mid && last <= end)
{
if ( data[first] < data[last])
{
tmp[i++] = data[first++];
}
else
{
tmp[i++] = data[last++];
}
}
while (first <= mid)
{
tmp[i++] = data[first++];
}
while (last <= end)
{
tmp[i++] = data[last++];
}
for (i--; i > 0; i--)
{
data[start + i] = tmp[i];
}
}
void MergeSort(int data[], int start, int end, int tmp[])
{
if (start < end)
{//分解数列
int mid = (start + end) / 2;
MergeSort(data, start, mid, tmp);
MergeSort(data, mid + 1, end, tmp);
//数组合并
Merge(data, start, end, tmp);
}
}