tinystl实现(第十步:Algorithm.cpp)

39 篇文章 4 订阅
28 篇文章 36 订阅

经过长时间的学习终于可以开始tinystl的仿(chao)写工作了,本文参考了这位大佬的博客,坦白讲我只是补充了注释,因为tinystl的代码真的非常经典而我又没什么这种大型项目的经验,所以只能这样做,不过相信能够有助于大家的学习
#强烈建议按顺序阅读本专栏
Algorithm是目前为止最长的一个部分,也是实现过程中收获最丰富的一部分,在本片中可以看到精简可复用的sort函数,copy函数,堆排序,查找节点,询问排列等经典设计
阅读这篇文章了解auto&decltype
阅读这篇文章了解memcpy

#pragma once
#ifndef _ALGORITHM_H_
#define _ALGORITHM_H_

#include<cstring>
#include<utility>

#include"Allocator.h"
#include"Functional.h"
#include"Iterator.h"
#include"TypeTrails.h"
#include"Utility.h"

namespace mySTL {
	template<class ForwardIterator,class T>
	void fill(ForwardIterator first, ForwardIterator, const T& value)
	{
		for (; first != last; ++first) {
			*first = value;//将该区域全部赋值为value
		}
	}
	//重载,对非迭代器传入用memset处理
	inline void fill(char *first, char *last, const char& value)
	{
		memset(first, static_cast<unsigned char>(value), last - first);
	}
	inline void fill(wchar_t *first, wchar_t *last, const wchar_t& value)
	{
		memset(first, static_cast<unsigned char>(value), (last - first)*sizeof(wchar_t));
	}
	template<class OutputIterator,class Size, class T>
	OutputIterator fill_n(OutputIterator first, Size n, const T& value)
	{
		for (; n > 0; --n, ++first)
		{
			*first = value;//将连续n块区域赋予该值
		}
		return first;
	}
	//对非迭代器输入进行重载处理
	template<class Size>
	char *fill_n(char *first, Size n, const char& value)
	{
		memset(first, static_cast<unsigned char>(value), n);
		return first + n;
	}
	template<class Size>
	char *fill_n(char *first, Size n, const wchar_t& value)
	{
		memset(first, static_cast<unsigned char>(value), n*sizeof(wchar_t));
		return first + n;
	}
	//取较小值
	template <class T>
	const T& min(const T& a, const T& b) {
		return !(b < a) ? a : b;
	}
	template <class T, class Compare>
	//为用户提供比较方法的选择
	const T& min(const T& a, const T& b, Compare comp) {
		return !comp(b, a) ? a : b;
	}
	//取较大者
	template <class T>
	const T& max(const T& a, const T& b) {
		return (a < b) ? b : a;
	}
	//为用户提供比较方法的选择
	template <class T, class Compare>
	const T& max(const T& a, const T& b, Compare comp) {
		return (copm(a, b)) ? b : a;
	}
	template<class RandomAccessIterator,class Compare>
	//堆排序上浮
	static void up(RandomAccessIterator first, RandomAccessIterator last,
		RandomAccessIterator head, Compare comp) {
		if (first != last) {
			int index = last - head;
			auto parentIndex = (index - 1) / 2;
			for (auto cur = last; parentIndex >= 0 && cur != head; parentIndex = (index - 1) / 2) {
				auto parent = head + parentIndex;
				if (comp(*parent, *cur))
					mySTL::swap(*parent, *cur);
				cur = parent;
				index = cur - head;
			} }
	}
	//堆排序下降
	template<class RandomAccessIterator, class Compare>
	static void down(RandomAccessIterator first, RandomAccessIterator last,
		RandomAccessIterator head, Compare comp) {
		if (first != last) {
			int index = last - head;
			auto leftChildIndex = 1 + index * 2;
			for (auto cur = first; leftChildIndex < (last - head + 1) && cur < last; leftChildIndex = index * 2 + 1) {
				auto child = head + leftChildIndex;
				if ((chilid + 1) <= last && *(child + 1) > *child)
					child = child + 1;//有有孩子找右孩子
				if (comp(*cur, *child))
					mySTL::swap(*child, *cur);
				cur = child;
				index = cur - head;
			}
		}
	}
	//建堆部分
	template<class RandomAccessIterator>
	void make_heap(RandomAccessIterator first, RandomAccessIterator last) {
		mySTL::make_heap(first, last,
			typename mySTL::less<mySTL::iterator_traits<RandomAccessIterator>::value_type>())
	}//没有比较函数则默认调用less
	//有比较函数的建堆
	template<class RandomAccessIterator,class Compare>
	void make_heap(RandomAccessIterator first, RandomAccessIterator last, Compare comp) {
		const auto range = last - first;
		for (auto cur = first + range / 2 + 1; cur >= first; --cur) {
			mySTL::down(cur, last - 1, first, comp);//逐一执行down
			if (cur == first)return;
		}
	}
	//放入节点的函数:默认节点已经在数组最末端
	template<class RandomAccessIterator>
	void push_heap(RandomAccessIterator first, RandomAccessIterator last) {
		mySTL::push_heap(first, last,
			typename mySTL::less<mySTL::iterator_traits<RandomAccessIterator>::value_type>());
	}

