1. 程式人生 > 其它 >C++STL標準庫學習筆記(一)sort

C++STL標準庫學習筆記(一)sort

前言:

近來在學習STL標準庫,做一份筆記並整理好,方便自己梳理知識、以後查詢,也方便他人學習,兩全其美,快哉快哉!

這裡我會以中國大學慕課上北京大學郭煒老師的《程式設計與演算法(一)C語言程式設計》中的十二章十三章為學習資料來做筆記。並且我會附上程式碼(只要我不偷懶的話)。若有沒學習到的部分,我會繼續找資料來更新學習筆記。

STL(Standard Template Library,標準模板庫)

包含一些常用的演算法如排序查詢,和常用的資料結構如:可變長陣列,連結串列,字典等。

優點:使用方便,(執行)效率較高。

注意:若要使用其中的演算法,需要#include<algorithm>

一、排序(sort)

本質上是用快速排序演算法實現。

用法1:對基本型別的陣列(int,double,char...)從小到大排序

sort(陣列名+n1, 陣列名+n2);

n1和n2都是int型別表示式,可以包含變數

如果n1=0,則+n1可以不寫

作用是將陣列中下標範圍為[n1,n2)的元素從小到大排序,下標為n2的元素不在排序區間內。

樣例:

 1 int main(int argc, char const *argv[])
 2 {
 3   int a[] = {15,4,3,8,7,2,6};
 4   sort(a,a+7);//對整個陣列從小到大排序
 5   for (int
i = 0; i < 7; i++) 6 { 7 cout<<a[i]<<' '; 8 }//結果:2 3 4 6 7 8 15 9 cout<<endl; 10 int b[] = {15,4,3,8,7,2,6}; 11 sort(b,b+3); 12 for (int i = 0; i < 7; i++) 13 { 14 cout<<b[i]<<' '; 15 }//結果:3 4 15 8 7 2 6 16 cout<<endl; 17 int c[] = {15
,4,3,8,7,2,6}; 18 sort(c+2,c+5); 19 for (int i = 0; i < 7; i++) 20 { 21 cout<<c[i]<<' '; 22 }//結果:15 4 3 7 8 2 6 23 cout<<endl; 24 return 0; 25 }
用法1

用法2:對元素型別為T的基本型別陣列從大到小排序:

sort(陣列名+n1,陣列名+n2,greater<T>);

樣例:

 1 int main(int argc, char const *argv[])
 2 {
 3   int a[] = {15,4,3,8,7,2,6};
 4   int i;
 5   sort(a,a+7,greater<int>());
 6   for ( i = 0; i < 7; i++)
 7   {
 8     cout<<a[i]<<' ';
 9   }//結果:15 8 7 6 4 3 2
10   
11   return 0;
12 }
用法2

用法3:用自定義的排序規則,對任何型別T的陣列排序

使用這種用法的原因:在我們自己定義了一些類/結構體的時候,自帶的排序規則可能無法使用,或者說我們需要用我們自己的方法來排序,這個時候我們就要自定義排序規則了。

sort(陣列名+n1,陣列名+n2,排序規則結構名());

排序規則結構的定義方式:

1 struct 結構名
2 {
3   bool operator()(const T & a1,const T & a2)const
4   {
5     //若a1應該在a2前面,則返回true
6     //否則返回false
7   }
8 };
定義方式

在bool operator()(const T & a1,const T & a2)const這一句中,要記得寫上const,否則可能會有奇奇怪怪的錯誤。

樣例1(自定義規則排序):

 1 struct rule1//從大到小排序
 2 {
 3   bool operator()(const int & a1,const int & a2)const
 4   {
 5     return a1 > a2;
 6   }
 7 };
 8 struct rule2//按個位數從大到小排序
 9 {
10   bool operator()(const int & a1,const int & a2)const
11   {
12     return a1%10 < a2%10;
13   }
14 };
15 void Print(int a[],int size)
16 {
17   for (int i = 0; i < size; i++)
18   {
19     cout<<a[i]<<",";
20   }
21   cout<<endl;
22 }
23 int main(int argc, char const *argv[])
24 {
25   int a[] = {12,45,3,98,21,7};
26   sort(a,a+sizeof(a)/sizeof(int));//從小到大排序
27   cout<<"1)";Print(a,sizeof(a)/sizeof(int));
28   //結果:1)3,7,12,21,45,98,
29   sort(a,a+sizeof(a)/sizeof(int),rule1());//從大到小排序
30   cout<<"2)";Print(a,sizeof(a)/sizeof(int));
31   //結果:2)98,45,21,12,7,3,
32   sort(a,a+sizeof(a)/sizeof(int),rule2());//按個位數從小到大排序
33   cout<<"3)";Print(a,sizeof(a)/sizeof(int));
34   //結果:3)21,12,3,45,7,98,
35   return 0;
36 }
用法3樣例1(自定義規則排序)

樣例2(結構體陣列排序):

 1 struct Student
 2 {
 3   char name[20];
 4   int id;
 5   double gpa;
 6 };
 7 Student students [] =
 8 {
 9   {"Jack",112,3.4},{"Mary",102,3.8},{"Mary",117,3.9},
10   {"Ala",333,3.5},{"Zero",101,4.0}
11 };
12 //排序範圍是[n1,n2)的元素
13 //在使用二分查詢時,查詢規則必須和排序規則一致
14 struct StudentRule1//按姓名從小到大排
15 {
16   bool operator()(const Student & s1,const Student & s2)const{
17     if (stricmp(s1.name,s2.name) < 0)
18     {
19       return true;
20     }
21     return false;
22   }
23 };
24 struct StudentRule2//按id從小到大排
25 {
26   bool operator()(const Student & s1,const Student & s2)const{
27     return s1.id < s2.id;
28   }
29 };
30 struct StudentRule3//按gpa從高到低排
31 {
32   bool operator()(const Student & s1,const Student & s2)const{
33     return s1.gpa > s2.gpa;
34   }
35 };
36 void PrintStudents(Student s[],int size)
37 {
38   for (int i = 0; i < size; i++)
39   {
40     cout<<"("<<s[i].name<<","<<s[i].id<<","<<s[i].gpa<<")";
41   }
42   cout<<endl;
43 }
44 int main()
45 {
46   int n = sizeof(students)/sizeof(Student);
47 
48   sort(students,students+n,StudentRule1());
49   PrintStudents(students,n);
50   //結果:(Ala,333,3.5)(Jack,112,3.4)(Mary,102,3.8)(Mary,117,3.9)(Zero,101,4)
51   sort(students,students+n,StudentRule2());
52   PrintStudents(students,n);
53   //結果:(Zero,101,4)(Mary,102,3.8)(Jack,112,3.4)(Mary,117,3.9)(Ala,333,3.5)
54   sort(students,students+n,StudentRule3());
55   PrintStudents(students,n);
56   //結果:(Zero,101,4)(Mary,117,3.9)(Mary,102,3.8)(Ala,333,3.5)(Jack,112,3.4)
57   return 0;
58 }
用法3樣例2(結構體陣列排序)

這些就是這次筆記的內容了,感謝大家讀到這裡,祝大家學習愉快,頭髮常駐!