STL初步-sort排序算法与二分查找算法

最近刷题遇到了一些题目,做起来有些困难,感觉用STL解决起来会更快,也是为了12月的PTA乙级和转专业机试做准备,所以把这些知识再复习一遍

STL介绍

  • STL:(Standard Template Library)标准模板库
  • 包含一些常用的算法如排序查找,还有常用的数据结构如可变长数组链表
    字典等。
  • 使用方便,效率较高
  • 需包含头文件 #include

sort排序

用法一

sort(数组名+n1,数组名+n2);

  • 对下标范围为[n1,n2)的元素从小到大排序,n2不在排序范围内
用法二

sort(数组名+n1,数组名+n2,greater() );

  • 对下标范围为[n1,n2)的元素从大到小排序,n2不在排序范围内
用法三

sort(数组名+n1,数组名+n2,排序规则结构名() );

  • 自定义的排序规则,对任何类型T的数组排序
  • 定义:
struct 结构名
{
   bool operator()(const T & a1,const T & a2)
   {
       //若a1应该在a2前面,则返回true。
       //否则返回false。
   }
}

注意!!不能造成比较 a1,a2 返回 true 比较 a2,a1 也返回 true
否则sort会 runtime error
比较 a1,a2 返回 false 比较 a2,a1 也返回 false,则没有问题

  • 例子:
#include
#include
#include
using namespace std;

struct Student{
	string name;
	int id;
	double gpa;
};

Student stds[]={{"Jack",112,3.4},{"Mary",102,3.8},{"Mary",117,3.9},
{"Ala",333,3.5},{"Zero",101,4.0}};

struct Rule1{ //按名字从小到大排 
	bool operator() ( const Student & a1,const Student & a2)
	{
		if(a1.name<a2.name) return true;
		return false;
	}
};

void PrintStudents(Student s[],int size)
{ //打印学生信息
   for(int i = 0;i < size;++i)
   cout << "(" << s[i].name << ","
   << s[i].id <<"," << s[i].gpa << ") " ;
   cout << endl;
}


int main()
{
	int n=sizeof(stds)/sizeof(Student); //n表示有多少个Student元素
    sort(stds,stds+n,Rule1()); //按名字排序
    PrintStudents(stds,n);
  return 0;

}

二分查找算法

二分查找算法必须用在已排好序的数组上

binary_search
lower_bound
upper_bound

binary_search二分查找
用法一
  • 在从小到大排好序的基本类型数组上进行二分查找

binary_search(数组名+n1,数组名+n2,值)

返回值为true(找到),false(没找到)

用法二
  • 在用自定义排序规则排好序的、元素为任意的T类型的数组中进行二分查找

binary_search(数组名+n1,数组名+n2,值,排序规则结构名());

返回值为true(找到),false(没找到)
查找时的排序规则,必须和排序时的规则一致

#include 
#include 
#include 
using namespace std;

struct Student {
       char name[20];
       int id;
       double gpa;
};

Student students [] = {
{"Jack",112,3.4},{"Mary",102,3.8},{"Mary",117,3.9},
{"Ala",333,3.5},{"Zero",101,4.0}};

struct StudentRule1 { //按姓名从小到大排
         bool operator() (const Student & s1,const Student & s2) {         
         if( stricmp(s1.name,s2.name) < 0)
         return true;
         return false;
         }
};
struct StudentRule2 { //按id从小到大排
         bool operator() (const Student & s1,const Student & s2) {
         return s1.id < s2.id;
         }
};
struct StudentRule3 {//按gpa从高到低排
         bool operator() (const Student & s1,const Student & s2) {
         return s1.gpa > s2.gpa;
         }
};

int main()
{
   Student s;
   strcpy(s.name,"Mary");
   s.id= 117;
   s.gpa = 0;
   int n = sizeof(students) / sizeof(Student);
   sort(students,students+n,StudentRule1()); //按姓名从小到大排
   cout << binary_search( students , students+n,s,
   StudentRule1()) << endl;
   strcpy(s.name,"Bob");
   cout << binary_search( students , students+n,s,
   StudentRule1()) << endl;
   sort(students,students+n,StudentRule2()); //按id从小到大排
   cout << binary_search( students , students+n,s,
   StudentRule2()) << endl;
   return 0;
 输出:  
       0
       1
       0
}
lower_bound二分查找下界
用法一

用于已从小到大排好序的数组上

T * lower_bound(数组名+n1,数组名+n2,值);
返回一个指针 T * p;

*p 是查找区间里下标最小的,大于等于"值" 的元素。如果找不到,p指向下标为n2的
元素

用法二

自定义排序规则

T * lower_bound(数组名+n1,数组名+n2,值,排序规则结构名());
返回一个指针 T * p;

*p 是查找区间里下标最小的,按自定义排序规则,可以排在"值"后面的元素。如果找
不到,p指向下标为n2的元素

upper_bound二分查找上界
用法一

用于已从小到大排好序的数组上

T * upper_bound(数组名+n1,数组名+n2,值);
返回一个指针 T * p;

*p 是查找区间里下标最小的,大于"值" 的元素。如果找不到,p指向下标为n2的
元素

用法二

自定义排序规则

T * upper_bound(数组名+n1,数组名+n2,值,排序规则结构名());
返回一个指针 T * p;

*p 是查找区间里下标最小的,按自定义排序规则,必须排在"值"后面的元素。如果找
不到,p指向下标为n2的元素

lower_bound,upper_bound用法示例
#include 
#include 
#include 
using namespace std;

struct Rule
{	//按个位数从小到大排序 
   bool operator()( const int & a1,const int & a2) 
   {
      return a1%10 < a2%10;
   }
};

void Print(int a[],int size) 
{ //打印数组 
   for(int i = 0;i < size;++i) 
   {
      cout << a[i] << "," ;
   }
   cout << endl;
}

#define NUM 7
int main()
{
    int a[NUM] = { 12,5,3,5,98,21,7};
	sort(a,a+NUM);
	Print(a,NUM); // => 3,5,5,7,12,21,98,
	int * p = lower_bound(a,a+NUM,5);
	cout << *p << "," << p-a << endl; //=> 5,1
	p = upper_bound(a,a+NUM,5);
	cout << *p << endl; //=>7
	cout << * upper_bound(a,a+NUM,13) << endl; //=>21
	sort(a,a+NUM,Rule());
	Print(a,NUM); //=>21,12,3,5,5,7,98,
	cout << * lower_bound(a,a+NUM,16,Rule()) << endl; // => 7
	cout << lower_bound(a,a+NUM,25,Rule()) - a<< endl; // => 3
	cout << upper_bound(a,a+NUM,18,Rule()) - a << endl; // => 7
	if( upper_bound(a,a+NUM,18,Rule()) == a+NUM)
	cout << "not found" << endl; //=> not found
	cout << * upper_bound(a,a+NUM,5,Rule()) << endl; // =>7
	cout << * upper_bound(a,a+NUM,4,Rule()) << endl; // =>5
	return 0;
}	

你可能感兴趣的:(STL初步-sort排序算法与二分查找算法)