	template<class RandomAccessIterator,class Compare>
	void push_heap(RandomAccessIterator first, RandomAccessIterator last, Compare comp) {
		mySTL::up(first, last - 1, first, comp);
	}
	//移除堆顶的数(本质是移动到last位置使之无效化)
	template<class RandomAccessIterator>
	void pop_heap(RandomAccessIterator first, RandomAccessIterator last) {
		mySTL::pop_heap(first, last,
			typename mySTL::less<mySTL::iterator_traits<RandomAccessIterator>::value_type>());
	}
	template<class RandomAccessIterator, class Compare>
	void push_heap(RandomAccessIterator first, RandomAccessIterator last, Compare comp) {
		mySTL::swap(*first, *(last - 1));
		if(last-first>=2)
		mySTL::down(first, last - 2, first, comp);
	}
	//堆排序
	template<class RandomAccessIterator>
	void sort_heap(RandomAccessIterator first, RandomAccessIterator last) {
		return mySTL::sort_heap(first, last,
			typename mySTL::less<mySTL::iterator_traits<RandomAccessIterator>::value_type>());
	}
	template<class RandomAccessIterator, class Compare>
	void sort_heap(RandomAccessIterator first, RandomAccessIterator last, Compare comp) {
		for (auto cur = last; cur != first; --cur) {
			mySTL::pop_heap(first, cur, comp);
		}
	}
	template<class RandomAccessIterator>
	void is_heap(RandomAccessIterator first, RandomAccessIterator last) {
		return mySTL::is_heap(first, last,
			typename mySTL::less<mySTL::iterator_traits<RandomAccessIterator>::value_type>());
	}
	template<class RandomAccessIterator, class Compare>
	void sort_heap(RandomAccessIterator first, RandomAccessIterator last, Compare comp) {
		const auto range = last - first;
		auto index = range / 2 - 1;
		for (auto cur = first + range / 2 - 1; cur >= first; --cur, --index) {
			if (*(first + (index * 2 + 1)) > *cur ||
				(first + (index * 2 + 2)) <= last && (first + (index * 2 + 2)) > *cur)
				return false;
			if (cur == first)
				break;
		}
		return true;
	}
	//判断是否都符合predicate
	template <class InputIterator, class UnaryPredicate>
	bool all_of(InputIterator first, InputIterator last, UnaryPredicate pred) {
		for (; first != last; ++first) {
			if (!pred(*first))
				return false;
		}
		return true;
	}
	//判断是否至少一个符合predicate
	template <class InputIterator, class UnaryPredicate>
	bool any_of(InputIterator first, InputIterator last, UnaryPredicate pred) {
		for (; first != last; ++first) {
			if (!pred(*first))
				return true;
		}
		return false;
	}
	//判断是否至少一个不符合predicate
	template <class InputIterator, class UnaryPredicate>
	bool none_of(InputIterator first, InputIterator last, UnaryPredicate pred) {
		for (; first != last; ++first) {
			if (pred(*first))
				return false;
		}
		return true;
	}
	//对结构中所有数据做同一函数(func)处理
	template<class InputIterator,class Function>
	Function for_each(InputIterator first, InputIterator last, Function fn) {
		for (; first! = last; ++first)
			fn(*first);
		return fn;
	}
	//查找
	template<class InputIterator, class T>
	InputIterator find(InputIterator first, InputIterator last, const T& val) {
		for (; first! = last; ++first)
			if(*first==val)break;
		return first;
	}
	//查找第一个符合predicate的数据
	template <class InputIterator, class UnaryPredicate>
	InputIterator find_if(InputIterator first, InputIterator last, UnaryPredicate pred) {
		for (; first! = last; ++first)
			if (pred(*first))break;
		return first;
	}
	//查找第一个不符合predicate的数据
	template <class InputIterator, class UnaryPredicate>
	InputIterator find_if_not(InputIterator first, InputIterator last, UnaryPredicate pred) {
		for (; first! = last; ++first)
			if (!pred(*first))break;
		return first;
	}
	//查找子区间
	template<class ForwardIterator1,class ForwardIterator2>
	ForwardIterator1 find_end(ForwardIterator1 first1, ForwardIterator1 last1,
		ForwardIterator2 first2, ForwardIterator2 last2) {
		if (first2 == last2)//目标空间为空,返回空
			return last1;
		ForwardIterator1 ret = last1;//默认返回空
		while (first1 != last1)
		{
			ForwardIterator1 it1 = first1;
			ForwardIterator2 it2 = first2;
			while (*it1 == *it2) {//发现对应起点
				++it1;
				++it2;
				if (it2 == last2) {//找到区间,取值返回
					ret = first1;
					break;
				}
				if (it1 == last1)return ret;//到最后,返回
			}
			++first1;
		}
		return ret;//返回空值
	}
	//引入了predicate的查找区间
	template<class ForwardIterator1, class ForwardIterator2,class BinaryPredicate>
	ForwardIterator1 find_end(ForwardIterator1 first1, ForwardIterator1 last1,
		ForwardIterator2 first2, ForwardIterator2 last2,
		BinaryPredicate pred) {
		if (first2 == last2)
			return last1;
		ForwardIterator1 ret = last1;
		while (first1 != last1)
		{
			ForwardIterator1 it1 = first1;
			ForwardIterator2 it2 = first2;
			while (pred(*it1, *it2)) {
				++it1;
				++it2;
				if (it2 == last2) {
					ret = first1;
					break;
				}
				if (it1 == last1)return ret;
			}
			++first1;
		}
		return ret;
	}
	//查找first1中第一个属于first2中的数
	template<class ForwardIterator1, class ForwardIterator2>
	ForwardIterator1 find_first_of(ForwardIterator1 first1, ForwardIterator1 last1,
		ForwardIterator2 first2, ForwardIterator2 last2) {
		for (; first1 != last1; ++first1) {
			for (auto it = first2; it != first2; ++it)
				if (*first == *it)
					return first1;//遍历first2,找到返回
		}
		return last1;//未找到
	}
	//借助pred判断
	template<class ForwardIterator1, class ForwardIterator2,class BinaryPredicate>
	ForwardIterator1 find_first_of(ForwardIterator1 first1, ForwardIterator1 last1,
		ForwardIterator2 first2, ForwardIterator2 last2,
		BinaryPredicate pred) {
		for (; first1 != last1; ++first1) {
			for (auto it = first2; it != first2; ++it)
				if (pred(*first , *it))
					return first1;//遍历first2,找到返回
		}
		return last1;//未找到
	}
	//查找第一组两个连续的符合条件的数数
	//没有输入条件默认调用equal
	template<class ForwardIterator>
	ForwardIterator adjacent_find(ForwardIterator first, ForwardIterator last) {
		return mySTL::adjacent_find(first, last,
			equal_to<iterator_traits<typename ForwardIterator>::value_type>());
	}
	template<class ForwardIterator, class BinaryPredicate>
	ForwardIterator adjacent_find(ForwardIterator first, ForwardIterator last,
		BinaryPredicate pred) {
		for (; first != last; ++first) {
			if (first += last && pred(*(first), *(first + 1)))
				break;
		}
		return first;
	}

