C++筆記 劃分與排序演算法

qq_36333986發表於2020-10-15

primer C++筆記

劃分與排序演算法

在這裡插入圖片描述
在這裡插入圖片描述
在這裡插入圖片描述

#include <iostream>
#include <stdlib.h>
#include <algorithm>
#include <array>
#include <vector>
#include <forward_list>
#include <iterator>
#include <random>
using namespace std;

//劃分演算法
namespace Partition
{
	//is_partitioned(beg, end, unaryPred)
	void test01()
	{
		std::array<int, 9> v = { 1, 2, 3, 4, 5, 6, 7, 8, 9 };

		auto is_even = [](int i) { return i % 2 == 0; };
		std::cout.setf(std::ios_base::boolalpha);
		std::cout << std::is_partitioned(v.begin(), v.end(), is_even) << ' ';

		std::partition(v.begin(), v.end(), is_even);
		std::cout << std::is_partitioned(v.begin(), v.end(), is_even) << ' ';

		std::reverse(v.begin(), v.end());
		std::cout << std::is_partitioned(v.begin(), v.end(), is_even);

		//false true false
	}

	//partition_copy(beg, end, dest1, dest2, unaryPred)
	void test02()
	{
		int arr[10] = { 1,2,3,4,5,6,7,8,9,10 };
		int true_arr[5] = { 0 };
		int false_arr[5] = { 0 };

		std::partition_copy(std::begin(arr), std::end(arr), std::begin(true_arr), std::begin(false_arr),
			[](int i) {return i > 5; });

		std::cout << "true_arr: ";
		for (auto x : true_arr) {
			std::cout << x << ' ';
		}
		std::cout << '\n';

		std::cout << "false_arr: ";
		for (auto x : false_arr) {
			std::cout << x << ' ';
		}
		std::cout << '\n';

		/*true_arr: 6 7 8 9 10
		false_arr : 1 2 3 4 5*/
	}

	//partition_point(beg, end, unaryPred)
	void test03()
	{
		std::array<int, 9> v = { 1, 2, 3, 4, 5, 6, 7, 8, 9 };

		auto is_even = [](int i) { return i % 2 == 0; };
		std::partition(v.begin(), v.end(), is_even);

		auto p = std::partition_point(v.begin(), v.end(), is_even);

		std::cout << "Before partition:\n    ";
		std::copy(v.begin(), p, std::ostream_iterator<int>(std::cout, " "));
		std::cout << "\nAfter partition:\n    ";
		std::copy(p, v.end(), std::ostream_iterator<int>(std::cout, " "));

		/*Before partition :
		8 2 6 4
		After partition :
		5 3 7 1 9*/
	}

	//stable_partition(beg, end, unaryPred)
	//partition(beg, end, unaryPred)

	void test04()
	{
		std::vector<int> v{ 0, 0, 3, 0, 2, 4, 5, 0, 7 };
		std::stable_partition(v.begin(), v.end(), [](int n) {return n > 0; });
		for (int n : v) {
			std::cout << n << ' ';
		}
		std::cout << '\n';

		//3 2 4 5 7 0 0 0 0
	}

	template <class ForwardIt>
	void quicksort(ForwardIt first, ForwardIt last)
	{
		if (first == last) return;
		auto pivot = *std::next(first, std::distance(first, last) / 2);
		ForwardIt middle1 = std::partition(first, last,
			[pivot](const auto& em) { return em < pivot; });
		ForwardIt middle2 = std::partition(middle1, last,
			[pivot](const auto& em) { return !(pivot < em); });
		quicksort(first, middle1);
		quicksort(middle2, last);
	}
	void test05()
	{
		std::vector<int> v = { 0,1,2,3,4,5,6,7,8,9 };
		std::cout << "Original vector:\n    ";
		for (int elem : v)
			std::cout << elem << ' ';

		auto it = std::partition(v.begin(), v.end(), [](int i) {return i % 2 == 0; });

		std::cout << "\nPartitioned vector:\n    ";
		std::copy(std::begin(v), it, std::ostream_iterator<int>(std::cout, " "));
		std::cout << " * ";
		std::copy(it, std::end(v), std::ostream_iterator<int>(std::cout, " "));

		std::forward_list<int> fl = { 1, 30, -4, 3, 5, -4, 1, 6, -8, 2, -5, 64, 1, 92 };
		std::cout << "\nUnsorted list:\n    ";
		for (int n : fl)
			std::cout << n << ' ';
		std::cout << '\n';

		quicksort(std::begin(fl), std::end(fl));
		std::cout << "Sorted using quicksort:\n    ";
		for (int fi : fl) std::cout << fi << ' ';
		std::cout << '\n';

		/*Original vector :
		0 1 2 3 4 5 6 7 8 9
		Partitioned vector :
		0 8 2 6 4 * 5 3 7 1 9
		Unsorted list :
		1 30 - 4 3 5 - 4 1 6 - 8 2 - 5 64 1 92
		Sorted using quicksort :
		-8 - 5 - 4 - 4 1 1 1 2 3 5 6 30 64 92*/
	}
}

