标准库STL算法Algorithm

本文详细解析了求解二叉树最小深度的两种算法:递归法和层序遍历法。递归法通过判断左右子树的深度来确定最小深度,而层序遍历法则采用广度优先搜索策略,逐层遍历直至找到首个叶子节点。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

目录

Non-modifying sequence operations

Modifying sequence operations

​Partitions

Sorting

​Binary search

Merge

Heap

Min/max

Other


​        The header <algorithm> defines a collection of functions especially designed to be used on ranges of elements.

        A range is any sequence of objects that can be accessed through iterators or pointers, such as an array or an instance of some of the STL containers. Notice though, that algorithms operate through iterators directly on the values, not affecting in any way the structure of any possible container (it never affects the size or storage allocation of the container).

Non-modifying sequence operations

存在:all_of 、any_of、 none_of

    vector<int>nums{ 1,2,3,4,5,6,7,8,9 };
	std::cout << boolalpha;
	{
		//bool all_of (InputIterator first, InputIterator last, UnaryPredicate pred)		
		bool bGreaterZero = std::all_of(nums.begin(), nums.end(), [](int i) { return i > 0; });
		std::cout << "nums全部大于0:" << bGreaterZero << std::endl;

		//bool any_of (InputIterator first, InputIterator last, UnaryPredicate pred)
		bool bExistEven = std::any_of(nums.begin(), nums.end(), [](int i) { return (i & 1) == 0; });
		std::cout << "nums存在偶数:" << bExistEven << std::endl;

		//bool none_of (InputIterator first, InputIterator last, UnaryPredicate pred)
		bool bNoExistOdd = std::none_of(nums.begin(), nums.end(), [](int i) { return (i & 1) == 1; });
		std::cout << "nums不存在奇数:" << bNoExistOdd << std::endl;
	}

/*
nums全部大于0:true
nums存在偶数:true
nums不存在奇数:false
*/

遍历:for_each

Function for_each(InputIterator first, InputIterator last, Function fn)

for_each(nums.begin(), nums.end(), [](int num) {std::cout << " " << num << " "; });

//1  2  3  4  5  6  7  8  9

查找:find、find_if、find_if_not

// InputIterator find (InputIterator first, InputIterator last, const T& val) find first equals val
	{
		auto iter = std::find(nums.begin(), nums.end(), 4);
		if (iter != nums.end())
		{
			std::cout << std::endl << "找到nums中:" << *iter << std::endl;
		}
	}

	//InputIterator find_if (InputIterator first, InputIterator last, UnaryPredicate pred) find first
	{
		auto iter = std::find_if(nums.begin(), nums.end(), [](int num) { return num % 3 == 0; });
		std::cout << "nums中第一个3的倍数:" << *iter << std::endl;
	}

	//InputIterator find_if_not (InputIterator first, InputIterator last, UnaryPredicate pred)
	{
		//第一个不满足pred(返回false)的元素
		auto iter = std::find_if_not(nums.begin(), nums.end(), [](int num) { return (num & 1) == 1; });
		std::cout << "nums中第一个偶数:" << *iter << std::endl;
	}

/*
找到nums中:4
nums中第一个3的倍数:3
nums中第一个偶数:2
*/

查找序列匹配 :find_first_of find_end

//寻找最先匹配的序列
	{
		vector<int>nums1{ 1,2,3,4,5,6,7,6,5,1,2,3,4 };
		vector<int>nums2{ 1,2,3,4 };
		auto it = std::find_first_of(nums1.begin(), nums1.end(), nums2.begin(), nums2.begin() + 3);
		if (it != nums1.end())
		{
			std::cout << "nums中最先完全匹配123的起始下标:" << (it - nums1.begin()) << endl;
		}
		auto it2 = std::find_first_of(nums1.begin(), nums1.end(), nums2.begin(), nums2.begin() + 3, [](int i, int j) { return i == j + 1; });
		if (it2 != nums1.end())
		{
			std::cout << "nums中最先匹配123每个+1的起始下标:" << (it2 - nums1.begin()) << endl;
		}
	}

