例:全国所有城市,如果做飞机从A点到B点,需要多次换乘。
已知如:上海可以到 北京广州深圳香港
        北京可以到 哈尔滨内蒙古
        内蒙古可以到 新疆西藏甘肃
        。省略更多然后我要求上海到新疆的路线应该怎么走:结果肯定是 上海-北京-内蒙古-新疆。那么根据已知数据得到结果这样的函数怎么写呢???

解决方案 »

  1.   

    不用数据库形式,比如用INI存储
    [上海]
    到达=北京,广州,深圳
    [北京]
    到达=哈尔滨,内蒙古这样
      

  2.   

    不是一个函数能解决的问题,应该是根据你的INI要建立一种数据结构,然后实现一个遍历算法,解决了你可以去DDMAP应聘咯,题目挺有意思,顶。坐等高手具体解决
      

  3.   

    http://zhidao.baidu.com/question/39460604.html?fr=ala0
    请参照上面的链接。
      

  4.   

    我用文本文件来作数据源,我觉得比ini文件还好些,每一行的第一个地点表示起点,后面的表示目的地
    我的test.txt文件如下:
    上海,北京,广州,深圳,香港
    北京,哈尔滨,内蒙古
    内蒙古,新疆,西藏,甘肃
    广州,长沙
    长沙,成都
    成都,武汉
    武汉,新疆
    深圳,哈尔滨
    哈尔滨,新疆程序代码如下:
    unit Unit1;interfaceuses
      Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
      Dialogs, StdCtrls;type
      TForm1 = class(TForm)
        Button1: TButton;
        edQD: TEdit;//起点
        edZD: TEdit;//终点
        M1: TMemo;//结果
        procedure FormCreate(Sender: TObject);
        procedure FormDestroy(Sender: TObject);
        procedure Button1Click(Sender: TObject);
      private
        FList:TStringList;    procedure AddNode(const ANode,APNode:string);
        function Search(const AZD,AQD:string):string;
        procedure DelList;
      public
        { Public declarations }
      end;var
      Form1: TForm1;implementation{$R *.dfm}type
      PDataNode=^TDataNode;
      TDataNode=record
        Node:string;
        PNode:string;
    end;procedure TForm1.FormCreate(Sender: TObject);
    begin
      FList:=TStringList.Create;
      FList.Sorted:=True;
    end;procedure TForm1.FormDestroy(Sender: TObject);
    begin
      DelList;
      FList.Free;
    end;procedure TForm1.Button1Click(Sender: TObject);
    var
      i,j:Integer;
      sList,sTmpList:TStringList;
    begin
      if not FileExists('.\test.txt') then exit;  DelList;  sList:=TStringList.Create;
      try
        sList.LoadFromFile('.\test.txt');
        if sList.Count<=0 then exit;    sTmpList:=TStringList.Create;
        try
          for i:=0 to sList.Count-1 do
          begin
            sTmpList.Delimiter:=',';
            sTmpList.DelimitedText:=sList[i];        for j:=0 to sTmpList.Count-1 do
              AddNode(sTmpList[j],sTmpList[0]);
          end;
        finally
          sTmpList.Free;
        end;
      finally
        sList.Free;
      end;  if FList.IndexOf(edZD.Text)=-1 then exit;
      if FList.IndexOf(edQD.Text)=-1 then exit;  M1.Clear;
      Search(edZD.Text,edQD.text);
    end;procedure TForm1.AddNode(const ANode, APNode: string);
    var
      index:Integer;
      DataNode:PDataNode;
    begin
      index:=FList.IndexOf(ANode);
      if index=-1 then
      begin
        New(DataNode);
        DataNode^.Node:=ANode;
        if APNode<>ANode then
        DataNode^.PNode:=APNode;
        FList.AddObject(ANode,TObject(DataNode));
      end
      else begin
        if APNode=ANode then exit;
        DataNode:=PDataNode(FList.Objects[index]);
        DataNode^.PNode:=DataNode^.PNode+','+APNode;
      end;
    end;function TForm1.Search(const AZD,AQD: string): string;
    var
      sPNode,s:string;
      index:Integer;
      sList:TStringList;  procedure _Search(const AZD,AQD:string;var ARs:string);
      var
        _sPNode:string;
        _index:Integer;
        _sList:TStringList;
      begin
        _index:=FList.IndexOf(AZD);
        _sPNode:=PDataNode(FList.Objects[_index])^.PNode;
        _sList:=TStringList.Create;
        try
          _sList.Delimiter:=',';
          _sList.DelimitedText:=_sPNode;
          for _index:=0 to _sList.Count-1 do
          begin
            if _sList[_index]=AQD then
              exit
            else begin
              if Pos(AZD,ARs)=0 then ARs:=AZD+','+ARs;
              ARs:=_sList[_index]+','+ARs;
              _Search(_sList[_index],AQD,ARs);
            end;
          end;
        finally
          _sList.Free;
        end;
      end;begin
      index:=FList.IndexOf(AZD);
      sPNode:=PDataNode(FList.Objects[index])^.PNode;
      sList:=TStringList.Create;
      try
        sList.Delimiter:=',';
        sList.DelimitedText:=sPNode;
        for index:=0 to sList.Count-1 do
        begin
          if sList[index]=AQD then
            exit
          else begin
            s:='';
            _Search(sList[index],AQD,s);
            if s<>'' then s:=AQD+','+s+AZD;
            if M1.Lines.IndexOf(s)=-1 then
            M1.Lines.Add(s);
          end;
        end;
      finally
        sList.Free;
      end;
    end;procedure TForm1.DelList;
    var
      p:Pointer;
    begin
      while FList.Count>0 do
      begin
        p:=FList.Objects[0];
        if Assigned(p) then Dispose(p);
        FList.Delete(0);
      end;
    end;end.
      

  5.   

    楼上的代码输出不报错,但是MEMO里没有内容,如上海-内蒙古 MEMO的LINE会加一行空行
      

  6.   

    这个题目不是树的遍历,而是求从树头到每一个叶子结点的所有路径,如果中间某个子结点出现分支的话,可以说是非常复杂.树可以创建出来,但是那个路径就很难求出来,如果中间某个子结点不出现分支的话,就可以求出来。下面是代码:
    unit Unit1;interfaceuses
      Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
      Dialogs, StdCtrls;type
      TForm1 = class(TForm)
        edQD: TEdit;//起点
        edZD: TEdit;//终点
        M1: TMemo;
        Button1: TButton;//结果
        procedure FormCreate(Sender: TObject);
        procedure FormDestroy(Sender: TObject);
        procedure Button1Click(Sender: TObject);
      private
        FList:TStringList;    procedure AddNode(const ANode,APNode:string);
        procedure DelList;    procedure CreateDataNode;
      public
        { Public declarations }
      end;type
      PMyTreeNode=^TMyTreeNode;
      TMyTreeNode=record
        data:string;
        count:integer;
        firstChild:PMyTreeNode;
        nextSibling:PMyTreeNode;
    end;var
      Form1: TForm1;implementation{$R *.dfm}type
      PDataNode=^TDataNode;
      TDataNode=record
        Node:string;
        PNode:string;
    end;var
      gRoot:PMyTreeNode;
      gRs:string;function CreateNode(const AData:string):PMyTreeNode;
    begin
      New(result);
      result.data:=AData;
      result.count:=0;
      result.firstChild:=nil;
      result.nextSibling:=nil;
    end;function FindNextNode(ANode:PMyTreeNode):PMyTreeNode;
    begin
      while ANode.nextSibling<>nil do
        ANode:=ANode.nextSibling;  result:=ANode;
    end;procedure VisitNode(ANode:PMyTreeNode;AShow:Boolean=false);
    begin
      if ANode=nil then exit
      else begin
        if (ANode.count>1) and (not AShow) then
        begin
          showmessage('子结点出现分支.');
          exit;
        end;    if ANode.data=form1.edQD.Text then gRs:=gRs+','+form1.edQD.Text+#13#10
        else gRs:=gRs+','+ANode.data;    if AShow then
          showmessage(ANode.data);
        VisitNode(ANode.firstChild,AShow);
        VisitNode(ANode.nextSibling,AShow);
      end;
    end;function FindNode(const AData:string;ANode:PMyTreeNode):PMyTreeNode;
    var
      iRet:Integer;  function _FindNode(const AData:string;ANode:PMyTreeNode;var vRet:Integer):PMyTreeNode;
      begin
        vRet:=0;
        result:=nil;
        if ANode=nil then exit
        else begin
          if ANode.data=AData then
          begin
            result:=ANode;
            vRet:=1;
            exit;
          end;      result:=_FindNode(AData,ANode.firstChild,vRet);
          if vRet=0 then
            result:=_FindNode(AData,ANode.nextSibling,vRet);
        end;
      end;begin
      iRet:=0;
      result:=_FindNode(AData,ANode,iRet);
    end;function AddChildNode(APNode:PMyTreeNode;const AData:string):PMyTreeNode;
    begin
      result:=CreateNode(AData);  if APNode.firstChild=nil then
        APNode.firstChild:=result
      else if APNode.firstChild.nextSibling=nil then
        APNode.firstChild.nextSibling:=result
      else begin
        APNode:=FindNextNode(APNode.firstChild);
        if APNode<>nil then
          APNode.nextSibling:=result;
      end;
    end;procedure TForm1.FormCreate(Sender: TObject);
    begin
      FList:=TStringList.Create;
      FList.Sorted:=True;
      CreateDataNode;
    end;procedure TForm1.FormDestroy(Sender: TObject);
    begin
      DelList;
      FList.Free;
    end;procedure TForm1.AddNode(const ANode, APNode: string);
    var
      index:Integer;
      DataNode:PDataNode;
    begin
      index:=FList.IndexOf(ANode);
      if index=-1 then
      begin
        New(DataNode);
        DataNode^.Node:=ANode;
        if APNode<>ANode then
        DataNode^.PNode:=APNode;
        FList.AddObject(ANode,TObject(DataNode));
      end
      else begin
        if APNode=ANode then exit;
        DataNode:=PDataNode(FList.Objects[index]);
        DataNode^.PNode:=DataNode^.PNode+','+APNode;
      end;
    end;procedure TForm1.DelList;
    var
      p:Pointer;
    begin
      while FList.Count>0 do
      begin
        p:=FList.Objects[0];
        if Assigned(p) then Dispose(p);
        FList.Delete(0);
      end;
    end;procedure TForm1.CreateDataNode;
    var
      i,j:Integer;
      sList,sTmpList:TStringList;
    begin
      if not FileExists('.\test.txt') then exit;  DelList;  sList:=TStringList.Create;
      try
        sList.LoadFromFile('.\test.txt');
        if sList.Count<=0 then exit;    sTmpList:=TStringList.Create;
        try
          for i:=0 to sList.Count-1 do
          begin
            sTmpList.Delimiter:=',';
            sTmpList.DelimitedText:=sList[i];        for j:=0 to sTmpList.Count-1 do
              AddNode(sTmpList[j],sTmpList[0]);
          end;
        finally
          sTmpList.Free;
        end;
      finally
        sList.Free;
      end;
    end;procedure TForm1.Button1Click(Sender: TObject);
    var
      i:integer;
      sList:TStringList;
      
      procedure _AddTreeNode(const AQD:string;var APNode:PMyTreeNode);
      var
        _sPNode:string;
        _index:Integer;
        _sList:TStringList;
        NewNode:PMyTreeNode;
      begin
        if AQD=edQD.Text then exit;    _index:=FList.IndexOf(AQD);
        _sPNode:=PDataNode(FList.Objects[_index])^.PNode;
        _sList:=TStringList.Create;
        try
          _sList.Delimiter:=',';
          _sList.DelimitedText:=_sPNode;
          APNode.count:=_sList.Count;
          for _index:=_sList.Count-1 downto 0 do
          begin
            NewNode:=AddChildNode(APNode,_sList[_index]);
            _AddTreeNode(_sList[_index],NewNode);
          end;
        finally
          _sList.Free;
        end;
      end;  function ReverseString(const AText: string): string;
      var
        j:Integer;
      begin
        sList.Delimiter:=',';
        sList.DelimitedText:=AText;
        result:='';
        for j:=sList.Count-1 downto 0 do
          result:=result+sList[j]+' ';
      end;
    begin
      if FList.IndexOf(edZD.Text)=-1 then exit;
      if FList.IndexOf(edQD.Text)=-1 then exit;  gRoot:=CreateNode(edZD.Text);
      _AddTreeNode(edZD.Text,gRoot);  gRs:='';
      VisitNode(gRoot.firstChild,true);
      M1.Text:=gRs;
      sList:=TStringList.Create;
      try
        for i:=0 to M1.Lines.Count-1 do
          M1.Lines[i]:=ReverseString(trim(edZD.Text+M1.Lines[i]));
      finally
        sList.Free;
      end;
    end;end.测试数据1,子结点不出现分支:
    上海,北京,广州,深圳,香港
    北京,哈尔滨,内蒙古
    内蒙古,新疆,西藏,甘肃树的构成是:
                   新疆
                    |
                  内蒙古
                    |
                  北京
                    |
                  上海   测试数据2, 子结点出现分支:
    上海,北京,广州,深圳,香港
    北京,哈尔滨,内蒙古
    内蒙古,新疆,西藏,甘肃
    广州,长沙
    长沙,新疆
    深圳,哈尔滨
    哈尔滨,新疆树的构成:
                   新      疆
         /     |    \
             哈尔滨   长沙  内蒙古 
               /  \     |      \
            深圳  北京 广州   北京  
             /      \   |       \
          上海     上海 上海     上海 
                                                  
    这个时候遍历树没问题,但是求不出所有路径,求出来的路径有问题.