• 线性表(一)——数组循环右移算法


    源码:rshift.cpp

    #include "stdafx.h"
    #include <stdio.h>
    
    
    /************************************************************************/
    /* 数组循环右移算法                                                     */
    /************************************************************************/
    
    /*
     * 要求:只用一个元素大小的辅助空间,且时间复杂度为O(n)
     */
    
    //************************************
    // Method:    求最大公约数(辗转相除)
    // FullName:  gcd
    // Access:    public 
    // Returns:   int
    // Qualifier:
    // Parameter: int m
    // Parameter: int n
    //************************************
    int gcd(int m, int n)
    {
        return n ? gcd(n, m % n) : m;
    }
    
    //************************************
    // Method:    循环右移解法一(通俗解法)
    // FullName:  rshift1
    // Access:    public 
    // Returns:   void
    // Qualifier:
    // Parameter: int array[]
    // Parameter: int length
    // Parameter: int shift
    //************************************
    void rshift1(int array[], int length, int shift)
    {
        //求最少循环移动链的数量
        //设length=m,shift=n
        //则[0] -> [n%m] -> [2n%m] -> ... -> [mn%m]=[0]=起始
        //假设kn%m==0,令m=gcd*X,n=gcd*Y,则X与Y互斥
        //则k*Y%X==0,Y与X互斥,故X能整除k,故k=m/gcd
        //k是一条链条的长度,故链条的数量为m/k=gcd
        int least_movement = gcd(length, shift);//最少循环移动链的数量
        int i;
        for (i = 0; i < least_movement; i++)
        {
            int swap_a = i;
            int swap_b = (i + shift) % length;
            int tmp = array[swap_a];
            while (swap_b != i)
            {
                array[swap_a] = array[swap_b];
                swap_a = swap_b;
                swap_b = (swap_b + shift) % length;
            }
            array[swap_a] = tmp;
        }
    }
    
    //************************************
    // Method:    循环右移解法二(翻转解法)
    // FullName:  rshift2
    // Access:    public 
    // Returns:   void
    // Qualifier:
    // Parameter: int array[]
    // Parameter: int length
    // Parameter: int shift
    //************************************
    void rshift2(int array[], int length, int shift)
    {
        //翻手掌算法
        //设length=m,shift=n(n=n%m)
        //方法:分割数组 => array1[0 .. n-1] | array2[ n .. m-1 ]
        //array1翻转,array2翻转,再整体翻转
        //
        //原先:     1,2,3,4,..,n-1     | n,...,m-2,m-1
        //各自翻转: n-1,n-2,...,2,1    | m-1,m-2,...,n
        //全部翻转: n,n+1,...,m-2,m-1  | 1,2,3,...,n-2,n-1
        //这就完成了右移n单位的任务
        int i;
        shift %= length;
        int tmp;
        for (i = 0; i < (shift - 1) / 2; i++)
        {
            tmp = array[i];
            array[i] = array[shift - i - 1];
            array[shift - i - 1] = tmp;
        }
        for (i = shift; i < shift + (length - shift) / 2; i++)
        {
            tmp = array[i];
            array[i] = array[length + shift - i - 1];
            array[length + shift - i - 1] = tmp;
        }
        for (i = 0; i < length / 2; i++)
        {
            tmp = array[i];
            array[i] = array[length - i - 1];
            array[length - i - 1] = tmp;
        }
    }
    
    void print_array(int array[], int length)
    {
        int i;
        for (i = 0; i < length; i++)
        {
            printf("%d ", array[i]);
        }
        printf("
    ");
    }
    
    int main(int argc, char* argv[])
    {
        int a[] = { 1,2,3,4,5,6 };
        printf("=====================
    ");
        print_array(a, 6);
        printf("========== rshift ==========
    ");
        rshift1(a, 6, 3);
        print_array(a, 6);
        printf("========== rshift ==========
    ");
        rshift2(a, 6, 3);
        print_array(a, 6);
        return 0;
    }
  • 相关阅读:
    Flutter 开发环境搭建
    swift 如何控制view的显示与隐藏
    TextView textSize 文字大小
    Android项目增加混淆
    Android EditText 无法换行
    Android 6.0 新特性 整理 资料来自网络
    java线程中的sleep/wait/notify/yield/interrupt方法 整理
    java 抽象类与接口的区别 整理
    android 系统架构
    android handler工作原理
  • 原文地址:https://www.cnblogs.com/bajdcc/p/4768163.html
Copyright © 2020-2023  润新知