//nums中最先完全匹配123的起始下标:0
//nums中最先匹配123每个+1的起始下标:1
	//寻找最后匹配的序列
	{
		vector<int>nums1{ 1,2,3,4,5,6,7,6,5,1,2,3,4 };
		vector<int>nums2{ 1,2,3,4 };
		auto it = std::find_end(nums1.begin(),nums1.end(), nums2.begin(), nums2.begin()+3);
		if (it != nums1.end())
		{
			std::cout << "nums中最后完全匹配123的起始下标:" << (it - nums1.begin()) << endl;
		}
		auto it2 = std::find_end(nums1.begin(), nums1.end(), nums2.begin(), nums2.begin() + 3, [](int i, int j) { return i == j + 1; });
		if (it2 != nums1.end())
		{
			std::cout << "nums中最后匹配123每个+1的起始下标:" << (it2 - nums1.begin()) << endl;
		}
	}

//nums中最后完全匹配123的起始下标:9
//nums中最后匹配123每个+1的起始下标:10

寻找两个连续相等的element 可添加pred:  adjacent_find

	//ForwardIterator adjacent_find (ForwardIterator first, ForwardIterator last)
	{
		vector<int>nums{ 0,2,3,4,5,6,6,7,7,8,16 };
		auto iter = std::adjacent_find(nums.begin(),nums.end());
		if (iter != nums.end())
		{
			std::cout << "nums中第一次出现两个现需相等的数是:" << *iter << endl;
		}
		auto iter2 = std::adjacent_find(nums.begin(), nums.end(), [](int i, int j) { return  i * 2 == j; });
		if (iter2 != nums.end())
		{
			std::cout << "nums中第一次出现连续两个数2倍关系是:" << *iter2 <<" "<< *(iter2+1)<< endl;
		}
	}
//nums中第一次出现两个现需相等的数是:6
//nums中第一次出现连续两个数2倍关系是:8 16

计数:count、 count_if

{
		vector<int>nums{ 0,2,3,4,5,6,6,6,7,8,16 };
		int count = std::count(nums.begin(), nums.end(), 6);
		std::cout << "nums中6的数量:"<<count << endl;

		//count_if(InputIterator first, InputIterator last, UnaryPredicate pred)
		int count2 = std::count_if(nums.begin(), nums.end(), [](int i) { return i % 2 == 0; });
		std::cout << "nums中偶数个数:" << count2 << endl;
}
//nums中6的数量:3
//nums中偶数个数:8

序列比较:mismatch、equal、is_permutation(两个序列等长)

//pair<InputIterator1, InputIterator2>
	//mismatch(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2)
	//first2之后的元素必须和first1-last1元素一样多
	//序列不匹配起始位置
	{
		
		vector<int>nums1{ 0,2,3,4,5,6,6,6,7,8,16 };
		vector<int>nums2{ 0,2,3,4,5,6,9,5,7,8,16 };
		std::pair<std::vector<int>::iterator, std::vector<int>::iterator> mypair;
		mypair = std::mismatch(nums1.begin(), nums1.end(), nums2.begin());
		std::cout << "序列不匹配从nums1:" << *mypair.first << "序列不匹配从nums2:" << *mypair.second << endl;
	}

//序列不匹配从nums1:6序列不匹配从nums2:9
	// bool equal ( InputIterator1 first1, InputIterator1 last1, InputIterator2 first2 )
	//序列等长
	{
		vector<int>nums1{ 0,2,3,4,5,6,6,6,7,8,16 };
		vector<int>nums2{ 0,2,3,4,5,6,7,5,7,8,16 };
		bool bEqual = std::equal(nums1.begin(), nums1.end(), nums2.begin());
		std::cout << "序列nums1 ==  nums2:" << bEqual << endl;

		bool bEqual2 = std::equal(nums1.begin(), nums1.end(), nums2.begin(), [](int i, int j) {return std::abs(i - j) < 3; });
		std::cout << "序列nums1与nums2各个位置元素绝对值差距小于3:" << bEqual2 << endl;
	}