//排序演算法
namespace Sort
{
	/*sort(beg, end);
	stable_sort(beg, end);
	sort(beg, end, comp);
	stable_sort(beg, end, comp);*/
	void test01()
	{
		std::array<int, 10> s = { 5, 7, 4, 2, 8, 6, 1, 9, 0, 3 };

		// 用預設的 operator< 排序
		std::sort(s.begin(), s.end());
		for (auto a : s) {
			std::cout << a << " ";
		}
		std::cout << '\n';

		// 用標準庫比較函式物件排序
		std::sort(s.begin(), s.end(), std::greater<int>());
		for (auto a : s) {
			std::cout << a << " ";
		}
		std::cout << '\n';

		// 用自定義函式物件排序
		struct {
			bool operator()(int a, int b) const
			{
				return a < b;
			}
		} customLess;
		std::sort(s.begin(), s.end(), customLess);
		for (auto a : s) {
			std::cout << a << " ";
		}
		std::cout << '\n';

		// 用 lambda 表示式排序
		std::sort(s.begin(), s.end(), [](int a, int b) {
			return b < a;
		});
		for (auto a : s) {
			std::cout << a << " ";
		}
		std::cout << '\n';

		/*0 1 2 3 4 5 6 7 8 9
		9 8 7 6 5 4 3 2 1 0
		0 1 2 3 4 5 6 7 8 9
		9 8 7 6 5 4 3 2 1 0*/
	}

	/*is_sorted(beg, end);
	is_sorted(beg, end, comp);
	is_sorted_until(beg, end);
	is_sorted_until(beg, end, comp);*/
	void test02()
	{
		int digits[] = { 3, 1, 4, 1, 5 };

		for (auto i : digits) std::cout << i << ' ';
		std::cout << ": is_sorted: " << std::boolalpha
			<< std::is_sorted(std::begin(digits), std::end(digits)) << '\n';

		std::sort(std::begin(digits), std::end(digits));

		for (auto i : digits) std::cout << i << ' ';
		std::cout << ": is_sorted: "
			<< std::is_sorted(std::begin(digits), std::end(digits)) << '\n';

		/*3 1 4 1 5 : is_sorted: false
		1 1 3 4 5 : is_sorted : true*/
	}

	void test03()
	{
		std::random_device rd;
		std::mt19937 g(rd());
		const int N = 6;
		int nums[N] = { 3, 1, 4, 1, 5, 9 };

		const int min_sorted_size = 4;
		int sorted_size = 0;
		do {
			std::shuffle(nums, nums + N, g);
			int *sorted_end = std::is_sorted_until(nums, nums + N);
			sorted_size = std::distance(nums, sorted_end);

			for (auto i : nums) std::cout << i << ' ';
			std::cout << " : " << sorted_size << " initial sorted elements\n";
		} while (sorted_size < min_sorted_size);

		/*4 1 9 5 1 3  : 1 initial sorted elements
		4 5 9 3 1 1 : 3 initial sorted elements
		9 3 1 4 5 1 : 1 initial sorted elements
		1 3 5 4 1 9 : 3 initial sorted elements
		5 9 1 1 3 4 : 2 initial sorted elements
		4 9 1 5 1 3 : 2 initial sorted elements
		1 1 4 9 5 3 : 4 initial sorted elements*/
	}

	//partial_sort(beg, mid, end);
	//partial_sort(beg, mid, end, comp);
	void test04()
	{
		std::array<int, 10> s{ 5, 7, 4, 2, 8, 6, 1, 9, 0, 3 };

		std::partial_sort(s.begin(), s.begin() + 3, s.end());
		for (int a : s) {
			std::cout << a << " ";
		}
	}

	//partial_sort_copy(beg, end, destBeg, destEnd);
	//partial_sort_copy(beg, end, destBeg, destEnd, comp);
	void test05()
	{
		std::vector<int> v0{ 4, 2, 5, 1, 3 };
		std::vector<int> v1{ 10, 11, 12 };
		std::vector<int> v2{ 10, 11, 12, 13, 14, 15, 16 };
		std::vector<int>::iterator it;

		it = std::partial_sort_copy(v0.begin(), v0.end(), v1.begin(), v1.end());

		std::cout << "Writing to the smaller vector in ascending order gives: ";
		for (int a : v1) {
			std::cout << a << " ";
		}
		std::cout << '\n';
		if (it == v1.end())
			std::cout << "The return value is the end iterator\n";

		it = std::partial_sort_copy(v0.begin(), v0.end(), v2.begin(), v2.end(),
			std::greater<int>());

		std::cout << "Writing to the larger vector in descending order gives: ";
		for (int a : v2) {
			std::cout << a << " ";
		}
		std::cout << '\n' << "The return value is the iterator to " << *it << '\n';

		/*Writing to the smaller vector in ascending order gives : 1 2 3
		The return value is the end iterator
		Writing to the larger vector in descending order gives : 5 4 3 2 1 15 16
		The return value is the iterator to 15*/
	}

	//nth_element(beg, nth, end);
	//nth_element(beg, nth, comp);
	void test06()
	{
		std::vector<int> v{ 5, 6, 4, 3, 2, 6, 7, 9, 3 };

		std::nth_element(v.begin(), v.begin() + v.size() / 2, v.end());
		std::cout << "The median is " << v[v.size() / 2] << '\n';

		std::nth_element(v.begin(), v.begin() + 1, v.end(), std::greater<int>());
		std::cout << "The second largest element is " << v[1] << '\n';

		/*The median is 5
		The second largest element is 7*/
	}
}

相關文章