源码: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("\n");
} int main(int argc, char* argv[])
{
int a[] = { 1,2,3,4,5,6 };
printf("=====================\n");
print_array(a, 6);
printf("========== rshift ==========\n");
rshift1(a, 6, 3);
print_array(a, 6);
printf("========== rshift ==========\n");
rshift2(a, 6, 3);
print_array(a, 6);
return 0;
}

线性表(一)——数组循环右移算法的更多相关文章

  1. JavaScript 数据结构与算法之美 - 线性表(数组、栈、队列、链表)

    前言 基础知识就像是一座大楼的地基,它决定了我们的技术高度. 我们应该多掌握一些可移值的技术或者再过十几年应该都不会过时的技术,数据结构与算法就是其中之一. 栈.队列.链表.堆 是数据结构与算法中的基 ...

  2. PTA 数组循环右移

    6-2 数组循环右移 (20 分)   本题要求实现一个对数组进行循环右移的简单函数:一个数组a中存有n(>)个整数,将每个整数循环向右移m(≥)个位置,即将a中的数据由(a​0​​a​1​​⋯ ...

  3. 第2章 线性表《C#数据结构和算法》

    ( )除第一个位置的数据 元素外,其它数据元素位置的前面都只有一个数据元素:( )除最后一个位置的 数据元素外,其它数据元素位置的后面都只有一个元素.也就是说,数据元素是 一个接一个的排列.因此,可以 ...

  4. 数据结构线性表的动态分配顺序存储结构算法c语言具体实现和算法时间复杂度分析

    #include<stdio.h>#include<stdlib.h>//线性表的动态分配顺序存储结构#define LIST_INIT_SIZE 100//线性表存储空间的初 ...

  5. C语言实现顺序表的基本操作(从键盘输入 生成线性表,读txt文件生成线性表和数组生成线性表----三种写法)

    经过三天的时间终于把顺序表的操作实现搞定了.(主要是在测试部分停留了太长时间) 1. 线性表顺序存储的概念:指的是在内存中用一段地址连续的存储单元依次存储线性表中的元素. 2. 采用的实现方式:一段地 ...

  6. c++线性表和数组的区别

    在传统C语言程序中,描述顺序表的存储表示有两种方式:静态方式.动态方式 顺序表的静态存储表示: #define maxSize 100 typedefintT; typedefstruct{ T da ...

  7. 线性表(存储结构数组)--Java 实现

    /*线性表的数组实现 *特点:插入删除慢需要平均移动一半的数据,查找较快 *注意:有重复和无重复的数据对应的操作会有些不同 *注意数组一旦创建其大小就固定了 *Java集合长度可变是由于创建新的数组将 ...

  8. Java探索之旅(10)——数组线性表ArrayList和字符串生成器StringBuffer/StringBuilder

    1.数组线性表ArrayList 数组一旦定义则不可改变大小.ArrayList可以不限定个数的存储对象.添加,插入,删除,查找比较数组更加容易.可以直接使用引用类型变量名输出,相当于toString ...

  9. 线性表(List)

    1.什么是线性表(List)? 零个或多个数据元素的有限序列. (1)元素之间是有序的. (2)线性表强调是有限的. 2.线性表有哪些操作? (1)线性表的创建和初始化,InitList (2)判空, ...

随机推荐

  1. iOS,XMPP本地环境搭建和框架使用

    1.XMPP的MySQL和openfire环境配置 2.XmppFramework框架导入和介绍 XMPP的MySQL和openfire环境配置 1.下载mysql安装 mysql下载 打开MySQL ...

  2. RDIFramework.NET ━ Web中打印的各种方案参考-欢迎补充

    RDIFramework.NET ━ Web中打印的各种方案参考-欢迎补充 做Web开发的同志应该都深有体会,在web程序中打印不再象应用程序中那样便于控制了,web程序天生的一些特性造成了这个缺点, ...

  3. (转)MVC设计模式学习总结

    原文  : chenchun的博客 http://www.cnblogs.com/jobscn/archive/2011/11/08/2240725.html -------------------- ...

  4. Centos 安装 Java

    建立文件夹 进入/usr/文件夹下,建立一个文件,我这里是java文件夹,将jdk-8u45-linux-x64.tar.gz复制到/usr/java文件夹下 解压文件 解压指令为:tar -zxvf ...

  5. 让Docker容器使用静态独立的外部IP(便于集群组建)

    需要使用Docker虚拟化Hadoop/Spark等测试环境,并且要可以对外提供服务,要求是完全分布式的部署(尽量模拟生产环境).那么我们会遇到几个问题: Container IP 是动态分配的 Co ...

  6. openDatabase() chrome vivaldi Stylish

    located at /Users/ruili/Library/Application Support/Vivaldi/Default/databases/ Databases.db contains ...

  7. Oracle logmnr工具分析日志脚本

    在oracle:对logmnr工具分析日志这个不陌生:对数据恢复应用场景经常用到:这里为了方便对归档日志进行分析: 当然网上有一个logmnr界面的工具:感觉很人性化:下载需要积分:为此写一个脚本. ...

  8. windows+caffe(四)——创建模型并编写配置文件+训练和测试

    1.模型就用程序自带的caffenet模型,位置在 models/bvlc_reference_caffenet/文件夹下, 将需要的两个配置文件,复制到myfile文件夹内 2. 修改solver. ...

  9. Tomcat配置文件之servlet.xml中选项介绍

    Servlet.xml 分为以下元素: server, service, Connector ( 表示客户端和service之间的连接), Engine ( 表示指定service 中的请求处理机,接 ...

  10. ReactJs入门教程

    现在最热门的前端框架有AngularJS.React.Bootstrap等.自从接触了ReactJS,ReactJs的虚拟DOM(Virtual DOM)和组件化的开发深深的吸引了我,下面来跟我一起领 ...