我们所知道的各种排序办法有:
1.直接插入排序
算法思想:
在一个已知的排好序的序列中,插入一个数据,使更新后的序列保持有序
//直接插入排序
//O(N^2)
void InsertSort(int * a, int size)
{
assert(a);
for (int begin = 1; begin < size; begin++)
{
int tmp = a[begin];
int end = begin - 1;
while (end >= 0 && a[end]>tmp)
{
a[end + 1] = a[end];
a[end] = tmp;
end--;
}
}
}
2.希尔排序
算法思想:
以gap为间隔进行排序,当gap为1时,说明已经排好序
//希尔排序(直接插入排序的优化)
//O(N^1.25)……1.6 O(N^1.25)
void ShellSort(int *a, int size)
{
assert(a);
int gap = size;
while (gap > 1)
{
gap = gap / 3 + 1;
for (int begin = 0; begin < size - gap; begin++)
{
int end = begin;
int tmp = a[end + gap];
while (end >= 0 && a[end]>a[end + gap])
{
a[end + gap] = a[end];
a[end] = tmp;
end -= gap;
}
}
}
}
3.选择排序
算法思想:
在一趟排序时,找出最大的数据,把最大的和最后一个交换,循环实现
//选择排序
//O(N^2)
void SelectSort(int *a, int size)
{
assert(a);
for (int end = size - 1; end >0; end--)
{
int maxIndex = 0;
for (int j = 1; j <= end; j++)
{
if (a[maxIndex] < a[j])
{
maxIndex = j;
}
}
swap(a[end], a[maxIndex]);
}
}
选择排序的优化:
一趟排序中,找出最大的和最小的
//选择排序
void SelectSortOP(int *a, int size)
{
assert(a);
int left = 0;
int right = size - 1;
while (left < right)
{
int minIndex = left;
int maxIndex = left;
for (int i = left; i <= right; i++)
{
if (a[minIndex]>a[i])
{
minIndex = i;
}
if (a[maxIndex] < a[i])
{
maxIndex = i;
}
}
swap(a[maxIndex], a[right]);
if (maxIndex == left)
{
maxIndex = right;
}
swap(a[minIndex], a[left]);
}
}
4.堆排序
算法思想:
建一个大堆,第一个元素是最大的,交换第一个和最后一个,然后把剩下的元素组成一个大堆,循环
<pre name="code" class="cpp" style="font-size:12px;">//堆排序
//O(N*lgN)
//向下调整
void AdjustDown(int *a, int size, int parent)
{
assert(a);
int child = parent * 2 + 1;
while (child < size)
{
if (child + 1 < size&&a[child + 1] > a[child])
{
child++;
}
if (a[parent] < a[child])
{
swap(a[parent], a[child]);
}
parent = child;
child = parent * 2 + 1;
}
}
void HeapSort(int *a, int size)
{
assert(a);
//建堆
for (int i = (size - 2) / 2; i >= 0; i--)
{
AdjustDown(a, size, i);
}
//排序
for (int i = size - 1; i >= 1; i--)
{
swap(a[0], a[i]);
AdjustDown(a, i, 0);
}
}
<p style="font-size:12px;"></p><pre name="code" class="cpp"><pre name="code" class="cpp"><span style="font-size:24px;">5.冒泡排序</span><span style="font-size:12px;">
算法思想:
两两比较,把大的元素放后面,循环把最大的放到最后;然后找次大的</span>
<span style="font-size:12px;">
//冒泡排序
void BubbleSort(int *a, int size)
{
assert(a);
for (int i = 0; i < size; i++)
{
for (int j = 0; j < size - i - 1; j++)
{
if (a[j] > a[j + 1])
{
swap(a[j], a[j + 1]);
}
}
}
}
//冒泡排序的优化
void BubbleSortOP(int * a, int size)
{
assert(a);
//定义一个标志位
int flag = true;
while (flag)
{
flag = false;
for (int i = 0; i < size - 1; i++)
{
//如果发生了交换,说明没有排好序
//如果没有发生交换,说明已经排好序了
if (a[i] > a[i + 1])
{
swap(a[i], a[i + 1]);
flag = true;
}
}
size--;
}
}</span>
<span style="font-size:12px;">
</span><pre name="code" class="cpp"><span style="font-size:24px;">6.快速排序</span><span style="font-size:12px;">
算法思想:
找出一个分界点,分为左右两个区间,递归到区间中只有一个元素,这时就是排好序的</span>
<pre name="code" class="cpp" style="font-size:12px;">
//快速排序
//O(n*lgN)……O(n^2)
//选取合适的div
int PartSort(int * a, int left, int right)
{
assert(a);
int key = a[right];
int begin = left;
int end = right - 1;
while (begin < end)
{
while (begin < end&&a[begin] <= key)
{
begin++;
}
while (begin < end&&a[end] >= key)
{
end--;
}
if (begin < end)
{
swap(a[begin], a[end]);
}
}
if (a[begin]>a[right])
{
swap(a[begin], a[right]);
return begin;
}
return right;
}
void QuickSort(int *a, int left, int right)
{
assert(a);
if (left >= right)
{
return;
}
int div = PartSort(a, left, right);
QuickSort(a, left, div - 1);
QuickSort(a, div + 1, right);
}
6.快速排序
算法思想:
找出一个分界点,分为左右两个区间,递归到区间中只有一个元素,这时就是排好序的