主题:有意者请踩踩,留下足迹!!
TL123
[专家分:0] 发布于 2006-10-24 22:12:00
由于初学数据结构,对写算法来说还不是很行,所以请大家给出你们所想到的答案或者留点意见,谢谢!!
题目:
试设计一个算法,将数组An中的元素A[0]至A[n-1]循环右移k位,并要求只用一个元素大小的附加存储,元素移动或交换次数为O(n).
回复列表 (共1个回复)
沙发
leolhc [专家分:430] 发布于 2006-10-27 21:11:00
1、求n与k的最大公约数
2、按1到最大公约数作一个mod等价类的划分
3、对每个等价类进行右移
例如:
n=6;k=3;
1、最大公约数3
2、化为3个等价类:[0],[1],[2]
3、对每个等价类按k=3右移交换;
下面是delphi下测试通过的程序(没时间改c语言,请见谅),使用了一个按钮和3个edit(皆为默认命名),本程序未判断n,k的合法性,请注意
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;
type
Arr=array of integer;
TForm1 = class(TForm)
Button1: TButton;
Edit1: TEdit;
Edit2: TEdit;
Edit3: TEdit;
procedure Button1Click(Sender: TObject);
function gcd(num1,num2:integer):integer;
procedure moveRight(i,n,k:integer;var A:Arr);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
procedure TForm1.Button1Click(Sender: TObject);
var
n,k,i:integer;
A:Arr;
begin
n:=6;k:=7;
SetLength(A,n+1);
randomize;
for i:=1 to n do
begin
A[i]:= random(100);
Edit2.Text:=Edit2.text+inttostr(A[i])+' ';
end;
Edit1.Text:=inttostr(gcd(n,k));
for i:=1 to gcd(n,k) do
begin
moveRight(i,n,k,A)
end;
for i:=1 to n do
begin
Edit3.Text:=Edit3.text+inttostr(A[i])+' ';
end;
end;
//循环右移k位
procedure TForm1.moveRight(i, n, k: integer;var A:Arr);
var
j,temp:integer;
begin
j:=i+n-k;
temp:=A[j];
while(j<>i)do
begin
if j-k<=0 then
begin
A[j]:=A[j-k+n];
j:=j-k+n;
end
else begin
A[j]:=A[j-k];
j:=j-k;
end;
end;
A[i]:=temp;
end;
//求最大公约数
function TForm1.gcd(num1,num2:integer):integer;
var
temp:integer;
begin
if(num1>num2) then
begin
temp:=num1;
num1:=num2;
num2:=temp;
end;
temp:=num1 mod num2;
while(temp>0) do
begin
num1:= num2;
num2:= temp;
temp:= num1 mod num2;
end;
gcd:=num2;
end;
end.
我来回复