十个经典排序算法

十个经典排序算法

快排

/* 快速排序 */
#include <iostream>
#include <cstdlib>

#define N 6

using namespace std;

void quick_sort(int arr[], int begin, int end);
void print_arr(int arr[], int n);

int main()
{
	int arr[N] = {10, 4,7, 10, 4,7};
	cout << "排序前:" << endl;
	print_arr(arr, N);
	quick_sort(arr, 0, N);
	cout << "排序后:" << endl;
	print_arr(arr, N);
}

// 不包含 end 
void quick_sort(int arr[], int begin, int end)
{
	if (end - begin <= 1)
		return;
	swap(arr[begin], arr[(begin + end) / 2]);
	int pivot = arr[begin];
	int i = begin + 1;
	int j = end - 1;
	while (i < j)
	{
		while (i < end - 1 && arr[i] < pivot)
			i++;
		while (j > begin && arr[j] > pivot)
			j--;
		if (i < j)
			swap(arr[i], arr[j]);
	}
	if (j < i)
		swap(arr[j], arr[begin]);
	quick_sort(arr, begin, j);
	quick_sort(arr, j + 1, end);
}

 
void print_arr(int arr[], int n)
{
	for (int i = 0; i < n; i++)
		cout << arr[i] << " ";
	cout << endl;
}

快排的要点

i 和 j 的关系

当 i < j 时,才能进行循环的移动和交换

每次让 i 指向从左到右,大于 pivot 的数

每次让 j 指向从右到左,小于 pivot 的数

当循环结束时,j 有两种情况,一种是 等于 i 一种是 小于 i

如果 j == i 的话,那么说明此时已经是有序了,不用再进行调换,如果调换反而会打乱顺序

如果 j < i 的话,说明 j 指向的是最后一个小于 pivot 的数,让他们换个位置

归并排序

/*归并排序*/
#include <iostream>
#include <cstdlib>
#include <string>

#define N 10

using namespace std;

void merge_sort(int arr[], int begin, int end); 
void print_arr(int arr[], int n);

int main()
{
	int arr[N] = {1,2,1,1,2,1,1,2,1,87};
	cout << "排序前:" << endl;
	print_arr(arr, N);
	merge_sort(arr, 0, N);
	cout << "排序后:" << endl;
	print_arr(arr, N);
}

void merge_sort(int arr[], int begin, int end)
{
	if (end - begin <= 1)
		return;
	int * new_arr = new int[end - begin];
	merge_sort(arr, begin, (begin + end) / 2);
	merge_sort(arr, (begin + end) / 2, end);
	int i = begin;
	int j = (begin + end) / 2;
	int k = 0;
	while (i < (begin + end) / 2 && j < end)
		new_arr[k++] = arr[i] < arr[j] ? arr[i++] : arr[j++];
	while (i < (begin + end) / 2)
		new_arr[k++] = arr[i++];
	while (j < end)
		new_arr[k++] = arr[j++];
	while (k)
		arr[begin + k - 1] = new_arr[--k];
	delete new_arr;
}

 
void print_arr(int arr[], int n)
{
	for (int i = 0; i < n; i++)
		cout << arr[i] << " ";
	cout << endl;
}

归并排序主要要注意的就是要造个新数组,把两个已经有序的子数组依次按从小到大放到新数组里面

计数排序

/* 计数排序 */
#include <iostream>
#include <cstdlib>

#define N 10


using namespace std;

void count_sort(int arr[], int n); 
void print_arr(int arr[], int n);

int main()
{
	int arr[N] = {5,4,3,2,1,5,4,3,2,1};
	cout << "排序前:" << endl;
	print_arr(arr, N);
	count_sort(arr, N);
	cout << "排序后:" << endl;
	print_arr(arr, N);
}

void count_sort(int arr[], int n)
{
	int max = arr[0];
	for (int i = 0; i < n; i++)
		if (arr[i] > max)
			max = arr[i];
	int * count = (int * )calloc(max + 1, sizeof(int));	// count 数组存放 0-max 每个数出现的次数
	
	for (int i = 0; i < n; i++)
		count[arr[i]]++;
	
	for (int i = 1; i <= max; i++)
		count[i] += count[i-1];
	
	int curr = 0;
	int i = 0;
	while (curr <= max)
	{
		while (count[curr] > i)
			arr[i++] = curr;
		curr++;
	}
	
}

 
void print_arr(int arr[], int n)
{
	for (int i = 0; i < n; i++)
		cout << arr[i] << " ";
	cout << endl;
}

希尔排序

希尔排序的稳定性_百度知道 (baidu.com)

/* shell 排序 */

#include <iostream>
#include <cstdlib>

#define N 3

using namespace std;

void shell_sort(int arr[], int n); 
void print_arr(int arr[], int n);
void bubble_sort(int arr[], int n, int begin, int step);

int main()
{
	int arr[N] = {1,2,0};
	cout << "排序前:" << endl;
	print_arr(arr, N);
	shell_sort(arr, N);
	cout << "排序后:" << endl;
	print_arr(arr, N);
}

void shell_sort(int arr[], int n)
{
	for (int step = n/2; step > 0; step /= 2)
		for (int i = 0; i < step; i++)
			bubble_sort(arr, n, i, step);
	
}

void print_arr(int arr[], int n)
{
	for (int i = 0; i < n; i++)
		cout << arr[i] << " ";
	cout << endl;
} 

void bubble_sort(int arr[], int n, int begin, int step)
{
	bool changed = false;
	for (int i = begin; i < n; i += step)
	{
		changed = false;
		for (int j = begin; j < n - step; j += step)
		{
			if (arr[j] > arr[j + step])
			{
				int temp = arr[j + step];
				arr[j + step] = arr[j];
				arr[j] = temp;
				changed = true;
			}
		}
		if (!changed)
			break;
	}
}

堆排序

【算法】排序算法之堆排序 - 知乎 (zhihu.com)

堆排序很好

/* 堆排序 */
#include <iostream>
#include <cstdlib>

#define N 12

using namespace std;

void heap_sort(int arr[], int n); 
void print_arr(int arr[], int n);
void heapify(int arr[], int n);

int main()
{
	int arr[N] = {5,4,3,2,1,5,4,7,8,3,2,1};
	cout << "排序前:" << endl;
	print_arr(arr, N);
	heap_sort(arr, N);
	cout << "排序后:" << endl;
	print_arr(arr, N);
}

void heap_sort(int arr[], int n)
{
	heapify(arr, n);
	for (int i = n; i > 1; i--)
	{
		swap(arr[i - 1], arr[0]);
		heapify(arr, i - 1);
	}
}

//完全二叉树 编号从1开始 
void heapify(int arr[], int n)
{
	for (int i = 2; i <= n; i++)
		for (int j = i; j > 1; j /= 2)
			if (arr[j - 1] > arr[j/2 - 1])
				swap(arr[j - 1], arr[j/2 - 1]);
}
 
void print_arr(int arr[], int n)
{
	for (int i = 0; i < n; i++)
		cout << arr[i] << " ";
	cout << endl;
}

桶排序

【算法】排序算法之桶排序 - 知乎 (zhihu.com)

桶排序算法 (biancheng.net)

基数排序(需要先修桶排序)

【算法】排序算法之基数排序 - 知乎 (zhihu.com)

posted @ 2021-11-01 00:02  lucky_doog  阅读(52)  评论(0编辑  收藏  举报