• 算法初步——排序


    简单选择排序

    • 令i从0到n-1枚举,进行n趟操作,每趟从A[i,n]中选择最小的元素 ,算法复杂度为O(n^2)
      /*
          选择排序
          思路:令i从0到n-1枚举,进行n趟操作,每趟从A[i,n]中选择最小的元素 
      */
      
      void selectSort(int A[], int n) {
          for(int i=0; i<n; ++i) {
              int k = i;                        // 记录最小元素 
              for(int j=i+1; j<n; ++j) {        // 从A[i,n]中选择最小的元素
                  if(a[j] < a[k])    k = j;
              }
              
              int temp = a[i];            // 交换 
              a[i] = a[k];
              a[k] = temp; 
          }
      }

    直接插入排序

    • 假设某一趟时,序列A的前i-1个元素A[1]~A[i-1]已经有序,然后从范围[1,i-1]中寻找某个位置j ,使得插入后仍然有序,算法复杂度为O(n^2)

      /*
          直接插入排序
          思路: 假设某一趟时,序列A的前i-1个元素A[1]~A[i-1]已经有序,
                 然后从范围[1,i-1]中寻找某个位置j ,使得插入后仍然有序 
      */
      
      void insertSort(int A[], int n) {
          for(int i=1; i<n; ++i) {        // 进行n-1趟排序 
              int temp=A[i], j=i;            // 从前往后遍历
              while(j>0 && temp<A[j-1]) {
                  A[j] = A[j-1];            // 后移 
                  j--;
              } 
              A[j] = temp; 
          }
      } 

    sort函数的应用

    • 使用时必须加上头文件  #include <algorithm>  和   using namespace std; 
    •  函数原型

      // sort(首元素的地址(必填),尾元素地址的下一个地址,比较函数(非必填))
      sort(a, a+6);
    • 如何实现比较函数cmp
      • 若比较函数不填,则默认按照从小到大的顺序排序,如果想要从大到小来排序,则要使用比较函数cmp
        bool cmp(int a, int b) {
            return a > b;    // 可以理解为当 a > b 时把 a 放前面 
        }  
      • 结构体数组的排序
        • 一级排序,按照 x 从大到小排序
          struct node {    // 结构体定义 
              int x, y;
          } ssd[10]; 
          bool cmp(node a, node b) {            // 一级排序 
              // 将ssd数组按照x从大到小排序 
              return a.x > b.x;
          } 
        • 二级排序,先按照 x 从大到小排序,但当 x 相等的情况下,按照 y 的大小来排序
          bool cmp(node a, node b) {            // 二级排序 
              // 将ssd数组先按照 x 从大到小排序,
              // 但当 x 相等的情况下,按照 y 的大小来排序
              if(a.x != b.x)    return a.x > b.x;
              else return a.y > b.y;
          }
      • 容器的排序
        • 在 STL 标准容器中,只有 vector、string、deque 是可以使用 sort 的。这是因为 set、map 这种容器是用红黑树实现的,元素本身有序
        • vector 的排序: sort(vi.begin(), vi.end()); // 对 vi 进行排序 
        • string 的排序: sort(str, str+3); // 对 str 进行排序        

      • 实例:对学生进行排序
        • 如果两个学生分数不相同,那么分数高的排在前面
        • 否则,将姓名字典序小的排在前面
          struct Student {
              char name[10];        // 姓名
              char id[10];        // 准考证号
              int score;            // 分数
              int rank;            // 排名 
          } stu[10010]; 
          bool cmp(Student a, Student b) {    // 二级排序 
              if(a.score != b.score)    return a.score > b.score;
              else return (strcmp(a.name, b.name) < 0);
          }      
    • 排名的实现
      • 规则一般是:分数不相同的排名不同,分数相同的排名相同但占用一个排位
        • 在数组排序完成后,先将数组的第一个个体(假设数组下标从0开始)的排名记为1
        • 然后遍历剩余个体
          • 如果当前个体的分数等于上一个个体的分数,那么当前个体的排名等于上一个个体的排名
          • 否则,当前个体的排名等于数组下标加一
            stu[0].rank = 1;
            for(int i=1; i<n; ++i) {
                if(stu[i].score == stu[i-1].score) {
                    stu[i].rank = stu[i-1].rank;
                } else {
                    stu[i].rank = i+1;
                }
            } 

     

    PAT A1025 PAT Ranking       

    •  题意:在 n 个考场有若干数量的考生。现在给出各个考场中考生的准考证号与分数,要求将所有考生按分数从高到低排序,并顺序输出所有考生的准考证号、排名、考场号、考场排名
    • 思路:
      • 按考场读入各考生的信息,并对当前读入的考生进行排序,将排名写入结构体中 
      • 对所有考生进行排序
      • 按顺序一边计算总排名,一边输出所有考生的信息
         1 #include <cstdio>
         2 #include <cstring>
         3 #include <algorithm>
         4 #include <cmath>
         5 using namespace std;
         6 
         7 struct Student {
         8     char id[15];            // 准考证号
         9     int score;                // 分数
        10     int location_number;    // 考场号
        11     int local_rank;            // 考场排名 
        12 } stu[30010]; 
        13 
        14 // 定义排序方法 
        15 bool cmp(Student a, Student b) {
        16     // 先按分数从大到小排序 
        17     if(a.score != b.score)    return a.score > b.score;
        18     else return (strcmp(a.id, b.id) < 0);    // 后按准考证号排序 
        19 } 
        20 
        21 int main() {
        22     int n, k, num=0;    // n 考场数 k 考场人数 num 总人数
        23     scanf("%d", &n);     // 输入考场数 
        24     
        25     // 按考场输入并排名 
        26     for(int i=1; i<=n; ++i) {
        27         scanf("%d", &k);    // 输入考场人数
        28         for(int j=1; j<=k; ++j) {    // 输入考生信息 
        29             scanf("%s %d", stu[num].id, &stu[num].score);
        30             stu[num].location_number = i;
        31             num++;            // 考生数量 +1 
        32         } 
        33         sort(stu+num-k, stu+num, cmp);    // 考场排序 
        34         stu[num-k].local_rank = 1;                        // 考场内排名 
        35         for(int j=num-k+1; j<num; ++j) {
        36             if(stu[j].score == stu[j-1].score) {
        37                 stu[j].local_rank = stu[j-1].local_rank;
        38             } else {
        39                 stu[j].local_rank = j - (num-k) +1;
        40             }
        41         } 
        42     }
        43     // 所有考生排名并输出信息 
        44     sort(stu, stu+num, cmp);
        45     int rank = 1;                // 记录排名 
        46     printf("%d
        ", num);        // 边计算总排名,边输出信息 
        47     printf("%s %d %d %d
        ", stu[0].id, rank, stu[0].location_number, stu[0].local_rank); 
        48     for(int i=1; i<num; ++i) {
        49         if(stu[i].score != stu[i-1].score) {
        50             rank = i+1;
        51         }
        52         printf("%s %d %d %d
        ", stu[i].id, rank, stu[i].location_number, stu[i].local_rank); 
        53     } 
        54 
        55     return 0;
        56 }

    qsort 函数的应用

      c语言中没有预置的sort函数,如果在c语言中,要调用sort函数,就需要使用c语言自有的qsort函数,其头文件为stdlib.h。

    函数原型

    1 void __cdecl qsort (void *base,size_t num,size_t width
    2             ,int (__cdecl *comp)(const void *,const void*))  

    输入参数:

      base:待排序数组

      num:数组元素的个数

      width:每一个元素所占存储空间的大小

      comp:自定义,决定排序的顺序

    以下是 qsort 的几种用法(升序排列)

    1. 对一维数组排序:

    1 #define ElemType double    // 可以为 char、int、float、double 
    2 // 对一维数组排序 
    3 int cmp1(const void* a, const void* b) {
    4     return *((ElemType*)a) > *((ElemType*)b) ? 1:-1;
    5 }

    2. 对字符串排序:

    1 // 对字符串排序
    2 int cmp2(const void* a, const void* b) {
    3     return strcmp((char*)a, (char*)b);
    4 }

    3. 按结构体中多个关键字排序(多级排序):

     1 // 对结构体排序
     2 struct node {
     3     double data;
     4     int other;
     5 } s[100];
     6 // 先按 data 从小到大排序
     7 // 若 data 相等,按 other 从小到大排序 
     8 int cmp3(const void* a, const void* b) {
     9     struct node* c = (node*)a;
    10     struct node* d = (node*)b;
    11     if(c->data != d->data) {
    12         return (c->data > d->data) ? 1 : -1;
    13     } else {
    14         return c->other - d->other;
    15     }
    16 }
  • 相关阅读:
    面向对象与面向过程的区别
    IE浏览器上传文件时本地路径变成”C:\fakepath\”的问题
    ldap bdb_db_open 错误解决办法
    转载:技术普及帖:你刚才在淘宝上买了一件东西
    js错误捕捉
    Linux服务器管理系统wdcp Lanmp
    [译]Pro ASP.NET MVC 3 Framework 3rd Edition (Chapter 20 JQuery) 0.引言
    发一个自己写的账号管理软件
    [译]Pro ASP.NET MVC 3 Framework 3rd Edition (Chapter 20 JQuery) 4.Basic jQuery Theory jQuery理论基础
    资源下载(2011609更新)
  • 原文地址:https://www.cnblogs.com/coderJiebao/p/Algorithmofnotes03.html
Copyright © 2020-2023  润新知