twomeng

### 编程笔记 cha 2-1 排序

排序算法

1. 排序(牛客网)

 1 #include <iostream>
 2 #include <algorithm>
 3 using namespace std;
 4 /*
 5     题目:排序
 6     思路:1--n冒泡排序、选择排序、快排
 7 */
 8 void bubbleSort(int a[],int n){
 9     int t;
10     for (int i=0;i<n-1;i++){
11         for (int j=0;j<n-i-1;j++){
12             if (a[j]>a[j+1]){
13                 t = a[j];
14                 a[j] = a[j+1];
15                 a[j+1] = t;
16             }
17         }
18     }
19 }
20 void selectSort(int a[],int n){
21     int k,t;
22     for (int i=0;i<n-1;i++){
23         k = i;
24         for (int j=i+1;j<n;j++){
25             if (a[j]<a[k]){
26                 k = j;
27             }
28         }
29         if (k!=i){
30             t = a[k];
31             a[k] = a[i];
32             a[i] = t;
33         }
34     }
35 }
36 void Qsort(int a[],int low,int high){
37     if (low >= high)
38         return;
39 
40     int first = low ;
41     int last = high ;
42     int key = a[first];
43     while (first < last){
44         while (first < last && a[last] >= key){
45             --last; // last先减一,再与first比较
46         }
47         a[first] = a[last];
48         while (first < last && a[first] <= key){
49             ++first;
50         }
51         a[last] = a[first];
52     }
53     a[first]=key; // 交换过程中key并没有交换,此时first/last之前的比key小,之后的比key大,递归调用
54     Qsort(a,low,first-1);
55     Qsort(a,first+1,high);
56 
57 }
58 bool cmp(int x,int y){
59     return x>y;
60 }
61 void print(int a[],int n){
62     for (int i=0;i<n;i++)
63         cout << a[i] << \' \';
64     cout<<endl;
65 }
66 int main()
67 {
68     int n,a[101];
69     while (cin >> n){
70         for (int i=0;i<n;i++)
71             cin >> a[i];
72         //bubbleSort(a,n);
73         //selectSort(a,n);
74         //sort(a,a+n);//内置快排升序算法,推荐使用
75         //sort(a,a+n,cmp);重载降序
76         Qsort(a,0,n-1);
77         print(a,n);
78 
79     }
80     return 0;
81 }

 

2.成绩排序

 1 #include <iostream>
 2 #include <algorithm>
 3 #include <string.h>
 4 using namespace std;
 5 /*
 6     题目:成绩排序
 7     思路:内置排序函数+重构cmp
 8 */
 9 struct Stu{
10     char name[100];
11     // string name;
12     int age;
13     int grade;
14 };
15 bool cmp(Stu s1,Stu s2){
16     if (s1.grade != s2.grade)
17         return s1.grade < s2.grade;//成绩低的在前面
18     int tmp = strcmp(s1.name,s2.name);
19     // int tmp = s1.name - s2.name;
20     if (tmp != 0)
21         return tmp < 0; // 字典序小的在前面
22     return s1.age < s2.age;
23 }
24 void print(Stu s[],int n){
25     for (int i=0;i<n;i++)
26         cout << s[i].name << \' \'<<s[i].age<<\' \'<<s[i].grade<<endl;
27 
28 }
29 int main()
30 {
31     int n;
32     Stu s[1001];
33     while (cin >> n){
34         for (int i=0;i<n;i++)
35             cin >> s[i].name>>s[i].age>>s[i].grade;
36         sort(s,s+n,cmp);
37         print(s,n);
38     }
39 
40 
41     return 0;
42 }

 

特殊排序

 1 #include <iostream>
 2 #include <algorithm>
 3 #include <string.h>
 4 using namespace std;
 5 /*
 6     题目:特殊排序
 7     思路:内置排序函数+重构cmp
 8 */
 9 
10 void print(int a[],int n){
11     cout<<a[n-1]<<endl;
12     if (n!=1){
13         for (int i=0;i<n-2;i++)
14             cout << a[i] << \' \';
15         cout <<a[n-2]<<endl;
16         // 提示格式错误:最后一个数后面没有空格
17     }
18     else{
19         cout<<-1<<endl;
20     }
21 }
22 int main()
23 {
24     int n,a[1001];
25     while (cin >> n){
26         for (int i=0;i<n;i++)
27             cin >> a[i];
28         sort(a,a+n);
29         print(a,n);
30     }
31 
32 
33     return 0;
34 }

 

