头文件sortDemo.h
#pragma once
#include<stdio.h>
#include<stdlib.h>
#include<time.h>
#include<stdbool.h>
int getRand(int,int);
void maoPao(int[],int);
void maoPao1(int[], int);
void selectSort(int[], int);
void selectSort1(int[], int);
void insertSort(int[], int);
void mergeSort(int[],int,int);
void merge(int[], int, int, int, int);
void reverse(int[], int, int);
int getMid(int[],int,int);
void quickSort(int[], int, int);
bool isLeaf(int, int);
void buildHeap(int[], int);
void heapSort(int[],int);
源文件seortDemo.c
#include "sortDemo.h"
void maoPao(int arr[],int n) //冒泡排序,两两比较,逐次前移,升序排列,arr长度为n
{
int temp = 0;
bool sign = false;
for (int i = 0; i < n; i++) {
for (int j = n - 1; j > i; j--) {
if (arr[j] < arr[j - 1]) {
temp = arr[j];
arr[j] = arr[j - 1];
arr[j - 1] = temp;
sign = true;
}
}
if (sign == false)
break;
else
sign = false;
}
}
void maoPao1(int arr[], int n)
{
int temp = 0;
bool sign = false;
for (int i = n-1; i>=0; i--) {
for (int j = 0; j <i; j++) {
if (arr[j] > arr[j+1]) {
temp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = temp;
sign = true;
}
}
if (sign == false)
break;
else
sign = false;
}
}
void selectSort(int arr[], int n)//选择排序,升序,寻找最大(小)下标,依次前移
{
int temp0,temp1;
for (int i = 0; i < n-1; i++) {
temp0 = arr[i]; //假定最小值有效
temp1 = i; //假定最小值下标
for (int j = i; j < n; j++) {
if (arr[j] < temp0) {
temp0 = arr[j];
temp1 = j;
}
}
arr[temp1] = arr[i];
arr[i] = temp0;
}
}
void selectSort1(int arr[], int n)
{
int temp0, temp1;
for (int i = n-1; i>0; i--) {
temp0 = arr[i]; //假定最大值有效
temp1 = i; //假定最大值下标
for (int j = i; j>=0; j--) {
if (arr[j] > temp0) {
temp0 = arr[j];
temp1 = j;
}
}
arr[temp1] = arr[i];
arr[i] = temp0;
}
}
void insertSort(int arr[], int n) { //插入排序,升序排列
int temp = 0;
for (int i = 0; i < n-1; i++) {
for (int j = i + 1; j > 0; j--) { //将j元素插入前排
if (arr[j] < arr[j - 1]) {
temp = arr[j];
arr[j] = arr[j - 1];
arr[j - 1] = arr[j];
}
else {
break;
}
}
}
}
void reverse(int arr[], int stIn, int endIn) //倒转序列
{
int temp = 0;
for (int i = stIn; i <= (stIn + endIn) / 2; i++) { //关键位置,注意小于等于,而不是小于
temp = arr[i];
arr[i] = arr[endIn + stIn - i];
arr[endIn + stIn - i] = temp;
}
}
void merge(int arr[], int st0, int end0, int st1, int end1)
{
if (st0 > end0 || st1 > end1) //一个序列为空,直接返回即可
return;
else {
if (arr[end1] <= arr[st0]) { //将后排全部插入前排之前 ,关键位置
reverse(arr, st0, end0);
reverse(arr, st1, end1);
reverse(arr, st0, end1);
}
else if (arr[st1] >= arr[end0]) //关键位置
{
//不用处理
}
else {
int i, j,k=0;
int *tempArr=(int*)malloc(sizeof(int)*(end1-st0+1)); //创建一个新的数组
for (i = st0, j = st1; i <= end0 && j <= end1;) {
if (arr[i] <= arr[j]) {
tempArr[k++] = arr[i];
i++;
}
else {
tempArr[k++] = arr[j];
j++;
}
if (i > end0 && j <= end1) { //后面的序列均比已排序列大
for (; j <= end1; j++) {
tempArr[k++] = arr[j];
}
break;
}
else if (i <= end0 && j > end1) { //前面的序列均比已排序列大,
for (; i <= end0; i++) {
tempArr[k++] = arr[i];
}
break;
}
}
for (i = st0,k=0; i <= end1; i++,k++) {
arr[i] = tempArr[k];
}
free(tempArr); //注意释放内存
}
}
}
void mergeSort(int arr[], int startIn, int endIn) { //二路归并排序
if (endIn <= startIn)
return;
else {
mergeSort(arr, startIn, (startIn + endIn) / 2);
mergeSort(arr, (startIn + endIn) / 2 + 1, endIn); //分路
//对arr[startIn, (startIn + endIn) / 2]与arr[(startIn + endIn) / 2 + 1, endIn]两路归并处理
merge(arr, startIn, (startIn + endIn) / 2, (startIn + endIn) / 2 + 1, endIn);
}
}
int getRand(int range, int min) {
return (rand() % range + min);
}
int getMid(int arr[],int startIn,int endIn) { //得到三个数字的中位数
srand((unsigned)time(NULL));
int keys[3];
int a, b, c;
for (int i = 0; i < 3; i++) {
keys[i] = getRand(endIn - startIn + 1, startIn); //得到[startIn,endIn]上的一个随机数,作为随机下标
}
a = keys[0];
b = keys[1];
c = keys[2];
if (arr[a] >= arr[b] && arr[a] <= arr[c] || arr[a] >= arr[c] &&arr[a] <= arr[b])
return a;
else if (arr[b] >= arr[a] && arr[b] <= arr[c] || arr[b] >= arr[c] &&arr[b] <= arr[a])
return b;
else
return c;
}
void quickSort(int arr[], int startIn, int endIn) { //快速排序,升序
if (endIn <= startIn)
return;
int keyIn = getMid(arr,startIn,endIn);
int temp1 = arr[keyIn];
arr[keyIn] = arr[startIn];
arr[startIn] = temp1;
keyIn = startIn;
int keyWord = arr[keyIn]; //关键字
int j = endIn, i = startIn;
int temp = 0;
while (i < j) {
for (; j >= startIn;) {
if (keyWord < arr[j])
j--;
else
break;
}
for (; i <= endIn; ) {
if (keyWord >= arr[i])
i++;
else
break;
}
if (j <= i)
break;
temp = arr[j];
arr[j] = arr[i];
arr[i] = temp;
}
temp = arr[keyIn];
arr[keyIn] = arr[j];
arr[j] = temp;
quickSort(arr, startIn, j - 1);
quickSort(arr, j + 1, endIn);
}
bool isLeaf(int curIn, int count) //判断该下标结点是否是叶子元素
{
return 2*curIn+1>=count;
}
//下标i元素的孩子结点元素下标为2*i+1,2*i+2,父节点的下标为(i-1)/2,i>=1。
void buildHeap(int arr[], int count) { //使用数组形式表示堆(特殊的完全二叉树),建造最大堆
int rootIn = 0; //根结点下标
for (int i = count - 1; i >= 0; i--) {
if (!isLeaf(i, count)) {
break;
}
else {
int parentIn = (i - 1) / 2; //当前结点的父节点下标
int curIn = i; //当前结点下标
int temp;
while (curIn>rootIn) {
if (arr[parentIn] < arr[curIn]) {
temp = arr[parentIn];
arr[parentIn] = arr[curIn];
arr[curIn] = temp;
}
curIn = parentIn;
parentIn = (parentIn - 1) / 2;
}
}
}
}
void heapSort(int arr[], int count)
{
int temp;
for (int i = 0; i < count - 1; i++) {
buildHeap(arr, count - i);
temp = arr[0];
arr[0] = arr[count - i-1];
arr[count - i-1] = temp;
}
}
测试代码test.c
#include"sortDemo.h"
void printRe(int arr[], int line,int count) { //输出排序结果,line为每行打印的数据数目
for (int i = 0; i < count; i++) {
printf("%-5d ", arr[i]); //左对齐,占5位
if ((i + 1) % line == 0)
printf("\n");
}
}
bool checkRe(int arr[], int count) { //验证结果是升序的函数
for (int i = 0; i < count-1; i++) {
if (arr[i] > arr[i + 1])
return false;
}
return true;
}
int main() {
int count = 1000; //随机数个数,范围[1,10000]
int arr[1000];
srand((unsigned)time(NULL));
for (int i = 0; i < count; i++) {
arr[i] = getRand(10000,0); //生成测试数组
}
//maoPao(arr,count); //冒泡
//maoPao1(arr,count); //冒泡
//selectSort(arr,count); /选择
//selectSort1(arr, count); //选择
//insertSort(arr, count); //插入
//mergeSort(arr, 0, count - 1); //有效下标范围,归并
quickSort(arr, 0, count - 1); //快排
//heapSort(arr, count); //堆排序
printRe(arr, 10, count);
bool re=checkRe(arr, count);
printf("%d\n", re);
return 0;
}
网上已经有很多各种基础算法的分析,于是此处不在赘述,但关于时间效率的测试结果会在接下来的一篇博文中进行图文并茂的描述,还请期待一下。还有就是上述所有代码均是在VS2015上编译通过并且运行成功,可能由于编译器版本或者平台不同造成错误的地方就是关于<stdbool.h
>头文件的使用,大家可以自行定义bool类型。