	template<class InputIterator, class T>
	typename iterator_traits<InputIterator>::difference_type
		count(InputIterator first, InputIterator last, const T&val) {
		typename iterator_traits<InputIterator>::difference_type n = 0;
		for (; first != last; ++first) {
			if (*first == val)
				++n;
		}
		return n;
	}
	//返回第一对不相等的值
	template <class InputIterator1, class InputIterator2> 
	pair< InputIterator1, InputIterator2>
		mismatch(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2)
		{
		for (; first != last1; ++first1, ++first2) {
			if (*first1 != *first2  )
				break;
			}
		return mySTL::make_pair(first1, first2);
		};
	template <class InputIterator1, class InputIterator2, class UnaryPredicate>
	pair< InputIterator1, InputIterator2>
		mismatch(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2
			,UnaryPredicate pred)
	{
		for (; first != last1; ++first1, ++first2) {
			if (!pred(*first1, *first2)  )
				break;
		}
		return mySTL::make_pair(first1, first2);
	};
	//监察后者与前者是否全部相同(后者比前者长的部分不处理)
	template <class InputIterator1, class InputIterator2>
	bool equal(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2) {
		return mySTL::equal(first1, last1,first2,
			equal_to<iterator_traits<typename InputIterator1>::value_type>());
	}
	template <class InputIterator1, class InputIterator2, class BinaryPredicate>
	bool equal(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2,BinaryPredicate pred)
	{
		for (; first != last1; ++first1, ++first2) {
			if (!pred(*first1, *first2))
				return false;
		}
		return true;
	};
	//检查是否另一序列的排列
	template<class ForwardIterator1, class ForwardIterator2>
	bool is_permutation(ForwardIterator1 first1, ForwardIterator1 last1
		,ForwardIterator2 first2) {
		return mySTL::is_permutation(first, last,
			equal_to<iterator_traits<typename ForwardIterator>::value_type>());
	}
	template<class ForwardIterator1, class ForwardIterator2, class BinaryPredicate>
	bool is_permutation(ForwardIterator1 first1, ForwardIterator1 last1
		, ForwardIterator2 first2, BinaryPredicate pred) {
		//找到第一个不同的地方
		auto res = mySTL::mismatch(first1, last1, first2, pred);
		first1 = res.first, first2 = res.second;
		if (first1 == last1)return true;
		auto last2 = first2;
		std::add_lvalue_reference(last2, std::distance(first1, last1));
		for (auto it1 = first1; it1 != last1; ++it1) {
			if (mySTL::find_if(first1, it1, [&](decltype(*first1)val) {return pred(val, *it1); }) == it1) {
				//如果it未在之前出现
				auto n = mySTL::count(first2, last2, it1);
				//如果在二中找不到则判断为假
				if (n == 0 || mySTL::count(it1, last1, *it1) != n)
					return false;
			}
		}
		return true;
	}
	//查找first2是否为first1子序列
	template<class ForwardIterator1, class ForwardIterator2>
	ForwardIterator1 search(ForwardIterator1 first1, ForwardIterator1 last1,
		ForwardIterator2 first2, ForwardIterator2 last2) {
		return mySTL::search(first1, last1, first2, last2,
			mySTL::equal_to<typename mySTL::iterator_traits<ForwardIterator1>::value_type>());
	}
	template<class ForwardIterator1, class ForwardIterator2, class BinaryPredicate>
	ForwardIterator1 search(ForwardIterator1 first1, ForwardIterator1 last1,
		ForwardIterator2 first2, ForwardIterator2 last2
		,BinaryPredicate pred) {
		while (first1 != last1) {
			auto it1 = first1;
			auto it2 = first2;
			while (it1 != last1 && it2 != last2) {
				if (pred(*it1, *it2)) {
					++it1, ++it2;//跳过相同的部分
				}
				else break;
			}
			if (it2 == last2)return first1;//整个first2都在first1中
			if (it1 == last1)return last1;//first1找到尾也找不齐,返回first1的尾
			++first1;//拖动first的起查点
		}
		return last1;
	}
	//不同iterator的向前移动
	namespace {
		template<class InputIterator, class Distance>
		void _advance(InputIterator &it, Distance n,
			input_iterator_tag) {
			assert(n >= 0);
			while (n--)++it;
		}
		template<class BidiretionIterator, class Distance>
		void _advance(BidiretionIterator &it, Distance n,
			bidirectional_iterator_tag) {
			if (n < 0) {
				while (n++)--it;
			}
			else while (n--)++it;
		}
		template<class RandomIterator, class Distance>
		void _advance(RandomIterator &it, Distance n,
			random_access_iterator_tag) {
			if (n < 0) {
				it-=(-n);
			}
			else it+=n;
		}
	}
	//公共接口
	template<class InputIterator, class Distance>
	void advance(InputIterator& it, Distance n) {
		typedef iterator_traits<InputIterator>::iterator_category iterator_category;
		_advance(it, n, iterator_category());
	}
	namespace {
		//sort的辅助函数
		template<class RandomIterator,class BinaryPredicate>
		typename iterator_traits<RandomIterator>::value_type
			mid3(RandomIterator first, RandomIterator last,
				BinaryPredicate pred) {
			auto mid = first + (last + 1 - first) / 2;
			if (pred(*mid, *first)) {
				swap(*mid, *first);
			}
			if (pred(*last, *mid)) {
				swap(*last, mid);
			}
			if (pred(*last, *first)) {
				swap(*last, *first);
			}
			auto ret = *mid;
			swap(*mid, *(last - 1));
			return ret;
		}
		//冒泡排序
		template<class RandomIterator, class BinaryPredicate>
		void bubble_sort(RandomIterator first, RandomIterator last,
			BinaryPredicate pred) {
			auto len = last - first;
			for (auto i = len; i != 0; --i) {
				bool swaped = false;
				for (auto p = first; p != (first + i - 1); ++p) {
					if (pred(*(p + 1), *p)) {
						swap(*(p + 1), *p);
						swaped = true;
					}
				}
				if (!swaped)break;
			}
		}
	
	}
	template<class RandomIterator>
	void sort(RandomIterator first, RandomIterator last) {
		return sort(first, last, less<typename iterator_traits<RandomIterator>::value_type>());
	}
	template<class RandomIterator, class BinaryPredicate>
	void sort(RandomIterator first, RandomIterator last,
		BinaryPredicate pred) {
		if (first >= last || first + 1 == last)
			return;//超出返回
		if (last - first <= 20)//区间小于等于20,冒泡排序
			return bubble_sort(first, last, pred);
		auto mid = mid3(first, last, pred);//调整first,mid,last三者的关系并返回mid
		auto p1 = first, p2 = last - 2;
		while (p1 < p2) {
			while (pred(*p1, mid) && (p1 < p2))++p1;//寻找左侧大于mid的值
			while (pred(*p2, mid) && (p1 < p2))--p2;//寻找右侧小于mid的值
			if (p1 < p2)swap(*p1, *p2);//交换
		}
		swap(*p1, *(last - 2));//换回mid
		sort(first, p1, pred);//左sort
		sort(p1 + 1, last, pred);//右sort
	}
	//全体赋值func返回值
	template<class InputIterator,class Function>
	void generate(InputIterator first, InputIterator last, Function func) {
		for (; first != last; ++first)*first = func();
	}
	//局部赋值
	template<class OutputIterator,class Size,class Generator>
	void generate_n(OutputIterator first, Size n, Generator gen) {
		while (n--) {
			*first = gen();
			++first;
		}
	}
	//求其长度
	template<class InputIterator>
	typename iterator_traits<InputIterator>::difference_type
		_distance(InputIterator first, InputIterator last, input_iterator_tag) {
		typename iterator_traits<InputIterator>::difference_type dist = 0;
		while (first++ != last) {
			++dist;
		}
		return dist;
	}
	//指针类更加快捷
	template<class RandomIterator>
	typename iterator_traits<RandomIterator>::difference_type
		_distance(RandomIterator first, RandomIterator last, random_access_iterator_tag) {
		auto dist = last - first;
		return dist;
	}
	//公用接口,不同iterator在这里分流
	template<class Iterator>
	typename iterator_traits<Iterator>::difference_type
		distance(Iterator first, Iterator last) {
		typedef typename iterator_traits<Iterator>::iterator_category iterator_category;
		return _distance(first, last, iterator_category());
	}
	//复制