EXCEL排序

  1 #include <iostream>
  2 #include <algorithm>
  3 #include <string.h>
  4 using namespace std;
  5 /*
  6     题目:EXCEL排序
  7     遇到的问题:定义number和name同时为char类型时,在一行内输入“010000 ack 30 ”时空格
  8     会被视为字符串内的一个字符,因此连续cin多个字符串时应当用回车来分离字符串。
  9     这里审题不清:将number定义为整数够用。
 10 
 11     报错:编译错误:
 12     error: control may reach end of non-void function [-Werror,-Wreturn-type]
 13     原因:某些测试条件下函数没有响应的返回
 14 
 15     输出int number时为了变成‘000001’的6位形式需加上my_itoa()函数
 16 
 17     当number和name都是char[]类型时的另一种输入方法:
 18     scanf("%s %s %d",buf[i].num,buf[i].name,&buf[i].score);
 19 */
 20 struct Stu{
 21     int number;
 22     char name[8];
 23     int grade;
 24 }student[100000];
 25 int c;
 26 /*
 27 替代写法:
 28  cout << setw(6) << setfill(\'0\') << list[i].num << " ";
 29  setw设置输出宽度为6位
 30  除去输出数据num所占位数外其余填充fill0 
 31 */
 32 char *my_itoa(int n)
 33 {
 34     static char str[7];
 35     int i;
 36     for(i=0;i<6;i++)
 37         str[i]=\'0\';
 38     str[7]=\'\0\';
 39     i=5;
 40     while(n)
 41     {
 42         str[i--]=n%10 + \'0\';
 43         n/=10;
 44     }
 45     return str;
 46 }
 47 bool cmp(Stu a,Stu b)
 48 {
 49     switch(c)
 50     {
 51     case 1:return a.number<b.number;
 52     case 2:
 53         if (strcmp(a.name,b.name)==0)
 54             return a.number-b.number<0;
 55         else
 56             return strcmp(a.name,b.name)<=0;
 57     case 3:
 58         if (a.grade==b.grade)
 59             return a.number<b.number;
 60         else
 61             return a.grade<=b.grade;
 62     default:return 0;
 63     }
 64 }
 65 
 66 /*
 67 cmp函数的另一种写法:
 68 
 69 
 70 bool cmp1(stu a, stu b) {
 71 
 72     return a.num < b.num; // 递增,当a<b时返回真
 73 
 74 }
 75 
 76 bool cmp2(stu a, stu b) {
 77 
 78     return a.name <= b.name;// 非递减 
 79 
 80 }
 81 
 82 bool cmp3(stu a, stu b) {
 83 
 84     if (a.grade != b.grade) {
 85 
 86         return a.grade <= b.grade; // 非递减 
 87 
 88     }
 89 
 90     else {
 91 
 92         return a.num < b.num;
 93 
 94     }
 95 
 96 }
 97 */
 98 void print(int n)
 99 {
100     cout<<"Case:"<<endl;
101     for (int i=0;i<n;i++)
102     {
103         cout<<my_itoa(student[i].number)<<" "<<student[i].name<<" "<<student[i].grade<<endl;
104     }
105 }
106 int main()
107 {
108 
109     int n;
110     while (cin>>n)
111     {
112         cin>>c;
113         for (int i=0;i<n;i++)
114         {
115             cin>>student[i].number;
116             cin>>student[i].name;
117             cin>>student[i].grade;
118         }
119         sort(student,student+n,cmp);
120         print(n);
121 
122     }
123 
124 
125 
126 
127     return 0;
128 }

 

字符串排序

 1 #include <iostream>
 2 #include <algorithm>
 3 #include <string.h>
 4 #include <stdio.h>
 5 using namespace std;
 6 /*
 7     题目:字符串内排序
 8     思路:字符串相当于一个数组,字母本质是个整数,所以用sort()配合strlen()求出字符串长度绰绰有余啦。
 9 */
10 int main()
11 {
12     char str[200];
13     while (scanf("%s",str)!=EOF)
14     {
15         sort(str,str+strlen(str));
16         cout<<str<<endl;
17     }
18     return 0;
19 }

 排序总结:

头文件:algorithm.h 

快排函数:sort(数组名,数组名+数组长度,比较函数(默认为从小到大排序))

比较函数的定义:

(1)非结构体的基本数据类型作为参数的比较函数定义

bool cmp(int x,int y)
{
    return x<y; // 递增
}
bool cmp(int x,int y)
{
    return x<=y; // 非递减
}
bool cmp(int x,int y)
{
    return x>y; // 递减
}
bool cmp(int x,int y)
{
    return x>=y; // 非递增
}

(2)结构体的比较函数定义

 1 struct stu
 2 {
 3     char name[101];
 4     int age;
 5     int score;
 6     bool operator<(const stu &b)const 
 7 {
 8     // 分数不相同时分数低者在前
 9     if (score!=b.score) return score<b.score;
10     int tmp=strcmp(name,b.name);
11     if (tmp!=0) return tmp<0;
12     else return age < b.age;
13 }
14 };
15 bool cmp(const stu &a, const stu &b)
16 {
17     // 分数不相同时分数低者在前
18     if (a.score!=b.score) return a.score<b.score;
19     int tmp=strcmp(a.name,b.name);
20     if (tmp!=0) return tmp<0;
21     else return a.age < b.age;
22 }

第一种方式:定义cmp函数,参数最好写成const 数据类型 &变量名的形式,防止调用函数过程中对于变量的改变

第二种方式:结构体内重载<运算符,此时参数和成员函数进行比较,仅需要一个参数即可。注意此时函数要定义成const的不可变函数,否则会报错。

 

 

 

 

分类:

技术点:

相关文章: