zoukankan      html  css  js  c++  java
  • 插入排序

                                          知识点总结报告

    知识点:

    插入排序

    (原理)每次将一个待排序的元素按其关键字大小插入到前面已经排好序的子表中的适当位置,直到全部元素插入完成为止。主要有三种排序方法直接插入排序,折半插入排序,希尔排序。

    直接插入排序

    将当前无序区的开头元素R[i](1<=i<=n-1)插入到有序区R[0...i-1]中的适当位置,使R[0...i]变为新的有序区。

    void InsertSort(RecType R[ ],int n)     //对R[0...n-1]按递增有序进直接插入排序

    {  int i,j; RecType tmp;

      for(i=1;i<n;i++)

      {  if(R[i].key<R[i-1].key)  //反序时

        {  tmp=R[i];

          j=i-1;

          do      //找R[i]的插入位置

          {  R[j+1]=R[j];      //将关键字大于R[i].key的记录后移

            j--;

          }  while (j>=0&&R[j].key>tmp.key);

          R[j+1]=tmp;      //在j+1处插入R[i]

         }

      }

    }

    折半插入排序

    有序区的元素是有序的,可以采用折半查找方法先在R[0...i-1]中找到插入位置,再通过移动元素进行插入。

    void BinInsertSort(RecType R[ ],int n)

    {  int i,j,low,high,mid;

      RecType tmp;

      for(i=1;i<n;i++)

      {  if(R[i].key<R[i-1].key)    //反序时

        {  tmp=R[i];        //将R[i]保存到tmp中

           low=0;  high=i-1;

          while(low<=high)      //在R[low...high]中查找插入的位置

          {  mid=(low+high)/2;    //取中间位置

            if(tmp.key<R[mid].key)

              high=mid-1;      //插入点在左半区

            else

              low=mid+1;      //插入点在右半区

          }              //找位置high

          for(j=i-1;j>=high+1;j--)    //集中进行元素后移

            R[j+1]=R[j];

          R[high+1]=tmp;      //插入tmp

        }

      }

    }

    希尔排序

    先取一个小于n的整数d1作为第一个增量,把表的全部元素分成d1个组,将所有距离为d1的倍数的元素放在同一个组,在各组内进行直接插入排序;然后取第二个增量d2(<d1),重复上述分组和排序,直到所取的增量dt=1(dt<dt-1<...<d2<d1),即所有元素放在同一组中进行直接插入排序为止。

    void ShellSort(RecType R[ ],int n)    //希尔排序算法

    {  int i,j,d;

      RecType tmp;

      d=n/2;        //增量置初值

      while(d>0)

      {  for(i=d;i<n;i++)      //对所有组采用直接插入排序

        {  tmp=R[i];      //对相隔d个位置一组采用直接插入排序

          j=i-d;

          while(j>=0&&tmp.key<R[j].key)

          {  R[j+d]=R[j];

             j=j-d;

          }

          R[j+d]=tmp;

        }

        d=d/2;      //减小增量

      }

    }

    (例题)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1106

     

    Problem Description
    输入一行数字,如果我们把这行数字中的‘5’都看成空格,那么就得到一行用空格分割的若干非负整数(可能有些整数以‘0’开头,这些头部的‘0’应该被忽略掉,除非这个整数就是由若干个‘0’组成的,这时这个整数就是0)。

    你的任务是:对这些分割得到的整数,依从小到大的顺序排序输出。

     

     

    Input
    输入包含多组测试用例,每组输入数据只有一行数字(数字之间没有空格),这行数字的长度不大于1000。  

    输入数据保证:分割得到的非负整数不会大于100000000;输入数据不可能全由‘5’组成。
     

     

    Output
    对于每个测试用例,输出分割得到的整数排序的结果,相邻的两个整数之间用一个空格分开,每组输出占一行。
     

     

    Sample Input
    0051231232050775
     

     

    Sample Output
    0 77 12312320

    题目分析:

     所用知识:排序、字符串处理

    题解: 将这个字符串进行逐个判断,利用一个数组进行保存,最后用sort排序即可【注意输出格式】。

    题解代码:

    #include<cstdio>
    #include<algorithm>
    
    using namespace std;
    
    size_t const MAXSIZE = 1000 + 3;
    char str[MAXSIZE];
    int A[MAXSIZE];
    
    int main() {
        int n, t;
        bool flag = false;
        while (~scanf("%s", str)) {
            flag = 0; t = 0;
            memset(A ,0, sizeof A);
            n = strlen(str);
            for (int i = 0; i < n; i++) {
                if (str[i] != '5') {
                    A[t] = A[t] * 10 + (str[i] - 48);//对一段数字进行保存
                    flag = true;
                }
                else if (flag) {
                    ++t;
                    flag = false;
                }
                if (str[i] != '5'&& str[i + 1] == '\0') ++t;
            }
            
            sort(A, A + t);
            for (int i = 0; i<t; i++) {
                if (i == 0) printf("%d", A[i]);
                else printf(" %d", A[i]);
            }
            printf("\n");
        }
        return 0;
    }
     

     

    ---恢复内容结束---

  • 相关阅读:
    shell脚本之数组
    shell脚本之函数
    shell脚本之sed
    shell脚本的for循环与read
    shell脚本之if语句
    shell脚本正则表达式
    shell的编程原理
    《梦断代码》阅读笔记03
    12.19学习总结
    《梦断代码》阅读笔记02
  • 原文地址:https://www.cnblogs.com/li1997/p/8340889.html
Copyright © 2011-2022 走看看