算法笔记(1)—— 各类排序算法

排序算法

主要是算法导论的内容,第二章提到插入排序、归并排序(递归、分治)
另外补充了的排序方法冒泡排序、选择排序、快速排序

具体思路可以参考百度百科感觉已经讲得很详细,都是基础算法

以下代码是自己的一些理解,可能跟书本不一样,或者跟最优、最简不同,欢迎提出。

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;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值