数据结构——排序
排序
简单排序
- 选择排序
- 冒泡排序
- 插入排序
选择排序
排序思想:
- 将排序序列分为已经有序和待排序两部分
- 每次从待排序的序列中选出最小的放到已排序末尾
性质:不稳定
void sort1(int a[], int n)
{
for (int i = 0; i < n - 1; i ++ ){ //选择n-1次
int min_id = i; //默认当前待排序的第一个为最小
for (int j = i; i < n; j ++ )
if (a[j] < a[min_id])
min_id = j;
//找到最小值, 交换:
swap(a[i], a[min_id]);
}
}
冒泡排序
排序思想:
反复比较两两相邻元素,若不符合顺序要求,则交换相邻元素,直至有序
性质: 稳定
void sort2(int a[], int n)
{
for (int i = 0; i < n - 1; i ++ ){
int flag = 1;
for (int j = 0; j < n - i - 1; j ++ )
if (a[j] > a[j + 1])
swap(a[j], a[j + 1]), flag = 0;
if (flag)
break;
}
}
插入排序
排序思想:
- 将序列分为待排序和已排序两部分
- 每次从待排序的部分选择一个插入到已排序部分(这里采用不断向前渗透的方法)
void sort3(int a[], int n)
{
for (int i = 2; i <= n; i ++ ){
a[0] = a[i];
for (int j = i; a[j] < a[j - 1]; j -- )
swap(a[j], a[j - 1]);
}
}
先进排序
快速排序
排序思想:
- 对待排序序列进行划分
- 对前半部分排序
- 对后半部分排序
性质:不稳定
划分:
从序列中选择一个元素作为划分依据,将序列分为前后两部分
//划分:
int Part(int a[], int l, int r)
{
int tmp = a[l];
while (l < r){
while (l < r && a[r] >= tmp)
r --;
a[l] = a[r];
while (l < r && a[l] <= tmp)
l ++;
a[r] = a[l];
}
a[l] = tmp;
return l;
}
//排序:
void sort3(int a[], int l, int r)
{
if (l >= r)
return;
int k = Part(a, l, r);
sort3(a, l, k - 1);
sort3(a, k + 1, r);
return;
}
堆排序
堆:完全二叉树
大顶堆:父节点的值大于等于子节点的值
小顶堆: 父节点的值小于等于子节点的值
堆调整
void Aheap(int s, int n)
{
int i = s;
while (2 * i + 1 < n){
int j = 2 * i + 1;
if (j + 1 < n && heap[j + 1] > heap[j]) j ++;
if (heap[i] >= heap[j]) break;
swap(heap[i], heap[j]);
i = j;
}
}
建堆
void Build(int n)
{
for (int i = n / 2 - 1; i >= 0; i -- )
Aheap(i, n);
}
排序
void HeapSort(int n)
{
Build(n);
for (int i = n - 1; i > 0; i -- ){
swap(heap[0], heap[i]);
Aheap(0, i);
}
}

浙公网安备 33010602011771号