线性表(一)——数组循环右移算法
源码: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;
}
线性表(一)——数组循环右移算法的更多相关文章
- JavaScript 数据结构与算法之美 - 线性表(数组、栈、队列、链表)
前言 基础知识就像是一座大楼的地基,它决定了我们的技术高度. 我们应该多掌握一些可移值的技术或者再过十几年应该都不会过时的技术,数据结构与算法就是其中之一. 栈.队列.链表.堆 是数据结构与算法中的基 ...
- PTA 数组循环右移
6-2 数组循环右移 (20 分) 本题要求实现一个对数组进行循环右移的简单函数:一个数组a中存有n(>)个整数,将每个整数循环向右移m(≥)个位置,即将a中的数据由(a0a1⋯ ...
- 第2章 线性表《C#数据结构和算法》
( )除第一个位置的数据 元素外,其它数据元素位置的前面都只有一个数据元素:( )除最后一个位置的 数据元素外,其它数据元素位置的后面都只有一个元素.也就是说,数据元素是 一个接一个的排列.因此,可以 ...
- 数据结构线性表的动态分配顺序存储结构算法c语言具体实现和算法时间复杂度分析
#include<stdio.h>#include<stdlib.h>//线性表的动态分配顺序存储结构#define LIST_INIT_SIZE 100//线性表存储空间的初 ...
- C语言实现顺序表的基本操作(从键盘输入 生成线性表,读txt文件生成线性表和数组生成线性表----三种写法)
经过三天的时间终于把顺序表的操作实现搞定了.(主要是在测试部分停留了太长时间) 1. 线性表顺序存储的概念:指的是在内存中用一段地址连续的存储单元依次存储线性表中的元素. 2. 采用的实现方式:一段地 ...
- c++线性表和数组的区别
在传统C语言程序中,描述顺序表的存储表示有两种方式:静态方式.动态方式 顺序表的静态存储表示: #define maxSize 100 typedefintT; typedefstruct{ T da ...
- 线性表(存储结构数组)--Java 实现
/*线性表的数组实现 *特点:插入删除慢需要平均移动一半的数据,查找较快 *注意:有重复和无重复的数据对应的操作会有些不同 *注意数组一旦创建其大小就固定了 *Java集合长度可变是由于创建新的数组将 ...
- Java探索之旅(10)——数组线性表ArrayList和字符串生成器StringBuffer/StringBuilder
1.数组线性表ArrayList 数组一旦定义则不可改变大小.ArrayList可以不限定个数的存储对象.添加,插入,删除,查找比较数组更加容易.可以直接使用引用类型变量名输出,相当于toString ...
- 线性表(List)
1.什么是线性表(List)? 零个或多个数据元素的有限序列. (1)元素之间是有序的. (2)线性表强调是有限的. 2.线性表有哪些操作? (1)线性表的创建和初始化,InitList (2)判空, ...
随机推荐
- 如何将SVN patch的修改做成old&new文件
背景 最近解决lua的一则协程问题, 需要将一个patch添加到我们自己的lua库代码中, 由于我们整合的lua库代码目录,与原始的lua库代码不一致,导致不能直接使用path应用到我们自己的lua代 ...
- Anaconda安装与使用
bash Anaconda.....sh命令安装成功 安装位置:/home/amelie/anaconda2 修改路径:vi ~/.bashrc vi编辑器在最后写上:export PATH=/hom ...
- MVC HtmlHelper用法(一)@Html.BeginForm的使用总结
1.@using(Html.BeginForm()){} //提交到当前页面 2.@using ...
- Asp.Net alert 方法
public static void ExcuteAlert(Page page, string strAlerts) { ClientScriptManager ...
- java多态性
多态分两种: (1) 编译时多态(设计时多态):方法重载. (2) 运行时多态:JAVA运行时系统根据调用该方法的实例的类型来决定选择调用哪个方法则被称为运行时多态.(我们平时说得多的事运行时 ...
- stl中的push_back
v_data.push_back(pdata);这句只是把指针pdata拷贝到 vector当中的一个指针p1当中 注意是拷贝也就是说当前pdata和p1指向同一个东西,p1在vector中.并不是将 ...
- 【转】[退役]纪念我的ACM——headacher@XDU
转自:http://hi.baidu.com/headacher/item/5a2ce1d50609091b20e25022 退役了,是时候总结一下我ACM的生涯了.虽然很舍不得,但这段回忆很值得纪念 ...
- SQL复制一个表的数据到另一个表
最近做一个项目,由于客户数据量大,为了不将数据彻底删除,于是将数据移动到历史表,原始表的数据删除.由于技术有限,想不到好的方法,于是写个存储过程 执行,为了防止执行过程中出现异常,执行不完整.用到hI ...
- kali安装nautilus-open-terminal不起作用
apt-get install nautilus-open-terminal (鼠标右键在当前目录打开终端) 这个功能不起作用时,可以按如下操作,经试验有效! nautilus -q && ...
- jquery easyui 解析数据库返回的数据