插入排序
插入排序的基本思想,见大佬的博客,算法图解之三种简单排序和和漫画:什么是插入排序,下面是C语言实现。
void insert_sort(int[] array, int length)
{
for(int i = 1; i < length;i++)
{
//将value的值保存下来
int InsertValue = array[i];
int j = i - 1;
for(; j >= 0 && InsertValue < array[i]; j--)
{
array[j + 1] = array[j];
}
//InsertValue的值插入适当的位置
array[j + 1] = InsertValue;
}
}
希尔排序
希尔排序是插入排序的一个改进版本,具体解释,看大佬的博客,算法图解之希尔排序,里面说得很好,代码是JAVA实现的,我这里用C实现以下。
void shell_sort(int *array, int length) {
int gap, i, j;
int temp;
for (gap = length >> 1; gap > 0; gap >>= 1)
for (i = gap; i < len; i++) {
temp = array[i];
for (j = i - gap; j >= 0 && array[j] > temp; j -= gap)
array[j + gap] = array[j];
array[j + gap] = temp;
}
}
堆排序
堆排序是利用二叉堆进行的排序,具体的解释,看大佬的博客,算法图解之堆排序,里面说得很详细了,我就不说了,下面是算法的C语言实现
#include <stdio.h>
#include <stdlib.h>
void swap(int *a, int *b) {
int temp = *b;
*b = *a;
*a = temp;
}
void max_heapify(int array[], int start, int end) {
// 建立父节点指示标和子节点指示标
int dad = start;
int son = dad * 2 + 1;
while (son <= end) { // 若子节点指示标在范围内才进行指示
if (son + 1 <= end && arr[son] < arr[son + 1]) // 先比较两个子节点大小,选择大的
son++;
if (arr[dad] > arr[son]) //如果父节点大于子节点代表调节完成,直接跳出函数
return;
else { // 否则交换父子节点内容再继续子节点和孙结点内容比较
swap(&arr[dad], &arr[son]);
dad = son;
son = dad * 2 + 1;
}
}
}
void heap_sort(int arr[], int len) {
int i;
// 初始化,i从最后一个父节点开始调整
for (i = len / 2 - 1; i >= 0; i--)
max_heapify(arr, i, len - 1);
// 先将第一位元素和已排好元素前一位交换,再重新调整,直到排序完毕。
for (i = len - 1; i > 0; i--) {
swap(&arr[0], &arr[i]);
max_heapify(arr, 0, i - 1);
}
}
int main() {
int arr[] = {9, 8, 7, 6, 5, 4, 3, 2, 1, 0};
int len = (int) sizeof(arr) / sizeof(*arr);
heap_sort(arr, len);
int i;
for (i = 0; i < len; i++)
printf("%d ", arr[i]);
printf("\n");
return 0;
}
归并排序
归并排序,算法的图解,还是见大佬的讲解,算法图解之归并排序,下面是C语言实现,有递归和迭代两个版本
迭代版本
int min(int x, int y) {
return x < y ? x : y;
}
void merge_sort(int arr[], int len) {
int *a = arr;
int *b = (int *) malloc(len * sizeof(int));
int seg, start;
for (seg = 1; seg < len; seg += seg) {
for (start = 0; start < len; start += seg * 2) {
int low = start, mid = min(start + seg, len), high = min(start + seg * 2, len);
int k = low;
int start1 = low, end1 = mid;
int start2 = mid, end2 = high;
while (start1 < end1 && start2 < end2)
b[k++] = a[start1] < a[start2] ? a[start1++] : a[start2++];
while (start1 < end1)
b[k++] = a[start1++];
while (start2 < end2)
b[k++] = a[start2++];
}
int *temp = a;
a = b;
b = temp;
}
if (a != arr) {
int i;
for (i = 0; i < len; i++)
b[i] = a[i];
b = a;
}
free(b);
}
递归版本
void merge_sort_recursive(int arr[], int reg[], int start, int end) {
if (start >= end)
return;
int len = end - start, mid = (len >> 1) + start;
int start1 = start, end1 = mid;
int start2 = mid + 1, end2 = end;
merge_sort_recursive(arr, reg, start1, end1);
merge_sort_recursive(arr, reg, start2, end2);
int k = start;
while (start1 <= end1 && start2 <= end2)
reg[k++] = arr[start1] < arr[start2] ? arr[start1++] : arr[start2++];
while (start1 <= end1)
reg[k++] = arr[start1++];
while (start2 <= end2)
reg[k++] = arr[start2++];
for (k = start; k <= end; k++)
arr[k] = reg[k];
}
void merge_sort(int arr[], const int len) {
int reg[len];
merge_sort_recursive(arr, reg, 0, len - 1);
}