源码: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. HTTP协议上传boundary确定&下载content-disposition理解

    HTTP协议上传文件-协议 上传文件需要将form标签 的 ENCTYPE 属性设置为 multipart/form-data属性, 与 application/x-www-form-urlencod ...

  2. [转] CentOS单独安装Apache Benchmark压力测试工具的办法

    Apache安装包中自带的压力测试工具 Apache Benchmark(简称ab) 简单易用,这里就采用 ab作为压力测试工具了. 1.独立安装 ab运行需要依赖apr-util包,安装命令为: 1 ...

  3. sdutoj 2609 A-Number and B-Number

    http://acm.sdut.edu.cn/sdutoj/problem.php?action=showproblem&problemid=2609 A-Number and B-Numbe ...

  4. Android studio 查看签名

    根据密钥查看 根据安装包查看:改apk为zip 解压 打开 META-INF --->cmd: keytool -printcert -file CERT.RSA

  5. AJAX-----14HTML5中新增的API---files

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  6. 【转】PowerShell入门(序):为什么需要PowerShell?

    转至:http://www.cnblogs.com/ceachy/archive/2013/01/23/PowerShellPreface.html 曾几何时,微软的服务器操作系统因为缺乏一个强大的S ...

  7. Egret官方案例学习笔记

    1.资源记载方式 (1)Egret引擎是2.0.5. (2)resource/resource.json文件是: { "resources": [ { "name&quo ...

  8. Annotation

    Annotation是给类,方法或域上加的一种特殊的标记,可以通过反射取到注解的类型和值,从而完成某种特定的操作. 定义注解需要使用元注解,元注解有@Retention和@Target p.p1 { ...

  9. QT笔记之VS开发程序遇到的问题

    转载:http://www.cnblogs.com/li-peng/p/3644812.html 转载:http://www.cnblogs.com/csuftzzk/p/VS_Qt_Experien ...

  10. PHP延迟静态绑定:static关键字

    PHP5.3中引入了延迟静态绑定的概念.该特性最明显的标志就是新关键字static.static类似于self,但它指的是被调用的类而不是包含类.在本例中,它的意思是调用Document::creat ...