C++学习笔记——STL【算法:排序算法】

sort 排序

函数签名:

template <class RandomAccessIterator>  
void sort (RandomAccessIterator first, RandomAccessIterator last);

template <class RandomAccessIterator, class Compare>  
void sort (RandomAccessIterator first, RandomAccessIterator last, Compare comp);

函数功能:

对待排序容器指定区间内的元素进行排序,可以自己指定排序规则

函数参数:

  • first 对待排序序列的初始位置的随机访问迭代器(包含)
  • last 对待排序序列的最终位置的随机访问迭代器(不包含)
  • comp 二元谓词 ,表示排序规则,可以是函数指针,也可以是函数对象

应用案例

#include<iostream>
#include<string>
#include<vector>
#include<algorithm>

using namespace std;

class IntCompare_1 {
public:
	bool operator()(int& v1, int& v2) {
		return v1 > v2;
	}
};
bool IntCopare_2(int& v1, int& v2) {
	return v1 > v2;
}

void printval(int& v) {
	cout << v << " ";
}

int main() {
	vector<int> v = { 2,1,5,3,7,6 };

	/*int型,默认按值升序排序*/
	sort(v.begin(), v.end());
	for_each(v.begin(), v.end(), printval); // 1 2 3 5 6 7
	cout << endl;

	/*传入自定义的排序规则-降序:以函数对象形式传入*/
	sort(v.begin(), v.end(), IntCompare_1());
	for_each(v.begin(), v.end(), printval); // 7 6 5 3 2 1
	cout << endl;

	vector<int> v2 = { 8,1,9,4,7,2,6 };
	/*传入自定义的培训规则-降序:以函数指针传入*/
	sort(v2.begin(), v2.end(), IntCopare_2);
	for_each(v2.begin(), v2.end(), printval); // 9 8 7 6 4 2 1

	return 0;
}

random_shuffle 打乱顺序

函数签名:

template <class RandomAccessIterator>  
void random_shuffle (RandomAccessIterator first, RandomAccessIterator last);

template <class RandomAccessIterator, class RandomNumberGenerator>  
void random_shuffle (RandomAccessIterator first, RandomAccessIterator last,RandomNumberGenerator&& gen);

函数功能:
随机地重新排列指定范围中的元素。函数将每个元素的值与其他随机选择的元素的值交换。
当提供函数gen时,函数gen决定在每种情况下选择哪个元素。否则,该函数将使用一些未指定的随机性源。

函数参数:

  • first 对待扰乱序列的初始位置的随机访问迭代器(包含)
  • last 对待扰乱序列的最终位置的随机访问迭代器(不包含)
  • gen 一元谓词,指定随机随机选择交换的策略

函数实现:

函数内部实现等价于:

template <class RandomAccessIterator, class RandomNumberGenerator>
  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)]);
  }
}

应用案例:

使用内置的随机生成器

#include<iostream>
#include<string>
#include<vector>
#include<algorithm>

using namespace std;

void print_val(const int& val) {
	cout << val << " ";
}
int main() {
	// 随机种子(需要提供随机种子,不然每次随机重排的结果都一样)
	srand((unsigned int)time(NULL));

	vector<int> v = {1,2,3,4,5,6};
	// 使用内置的随机生成器 随机重新排序
	random_shuffle(v.begin(), v.end());
	for_each(v.begin(),v.end(),print_val);
	return 0;
}

使用自定义的随机生成器

#include<iostream>
#include<string>
#include<vector>
#include<algorithm>

using namespace std;

// 随机生成器函数
int my_random(int i) {
	return rand() % i;
}

void print_val(const int& val) {
	cout << val << " ";
}
int main() {
	// 随机种子(需要提供随机种子,不然每次随机重排的结果都一样)
	srand((unsigned int)time(NULL));

	vector<int> v = {1,2,3,4,5,6};
	// 使用自定义的的随机生成器 随机重新排序
	random_shuffle(v.begin(), v.end(),my_random);
	for_each(v.begin(),v.end(),print_val);
	return 0;
}

merge 合并有序序列

函数签名:

template <class InputIterator1, class InputIterator2, class OutputIterator>
OutputIterator merge (InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, InputIterator2 last2,OutputIterator result);

template <class InputIterator1, class InputIterator2,class OutputIterator, class Compare>  
OutputIterator merge (InputIterator1 first1, InputIterator1 last1,InputIterator2 first2, InputIterator2 last2,OutputIterator result, Compare comp);

