排序算法
主要是算法导论的内容,第二章提到插入排序、归并排序(递归、分治)
另外补充了的排序方法冒泡排序、选择排序、快速排序
具体思路可以参考百度百科感觉已经讲得很详细,都是基础算法
以下代码是自己的一些理解,可能跟书本不一样,或者跟最优、最简不同,欢迎提出。
TODO:其他排序算法待更新
main函数中切换不同算法
/*
算法导论第二章-排序算法
插入排序、归并排序(递归、分治)
另外的排序方法冒泡排序、选择排序、快速排序
TODO:其他排序算法待更新
*/
#include "pch.h"
#include<stdio.h>
#include<windows.h>
//数组
int array[] = {2,1,3,6,2,5};
//=================================================
//打印数组
void printArray(int *a,int n) {
for (int i = 0; i < n; i++) {
printf("%d ", a[i]);
}
printf("\n");
}
//=================================================
//插入排序------2,1,3,6,2,5
void insert_sort(int *a, int n) {
for (int i = 1; i < n; i++) {
int temp = a[i];
int j = i-1;
//与排好序的数组比较,将最新的值插入到合适位置
while(j >= 0 && temp < a[j]) {
a[j + 1] = a[j];//向后移动
j--;
}
a[j + 1] = temp;
//打印当前结果
printArray(array, 6);
}
}
//=================================================
//归并排序------2,1,3,6,2,5
//合并两个子序列
void Merge(int sourceArr[],int startIndex, int midIndex, int endIndex)
{
int tempArr[6];
int i = startIndex, j = midIndex + 1, k = startIndex;
//分别从两个子序列开头比较,合并成一个序列
while (i != midIndex + 1 && j != endIndex + 1)
{
if (sourceArr[i] > sourceArr[j])
tempArr[k++] = sourceArr[j++];
else
tempArr[k++] = sourceArr[i++];
}
//某个子序列剩余
while (i != midIndex + 1)
tempArr[k++] = sourceArr[i++];
while (j != endIndex + 1)
tempArr[k++] = sourceArr[j++];
for (i = startIndex; i <= endIndex; i++)
sourceArr[i] = tempArr[i];
//打印当前结果
printArray(array, 6);
}
//内部使用递归
void MergeSort(int sourceArr[], int startIndex, int endIndex)
{
int midIndex;
if (startIndex < endIndex)
{
midIndex = startIndex + (endIndex - startIndex)/2;
MergeSort(sourceArr, startIndex, midIndex);
MergeSort(sourceArr, midIndex + 1, endIndex);
Merge(sourceArr, startIndex, midIndex, endIndex);
}
}
//=================================================
//非递归------2,1,3,6,2,5
void MergePass(int sourceArr[],int len,int k) {
int i = 0;//从头开始排序,步长为k
int *tempArr = new int[len];
//对k步长序列merge,最后一个步长可能小于2k长度,另外处理
while (i < len - 2 * k + 1) {
Merge(sourceArr, i, i + k - 1, i + 2 * k - 1);//merge的l、mid、r
i += 2 * k;
}
//最后一组序列处理
if (i < len - k) {
Merge(sourceArr, i, i + k - 1, len - 1);
}
delete[]tempArr;
}
void MergeSort2(int sourceArr[],int len) {
int k = 1;//步长k
while (k<len) {
MergePass(sourceArr,len,k);
k *= 2;//2倍,例1、2、4、8
}
}
//=================================================
//冒泡排序------2,1,3,6,2,5
void BubbleSort(int *a, int n) {
//循环遍历,比较相邻大小,按从小到大排列
for (int i = 0; i < n - 1; i++) {
for (int j = i+1; j < n; j++) {
if (a[i] > a[j]) {
int temp = a[i];
a[i] = a[j];
a[j] = temp;
}
}
}
//打印当前结果
printArray(array, 6);
}
//=================================================
//选择排序-------2,1,3,6,2,5
void SelectionSort(int *a, int n) {
//循环遍历,每次选取最小值,按从小到大排列
for (int i = 0; i < n - 1; i++) {
int min = a[i];
int index = i;//记录最小值下标
for (int j = i + 1; j < n; j++) {
if (a[j] < min) {
index = j;
min = a[j];
}
}
//如果最小值改变,则交换位置
if (index != i) {
int temp = a[i];
a[i] = a[index];
a[index] = temp;
}
}
//打印当前结果
printArray(array, 6);
}
//=================================================
//快速排序------2,1,3,6,2,5
void QuickSort(int *a,int low,int high) {
if (low >= high) return;
int i = low;
int j = high;
int key = a[i];
//以第一个值为分界值
while (true) {
//从右往左找比key小的值,从左往右找比key大的值,找到之后互相交换
while (i<j&&a[j]>=key)j--;
while (i<j&&a[i]<=key)i++;
//如果还有元素未分,则交换i和j的两个,否则break,把当前key放到中间位置
if (i >= j)break;
int temp = a[j];
a[j] = a[i];
a[i] = temp;
}
//把当前key和第一个元素交换位置
a[low] = a[j];
a[j] = key;
//递归排序
QuickSort(a, low, j - 1);
QuickSort(a, j + 1, high);
//打印当前结果
printArray(array, 6);
}
int main() {
printArray(array, 6);
//printf("Insert sort:\n");
//insert_sort(array, 6);
//printf("Merge sort:\n");
//MergeSort(array,0,5);
//printf("Merge sort 2:\n");
//MergeSort2(array,6);
//printf("Bubble sort:\n");
//BubbleSort(array,6);
//printf("Selection sort:\n");
//SelectionSort(array,6);
printf("Quick sort:\n");
QuickSort(array,0,5);
system("pause");
return 0;
}