//序列nums1 ==  nums2:false
//序列nums1与nums2各个位置元素绝对值差距小于3:true
// bool is_permutation (InputIterator1 first1, InputIterator1 last1,InputIterator2 first2)
	//等长序列
	{
		vector<int>nums1{ 0,2,3,4,5,6,6,6,7,8,16 };
		vector<int>nums2{ 3,6,7,4,5,6,0,2,16,6,8 };
		bool bPermuation = std::is_permutation(nums1.begin(), nums1.end(), nums2.begin());
		std::cout << "序列nums1和nums2是不同的排列:" << bPermuation << endl;
	}
//序列nums1和nums2是不同的排列:true

搜索子序列:search、search_n

//搜索第一个完全相等序列
	//ForwardIterator1 search(ForwardIterator1 first1, ForwardIterator1 last1,ForwardIterator2 first2, ForwardIterator2 last2)
	{
		vector<int>nums1{ 0,2,3,4,5,6,7,6,6,7,8,16 };
		vector<int>nums2{ 4,5,6 };
		auto it = std::search(nums1.begin(),nums1.end(),nums2.begin(),nums2.end());
		if (it != nums1.end())
		{
			std::cout << "序列nums1中匹配nums2开始位置和值" << it - nums1.begin() << "value:" << *it << endl;
		}

		auto it2 = std::search(nums1.begin(), nums1.end(), nums2.begin(), nums2.end(), [](int i, int j) { return i - j == 1; });
		if (it2 != nums1.end())
		{
			std::cout << "序列nums1中匹配nums2+1开始位置和值" << it2 - nums1.begin() << "value:" << *it2 << endl;
		}
	}


	//ForwardIterator search_n (ForwardIterator first, ForwardIterator last,Size count, const T& val,BinaryPredicate pred)
	{
		vector<int>nums{ 0,2,4,4,5,6,7,6,6,7,8,16 };
		auto it = std::search_n(nums.begin(), nums.end(), 2, 6);
		if (it != nums.end())
		{
			std::cout << "序列nums中找到2个6起始位置:" << it - nums.begin() << endl;
		}
		int n = 8;//谓词BinaryPredicate pred 第一个为序列值第二个为val
		auto it2 = std::search_n(nums.begin(), nums.end(), 2, n, [](int i, int j) { return i * 2 == j; });
		if (it != nums.end())
		{
			std::cout << "序列nums中找到2个4起始位置:" << it2 - nums.begin() << endl;
		}
	}

//序列nums1中匹配nums2开始位置和值3value:4
//序列nums1中匹配nums2+1开始位置和值4value:5
//序列nums中找到2个6起始位置:7
//序列nums中找到2个4起始位置:2

Modifying sequence operation

打印的仿函数

auto printVec = [](vector<int>nums,bool withStep = false) { 
		for (auto it : nums)
		{ 
			if (withStep)
			{
				cout << "["<<it << "]";
			}
			else {
				cout << it << " ";
			}
		} 
		cout << endl; 
	};

	auto printSet = [](set<int>nums, bool withStep = false) {
		for (auto it : nums)
		{
			if (withStep)
			{
				cout << "[" << it << "]";
			}
			else {
				cout << it << " ";
			}
		}
		cout << endl;
	};

	auto printVecStr = [](vector<string>nums, bool withStep = false) {
		for (auto it : nums)
		{
			if (withStep)
			{
				cout << "[" << it << "]";
			}
			else {
				cout << it << " ";
			}
		}
		cout << endl;
	};

拷贝:copy、copy_n、 copy_if、 copy_backward

