• 插入排序 静态链表转为有序数组


    #include <bits/stdc++.h>
    using namespace std;
    const int maxn = 1e5+7;
    int M[maxn];
    int N[maxn];///变化之前的链数组
    int W[maxn];///变化之后的链数组
    int n;
    /*
       插入排序的主要思路就是一个有序组和一个无序组   
       A1 | A2  A3  A4  A5   
       然后的话将右边的无序区的数组一个一个的插入左边的有序组
    */
    void init()
    {
        N[0] = 1;
        ///处理下边界,此处相当于表头节点
        for (int i=1;i<=n;++i)  N[i] = i+1;
        ///初始化  ,当前和下一个相连的下标就是当前下标+1
        N[n] = 0;
        ///链表最后就指向0   
    }
    /*
         静态链表
         M数据负责储存原始数据
         N数组相当于指针,指出下一个
         N[i]记录的是和i相连的下一个区块的下标
    */
    void out(int x)
    {
        if (x)
        {
          printf("%d ",M[x]);
          out(N[x]);
        }
    }///  输出函数
    int main()
    {
        scanf("%d",&n);
        init();
        for (int i=1;i<=n;++i)
        {
          scanf("%d",M+i); 
          /// cout<< M[i]<<endl;
        }
        if (N[0])
        {
            int p = 2;
            N[1] = 0; ///类似于之前的链表,只不过相当于将next指针换成一个数组   首先将链表的头截断
            while (p)
            {
                int t = 0;
                int q = N[p];///  记录下p的下一个坐标 防止丢失
                while (N[t] && M[p]>M[N[t]]) t = N[t];/// 找到有序组中可以插入的位置  找到的就是可以插入的位置的(前面那个)
                N[p] = N[t]; /// 首先取代t,将t的后面的那一段接给p
                N[t] = p;/// t的下一个就是p
                p = q;///无序组中的下一个
            }
         }
         
         ///out(N[0]);///输出
         ///cout<<endl;
         ///  之前的已经按照静态链表的数组进行储存
         ///  现在需要将数组变成有序数组  就不需要N数组的辅助
         for (int k=0;k<=n;++k)
         {
             W[k] = N[k];///  进行复制
         }
         int i = 1;
         int j = N[0];
         for (i = 1;i < n;++i)
         {
           ///cout<<i<<' '<<j<<endl;
           if (i==j)  ///  i是摆放的位置  j是摆放的数据来源的下标  相同就直接下一个
           {
             j = N[j];
           }
           else if(i<j) /// 如果当前的在后面 直接交换  已经摆好位置的i被后面的M[j]取代,
            ///  那么下次如果有之前的寻找的话,此时将W【i】变为J代表该位置已经被移动到j位置
           {
             swap(M[i],M[j]);
             W[j] = W[i];
             W[i] = j;
             j = N[j];  
           }
           else 
           {
              int t = j;/// j本身不能动,因为要从这里寻找下一个位置
              while (i>t) t=W[t];    ///  i>j 说明我现在需要交换的数据来源于之前的j,但是之前的位置按照w[t]一直寻找
              swap(M[i],M[t]);/// 跳到 i<j 的位置  然后进行交换   
              W[i] = t;  
              j = N[j];///  但是原本的位置还是需要保留   因为每次都是根据之前的原来的连接关系来求解的
           }
         }
         for (int t=1;t<=n;++t)
         {
           printf("%d ",M[t]);
         }
         puts("");
         return 0;
    }
    
    齐芒行,川锋明!
  • 相关阅读:
    Android中setContentView与inflate的区别
    Android RelativeLayout(相对布局)
    web移动开发最佳实践之js篇(转)
    SQL Server全文索引 (简单的搜索引擎)
    浅谈SQL Server中的三种物理连接操作 (转)
    sql server 优化顾问学习(转)
    IIS优化网站性能(转)
    js,css文件压缩
    SQL Server Profiler学习
    有效提高命中率的缓存设计
  • 原文地址:https://www.cnblogs.com/qimang-311/p/14036417.html
Copyright © 2020-2023  润新知