	template<class InputIterator, class OutputIterator>
	OutputIterator __copy(InputIterator first, InputIterator last, OutputIterator result, _true_type) {
		//对pod类型直接调用memcpy
		auto dist = distance(first, last);
		memcpy(result, first, sizeof(*first) * dist);
		advance(result, dist);
		return result;
	}
	template<class InputIterator, class OutputIterator>
	OutputIterator __copy(InputIterator first, InputIterator last, OutputIterator result, _false_type) {
		while (first != last) {
			*result = *first;//对非pod类型逐个复制
			++result;
			++first;
		}
		return result;
	}
	//查看是否为pod,转__copy
	template<class InputIterator, class OutputIterator, class T>
	OutputIterator _copy(InputIterator first, InputIterator last, OutputIterator result, T*) {
		typedef typename TinySTL::_type_traits<T>::is_POD_type is_pod;
		return __copy(first, last, result, is_pod());
	}
	//加入类型提取,转_copy
	template <class InputIterator, class OutputIterator>
	OutputIterator copy(InputIterator first, InputIterator last, OutputIterator result) {
		return _copy(first, last, result, value_type(first));
	}
	template<>
	inline char *copy(char *first, char *last, char *result) {
		auto dist = last - first;
		memcpy(result, first, sizeof(*first) * dist);
		return result + dist;
	}
	template<>
	inline wchar_t *copy(wchar_t *first, wchar_t *last, wchar_t *result) {
		auto dist = last - first;
		memcpy(result, first, sizeof(*first) * dist);
		return result + dist;
	}
}

#endif // !_ALGORITHM_H_

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值