//OutputIterator copy (InputIterator first, InputIterator last, OutputIterator result)
	{
		vector<int>nums{ 1,2,3,4,5,6,7,8 };
		vector<int>nums_copy(nums.size());
		std::copy(nums.begin(), nums.end(), nums_copy.begin());
		printVec(nums_copy);
	}

	// OutputIterator copy_n (InputIterator first, Size n, OutputIterator result)
	{
		vector<int>nums{ 1,2,3,4,5,6,7,8 };
		vector<int>nums_copy(nums.size()/2);
		std::copy_n(nums.begin(), nums.size() / 2, nums_copy.begin());
		printVec(nums_copy);
	}

	// OutputIterator copy_if (InputIterator first, InputIterator last,OutputIterator result, UnaryPredicate pred)
	{
		vector<int>nums{ 1,2,3,4,5,6,7,8 };
		vector<int>nums_copy(nums.size(),0);
		//返回拷贝完之后拷贝最后一个元素的下一个迭代器
		auto it = std::copy_if(nums.begin(), nums.end(), nums_copy.begin(), [](int n) { return (n & 1) == 0; });
		nums_copy.resize(it - nums_copy.begin());// shrink container to new size
		printVec(nums_copy);
	}
	//从后往前拷贝 先拷贝最后一个 迭代器均往前
	//BidirectionalIterator2 copy_backward ( BidirectionalIterator1 first,BidirectionalIterator1 last,BidirectionalIterator2 result )
	{
		vector<int>nums{ 1,2,3,4,5,6,7,8 };
		nums.resize(12, 0);
		//返回拷贝完之后拷贝序列的第一个元素迭代器
		auto it = std::copy_backward(nums.begin(), nums.begin() + 8, nums.end());
		vector<int>nums_copy(nums.end() - it,0);
		std::copy(it, nums.end(), nums_copy.begin());
		printVec(nums);
		printVec(nums_copy);
	}
	

移动:move、move_backward

//OutputIterator move(InputIterator first, InputIterator last, OutputIterator result)
	//The value of the elements in the [first,last) is transferred to the elements pointed by result. 
	//After the call, the elements in the range [first,last) are left in an unspecified but valid state.
	{
		std::vector<std::string> foo = { "air","water","fire","earth" };
		std::vector<std::string> bar(4);

		// moving ranges: size不变 元素被移动变为有效的初始值
		std::move(foo.begin(), foo.end(), bar.begin());

		std::cout << "foo contains " << foo.size() << " elements:";
		printVecStr(foo, true);//size仍然是4单已经没有特定的元素

		std::cout << "bar contains " << bar.size() << " elements:";
		printVecStr(bar, true);

		// moving container: size = 0
		std::cout << "Moving container...\n";
		foo = std::move(bar);

		std::cout << "foo contains " << foo.size() << " elements:";
		printVecStr(foo, true);
		std::cout << "bar contains " << bar.size() << " elements:";//0
		printVecStr(bar, true);
	}

	//BidirectionalIterator2 move_backward ( BidirectionalIterator1 first,BidirectionalIterator1 last,BidirectionalIterator2 result )
	//从后往前顺序移动
	{
		std::vector<string> elems = { "air","water","fire","earth" };
		elems.resize(10);
		// insert new element at the beginning:
		std::move_backward(elems.begin(), elems.begin() + 4, elems.begin() + 10);
		elems[0] = "ether";
		printVecStr(elems,true);
	}

交换:swap

//swap
	{
		//值替换
		int x = 10, y = 20;                              // x:10 y:20
		std::swap(x, y);                              // x:20 y:10

		//容器替换
		std::vector<int> foo(4, x), bar(6, y);       // foo:4x20 bar:6x10
		std::swap(foo, bar);                          // foo:6x10 bar:4x20
		printVec(foo);
		printVec(bar);	

		//set
		set<int>a = { 1,2,3,4 };
		set<int>b = {5,6,7,8,9};
		swap(a, b);
		printSet(a);
		printSet(b);
	}

转换:transform 

//OutputIterator transform (InputIterator first1, InputIterator last1,OutputIterator result, UnaryOperator op)
	{
		std::vector<int> nums1{1,2,3,4,5};
		std::vector<int> nums2(nums1.size(),-1);
		std::transform(nums1.begin(), nums1.end(), nums2.begin(), [](int n) { return std::pow(n,2); });
		printVec(nums2);
	}

 替换:replace、replace_if

