回 帖 发 新 帖 刷新版面

主题:有意者请踩踩,留下足迹!!

由于初学数据结构,对写算法来说还不是很行,所以请大家给出你们所想到的答案或者留点意见,谢谢!!
题目:
    试设计一个算法,将数组An中的元素A[0]至A[n-1]循环右移k位,并要求只用一个元素大小的附加存储,元素移动或交换次数为O(n).

回复列表 (共1个回复)

沙发

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.

我来回复

您尚未登录,请登录后再回复。点此登录或注册