常见排序算法的c语音实现
头文件sort.h
#ifndef SORT_H_
#define SORT_H_
typedef int ElemetType;
//插入排序
void insertSort(ElemetType list[],int n);
//希尔排序
void shellSort(ElemetType list[],int n);
//堆排序
void heapSort(ElemetType list[],int n);
void heap(ElemetType list[],int i,int n);
//归并排序
void mergeSort(int list[],int n);
void merge(int src[],int temp[],int head,int mid,int rear);
//快速排序(三数中值选择法)
void quickSort(ElemetType list[],int n);
void quickSort(ElemetType list[],int start,int end);
ElemetType median(ElemetType list[],int start,int end);
#endif /* SORT_H_ */
具体实现
#include <stdio.h>
#include <stdlib.h>
#include "sort.h"
/**
* 插入排序由N-1趟排序组成。对于P=1趟到P=N-1趟排序,要保证从下标0到下标P已经排好序
*/
void insertSort(ElemetType list[], int n) {
for (int i = 1, j; i < n; i++) {
int tmp = list[i]; //可减少赋值操作
for (j = i; j >= 1 && tmp < list[j - 1]; j--) {
list[j] = list[j - 1];
}
list[j] = tmp; //为第i个值找到合适位置
}
}
/**
* 希尔排序通过比较相距一定间隔的元素来工作,各趟比较所用的距离随着算法的进行而减小
* 直到只比较相邻元素的最后一趟排序
*/
void shellSort(ElemetType list[], int n) {
//初始距离为数组长度除以2取整
for (int increase = n / 2; increase > 0; increase = increase / 2) {
for (int i = increase; i < n; i++) {
int k, tmp = list[i];
for (k = i; k >= increase; k -= increase) {
if (list[k] < list[k - increase]) {
list[k] = list[k - increase];
} else {
break;
}
}
list[k] = tmp;
}
}
}
/**
* 堆排序
*/
void heapSort(ElemetType list[], int n) {
//先将数组用二叉堆表示
for (int i = 9 / 2 - 1; i >= 0; i--)
heap(list, i, 9);
//将第一个元素(数组最大值)与最后一个交换后,数组长度减1,然后对下标为0的元素进行最大堆排列
for (int i = n - 1; i >= 0; i--) {
int tmp = list[i];
list[i] = list[0];
list[0] = tmp;
heap(list, 0, i);
}
}
//对下标为i的元素进行最大堆排列。当前:i,父亲 :(i-1)/2,左孩子:2*i+1,右孩子:(i+1)*2
void heap(ElemetType list[], int i, int n) {
int up, left, right, tmp;
left = 2 * i + 1;
right = 2 * i + 2;
if (left < n && right < n)
up = list[left] > list[right] ? left : right;
else if (left < n && right >= n)
up = left;
else
return;
if (list[up] > list[i]) {
tmp = list[i];
list[i] = list[up];
list[up] = tmp;
heap(list, up, n);
}
}
/**
* 归并排序,经典递归算法
*/
void mergeSort(int list[], int n) {
ElemetType *temp = (ElemetType*) malloc(sizeof(ElemetType) * n);
for (int i = 0; i < n; i++)
temp[i] = list[i];
merge(list, temp, 0, n / 2, n - 1);
free(temp);
}
//合并
void merge(int src[], int temp[], int head, int mid, int rear) {
if (mid == head && mid == rear) {
return;
} else {
merge(src, temp, head, (head + mid) / 2, mid);
merge(src, temp, mid + 1, (rear + mid + 1) / 2, rear);
int i, m, n;
for (i = head, m = head, n = mid + 1; m <= mid && n <= rear; i++) {
if (temp[m] < temp[n]) {
src[i] = temp[m];
m++;
} else {
src[i] = temp[n];
n++;
}
}
for (; m <= mid; i++, m++)
src[i] = temp[m];
for (; n <= rear; n++, i++)
src[i] = temp[n];
for (i = head; i <= rear; i++)
temp[i] = src[i];
}
}
/**
* 快速排序(三数中值选择枢纽值法)
*/
void quickSort(ElemetType list[], int n) {
quickSort(list, 0, n - 1);
}
void quickSort(ElemetType list[], int start, int end) {
if (start >= end)
return;
ElemetType pivot = median(list, start, end); //枢纽值
ElemetType temp;
int i = start, j = end - 1;
while (true) {
for (; i < j && list[i] < pivot; i++)
;
for (; j > i && list[j] > pivot; j--)
;
if (i == j)
break;
temp = list[i];
list[i] = list[j];
list[j] = temp;
}
list[end] = list[i];
list[i] = pivot;
quickSort(list, start, i - 1);
quickSort(list, i + 1, end);
}
//返回start、end、和(start+end)/2位置上的中值
ElemetType median(ElemetType list[], int start, int end) {
int mid = (start + end) / 2;
int a, b; //a记录大的,b记录第二大的
ElemetType temp;
if (list[start] >= list[mid]) {
a = start;
b = mid;
} else {
a = mid;
b = start;
}
if (list[end] > list[mid]) {
b = end;
}
if (list[b] > list[a]) {
b = a;
}
temp = list[b];
list[b] = list[end];
list[end] = temp;
return list[end];
}
测试
int main() {
ElemetType list[] = { 5, 2, 6, 8, 7, 4, 3, 1, 9 };
//插入排序
insertSort(list,9);
//希尔排序
shellSort(list,9);
//堆排序
heapSort(list, 9);
//归并排序
mergeSort(list, 9);
//快速排序
quickSort(list,9);
for (int i = 0; i < 9; i++)
printf("%d ", list[i]);
return 0;
}