//void replace(ForwardIterator first, ForwardIterator last,const T& old_value, const T& new_value)
	{	
		int myints[] = { 10, 20, 30, 30, 20, 10, 10, 20 };
		std::vector<int> myvector(myints, myints + 8);            // 10 20 30 30 20 10 10 20
		std::replace(myvector.begin(), myvector.end(), 20, 99); // 10 99 30 30 99 10 10 99
		printVec(myvector);

		string str1 = "abcdefgfedcba";
		replace(str1.begin(), str1.end(), 'g', 'G');
		cout << str1 << endl;
	
	}

	// void replace_if (ForwardIterator first, ForwardIterator last,UnaryPredicate pred, const T& new_value)
	{
		string str = "abcDEFgUSNiHyNiHgIMug";
		std::replace_if(str.begin(), str.end(), [](char c) { 
			if (c >= 'A' && c <= 'Z')
			{
				return true;
			}
			return false;
		},'a'
		);
		cout << str << endl;
	}

拷贝同时替换:replace_copy、replace_copy_if 

// OutputIterator replace_copy (InputIterator first, InputIterator last,OutputIterator result, const T& old_value, const T& new_value)
	{
		int myints[] = { 10, 20, 30, 30, 20, 10, 10, 20 };
		std::vector<int> myvector(8);
		std::replace_copy(myints, myints + 8, myvector.begin(), 20, 99);
		printVec(myvector);
	}

	//OutputIterator replace_copy_if (InputIterator first, InputIterator last,OutputIterator result, UnaryPredicate pred,const T& new_value)
	{
		std::vector<int> foo, bar;

		// set some values:
		for (int i = 1; i<10; i++) foo.push_back(i);          // 1 2 3 4 5 6 7 8 9

		bar.resize(foo.size());   // allocate space
		std::replace_copy_if(foo.begin(), foo.end(), bar.begin(), [](int n) { return (n & 1) == 1; }, 0);
		printVec(bar);
	}

 填充:fill、fill_n

// void fill (ForwardIterator first, ForwardIterator last, const T& val)
	{
		std::vector<int> myvector(8,0);                       // myvector: 0 0 0 0 0 0 0 0
		std::fill(myvector.begin(), myvector.begin() + 4, 5);   // myvector: 5 5 5 5 0 0 0 0
		std::fill(myvector.begin() + 3, myvector.end() - 2, 8);   // myvector: 5 5 5 8 8 8 0 0
		printVec(myvector);
	}

	//OutputIterator fill_n (OutputIterator first, Size n, const T& val)
	{
		std::vector<int> myvector(8, 10);        // myvector: 10 10 10 10 10 10 10 10
		std::fill_n(myvector.begin(), 4, 20);     // myvector: 20 20 20 20 10 10 10 10
		std::fill_n(myvector.begin() + 3, 3, 33);   // myvector: 20 20 20 33 33 33 10 10
		printVec(myvector);
	}

 自定义填充:generate、generate_n


	//void generate ( ForwardIterator first, ForwardIterator last, Generator gen )
	{
		std::srand(unsigned(std::time(0)));
		std::vector<int> myvector(8);
		std::generate(myvector.begin(), myvector.end(), []() { return (rand() % 100); });
		printVec(myvector);
	}

	//void generate_n ( OutputIterator first, Size n, Generator gen )
	{
		vector<int>myvector(10,-1);
		std::srand(unsigned(std::time(0)));
		std::generate_n(myvector.begin(), 9, []() { return (rand() % 100); });
		printVec(myvector);
	}

 移除:remove、remove_if

   ForwardIterator remove (ForwardIterator first, ForwardIterator last, const T& val)
   实际不是删除只是元素的重新排列 ,符合条件的元素移动到容器后面,返回移动后边界迭代器。

{
		vector<int>myvector = { 10,20,30,30,20,10,10,20 };      // 10 20 30 30 20 10 10 20
		auto pend = std::remove(myvector.begin(), myvector.end(), 20);         // 10 30 30 10 * *
		//remove实际只是将符合条件的元素移动到后面 并非真正删除
		vector<int>resultVector(pend - myvector.begin());
		copy(myvector.begin(), pend, resultVector.begin());
		printVec(resultVector);//10 30 30 10 10

		//可以配合erase进行真正删除
		myvector.erase(pend, myvector.end());
		printVec(myvector);//10 30 30 10 10


		vector<int>myvector2 = { 10,21,30,31,20,11,10,23 };  
		auto iter = remove_if(myvector2.begin(), myvector2.end(), [](int num) { return (num & 1) == 0; });
		myvector2.erase(iter, myvector2.end());
		printVec(myvector2);
	}

去重:unique移除连续的重复元素,(非连续的重复不去除,全部去重最好先排序) 

ForwardIterator unique (ForwardIterator first, ForwardIterator last)
移除连续的重复元素 返回指向第一个重复元素的迭代器 如果要去重最好先排序 

{
		vector<int>myvector = { 10,20,30,30,20,10,10,20 };
		vector<int>myvector2(myvector);
		auto iter = std::unique(myvector.begin(), myvector.end());
		myvector.erase(iter,myvector.end());
		printVec(myvector);//10 20 30 20 10 20


		//排序后相等的元素会紧邻 unique后完成全局去重
		std::sort(myvector2.begin(), myvector2.end());
		auto iter2 = std::unique(myvector2.begin(), myvector2.end());
		myvector2.resize(iter2 - myvector2.begin());
		printVec(myvector2);
	}

 逆序:reverse

// void reverse (BidirectionalIterator first, BidirectionalIterator last) 逆序
	{
		vector<int>myvector = { 10,20,30,40,50,60,70,80 };
		reverse(myvector.begin(), myvector.end());
		printVec(myvector);
	}

 环移: rotate 循环移动first到last之间元素 使得middle重新在first位置
 void rotate (ForwardIterator first, ForwardIterator middle,ForwardIterator last)

	{
		vector<int>myvector{ 1,2,3,4,5,6,7,8 };
		rotate(myvector.begin(), myvector.begin() + 3, myvector.end());
		printVec(myvector);//4 5 6 7 8 1 2 3

		vector<int>myvector2{ 1,2,3,4,5,6,7,8 };
		rotate(myvector2.begin()+1, myvector2.begin() + 3, myvector2.begin()+7);
		printVec(myvector2);//1,4,5,6,7,2,3,8

	}

 洗牌算法
    Knuth - Durstenfeld Shuffle 算法:一个拥有n个元素的初始序列,
    将最后一个数和该序列的前 n 个数中的随机一个数进行交换(如果随机结果是和第n个数交换,相当于没换),
    然后倒数第二个数和该序列的前 n - 1 个数中的随机一个数进行交换,以此类推,直到将该序列第一个数操作完,
    就完成了洗牌,该算法保证了每个元素在每个位置的概率都是相等的,时间复杂度为O(N)
    
void random_shuffle (RandomAccessIterator first, RandomAccessIterator last,RandomNumberGenerator& gen)
    {
        iterator_traits<RandomAccessIterator>::difference_type i, n;
        n = (last-first);
        for (i=n-1; i>0; --i) {
        swap (first[i],first[gen(i+1)]);
        }
    }

random_shuffle 

{
		std::srand(unsigned(std::time(0)));
		std::vector<int> myvector = { 1, 2, 3, 4, 5, 6, 7, 8, 9 };
		// using built-in random generator:
		std::random_shuffle(myvector.begin(), myvector.end());

		printVec(myvector);
		// 自定义随机数生成器
		std::random_shuffle(myvector.begin(), myvector.end(), [](int i) {return std::rand() % i; });
		printVec(myvector);
	}


    shuffle 与random_shuffle相同 C++11引入 后续建议用这个
    C++11中的<random>头文件中提供了很多生成随机数的工具,需要搭配生成器和分布器来使用
    template <class RandomAccessIterator, class URNG>
    void shuffle (RandomAccessIterator first, RandomAccessIterator last, URNG&& g)
    {
        for (auto i=(last-first)-1; i>0; --i) {
        std::uniform_int_distribution<decltype(i)> d(0,i);
        swap (first[i], first[d(g)]);
        }
    }
    

shuffle 

{
		std::vector<int> vec{ 1, 2, 3, 4, 5, 6 };
		std::mt19937 gen(std::random_device{}());
		//mt19937 名字看起来有点怪,但它是常用的生成器,
		//mt表示它基于Mersenne Twister算法,19937源于产生随的机数的周期长可达到2^19937-1
		std::shuffle(vec.begin(), vec.end(), gen);
		printVec(vec);
	}

Partitions

Sorting


Binary search

Merge

Heap

Min/max

Other

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值