函数功能:

将两个有序序列的指定范围内元素合并到一个容器中。
可以通过二元谓词指定合并方式。

参数说明:
(包括first指向的元素,但不包括last指向的元素)

  • first1:第一个源有序序列的起始迭代器
  • last1:第一个源有序序列的终止迭代器
  • first2:第二个源有序序列的起始迭代器
  • last2:第二个源有序序列的终止迭代器
  • result:目标容器的起始迭代器
  • comp:自定义排序规则,可以是函数指针,也可以是函数对象

函数实现:

函数内部实现等价于:

template <class InputIterator1, class InputIterator2, class OutputIterator>
  OutputIterator merge (InputIterator1 first1, InputIterator1 last1,
                        InputIterator2 first2, InputIterator2 last2,
                        OutputIterator result)
{
  while (true) {
    if (first1==last1) return std::copy(first2,last2,result);
    if (first2==last2) return std::copy(first1,last1,result);
    *result++ = (*first2<*first1)? *first2++ : *first1++;
  }
}

应用案例:
采用默认的合并规则:对两个已升序排序的序列进行升序合并

#include<iostream>
#include<string>
#include<vector>
#include<algorithm>

using namespace std;

int main() {
	int arr1[] = { 15,13,17,11,19 };
	int arr2[] = { 9,1,8,3,7,2,4,3 };
	// 对两个源序列进行排序
	sort(arr1, arr1 + 5);
	sort(arr2, arr2 + 8);
	// 根据两个原序列大小构建vector容器
	vector<int>v(sizeof(arr1)/sizeof(arr1[0]) + sizeof(arr2) / sizeof(arr2[0]));
	// 合并两个序列所有元素到目标容器v
	// 默认的合并:int 类型默认按值升序合并到新的容器(源序列也需要是升序排序)
	merge(arr1,arr1 + 5,arr2,arr2 + 8,v.begin());
	// 输出目标容器中的元素
	for (vector<int>::iterator p = v.begin(); p != v.end(); p++) {
		cout << *p << " ";
	}
	cout << endl; 
	
	// 1 2 3 3 4 7 8 9 11 13 15 17 19
	return 0;
}

使用自定义的合并规则

#include<iostream>
#include<string>
#include<vector>
#include<algorithm>

using namespace std;

/*自定义的排序规则:降序*/
bool my_compare(const int& v1, const int& v2) {
	return v1 > v2;
}

int main() {
	int arr1[] = { 5,3,1,2,4 };
	int arr2[] = { 11,12,18,17,15,14,16,13 };
	// 对两个源序列进行排序:降序排序
	sort(arr1, arr1 + 5,my_compare);
	sort(arr2, arr2 + 8, my_compare);
	// 根据两个原序列大小构建vector容器
	vector<int>v(sizeof(arr1)/sizeof(arr1[0]) + sizeof(arr2) / sizeof(arr2[0]));
	// 合并两个序列所有元素到目标容器v
	merge(arr1,arr1 + 5,arr2,arr2 + 8,v.begin(), my_compare);
	// 输出目标容器中的元素
	for (vector<int>::iterator p = v.begin(); p != v.end(); p++) {
		cout << *p << " ";
	}
	cout << endl; 
	// 自定义的合并结果
	// 18 17 16 15 14 13 12 11 5 4 3 2 1
	return 0;
}

reverse 容器元素反转

函数签名:

template <class BidirectionalIterator>  
void reverse (BidirectionalIterator first, BidirectionalIterator last);

函数功能:
将容器指定区间内的的元素顺序翻转

参数说明:

  • first:目标容器的起始迭代器(包含)
  • last:目标容器的终止迭代器(不包含)

函数实现:

template <class BidirectionalIterator>
  void reverse (BidirectionalIterator first, BidirectionalIterator last)
{
  while ((first!=last)&&(first!=--last)) {
    std::iter_swap (first,last);
    ++first;
  }
}

应用案例:

#include<iostream>
#include<string>
#include<vector>
#include<algorithm>

using namespace std;

int main() {
	vector<int>v = {5,4,3,2,1};
	reverse(v.begin(), v.end());
	for (vector<int>::iterator p = v.begin(); p != v.end(); p++) {
		cout << *p << " ";
	}
	cout << endl; // 1 2 3 4 5
	return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值