求快速排序方法(100分)

  • 主题发起人 主题发起人 t_yyy
  • 开始时间 开始时间
目的是你的快速排序的实现脱离具体的结构类型 给每个结构类型写一个那不累死人
 
先按strs排好序保存以来以便以后查找啊
然后使用折半查找法,很快的噢
 
To Avalon:
type
PMyRec = ^TMyRec;
TMyRec = Record
Num:array[1..4000000] of Integer;//存放序号
Strs:array[1..4000000] of String[11];//字符串
eValue:array[1..4000000] of Extended;//计算用
end;
....
Result := StrComp(PAnsiChar(PMyRec(p_Data1)^.Strs), ////
PAnsiChar(PMyRec(p_Data2)^.Strs)); ////
报错 Invalid typecast
要先按eValue(浮点) 排序,这样行吗?不要说我笨哦 :(
 
1.按照前面所述排序后再用各种方式查找
2.将eValue值放入一个TStringList中,查找时用IndexOf定位,其位置就是该元素真正所在位置
 
好家伙 你理解反了 和数组没有关系 是基于链表LIST的

type
PMyRec = ^TMyRec;
TMyRec = Record
Num:Integer;//存放序号
Strs:String[11];//字符串
eValue: Extended;//计算用
end;
 PMyRec = ^TMyRec;

新建一个TList类型 比如为:m_NumList
每当新增一个PMyRec  就把这个结构追加到这个TList类型中去
m_NumList.add(PMyRec)

我给你的快速排序实际上是对这个TList类型指向TMyRec记性排序
定义好一个比较的方式
function f_SortNumUp(p_Data1, p_Data2: Pointer): integer; //号码升序 ////
begin ////
Result := StrComp(PAnsiChar(PMyRec(p_Data1)^.Strs), ////
PAnsiChar(PMyRec(p_Data2)^.Strs)); ////
end;

然后再调用
TDQuickSort(m_NumList, 0 , m_NumList.Count - 1, f_SortNumUp)
 
感谢Avalon,依您的方法实现了排序,下面是实现过程:
......
{$R *.dfm}
function f_SortNumUp(p_Data1, p_Data2: Pointer): integer; //号码升序 ////
begin ////
Result := StrComp(PAnsiChar(PMyRec(p_Data1)^.Strs), ////
PAnsiChar(PMyRec(p_Data2)^.Strs)); ////
end;

//降序
function ListSortMax(iP1, iP2: Pointer):Integer;
begin
if PMyRec(iP1)^.eValue > PMyRec(iP2)^.eValue then
Result := -1
else if PMyRec(iP1)^.eValue = PMyRec(iP2)^.eValue then
Result := 0
else
Result := 1;
end;


procedure TForm1.Button1Click(Sender: TObject);
var
m_NumList:TList;
PR,P:PMyRec;
k:Integer;
begin
(* 仅做测试 *)
m_NumList := TList.Create;
New(PR);
PR^.Num := 1;
PR^.Strs := '13345678912';
PR^.eValue := 1.08963;
m_NumList.Add(PR);

New(PR);
PR^.Num := 2;
PR^.Strs := '13045678912';
PR^.eValue := 9.08963;
m_NumList.Add(PR);

New(PR);
PR^.Num := 3;
PR^.Strs := '13145678912';
PR^.eValue := 6.08963;
m_NumList.Add(PR);

TDQuickSort(m_NumList, 0 , m_NumList.Count - 1, ListSortMax);
//TDQuickSort(m_NumList, 0 , m_NumList.Count - 1, f_SortNumUp);
//下面看排序结果
with m_NumList do for k := 0 to Count-1 do begin
p := Items[k];
showmessage(P^.Strs+':'+FormatFloat('0.000000',P^.eValue));
end;
m_NumList.Free;

end;
....
400w的数据速度测试ing....还有查询ing.... :)
 
按上面的办法生成400w数据时,m_NumList.Free后怎么释放不了内存??!!
如:
for k := 1 to 4000000 do begin
New(PR);
PR^.Num := 1;
PR^.Strs := '13345678912';
PR^.eValue := 1.08963;
m_NumList.Add(PR);
end;
//此时占用内存大约210M
m_NumList.Free;//只释放了大约16M,仍占用190M左右,什么原因?
 
procedure FreeList(List: TList);
var
I: Integer;
begin
for I := 0 to List.Count - 1 do
Dispose(List);
List.Free;
end;

对应节点的内存没FREE,当然这样了。

BTW:LZ将测试写全来,看看测试效率有怎么样。或者提供一个简单的测试数据出来
 
另: 400W次的New, Dispose是耗时操作,你可以改成:
var
Buffer: Pointer;

Buffer := AllocMem(SizeOf(PR^) * 4000000);
PR := Buffer;
for k := 1 to 4000000 do begin
PR^.Num := 1;
PR^.Strs := '13345678912';
PR^.eValue := 1.08963;
m_NumList.Add(PR);
Inc(PR);
end;

然后直接FreeMem(Buffer)就行了
不过PR对应的Strs没给释放,呵,如果是Int64类型就不会了。
 
感谢errorcode,我再试试....
 
按errorcode将Strs改为Int64.
P4/3.0/2G内存
400w数据处理时间:<5秒
排序:<10秒
查找(在百万序号后):<1秒
感谢大家!
 
散分了,这分好像不太够。:)
 
多人接受答案了。
 
u_QuickSort 有多种的快速排序方法 速度由慢到快最快可以提高普通快速排序的27% 
楼主有时间可以慢慢研究
 

Similar threads

S
回复
0
查看
3K
SUNSTONE的Delphi笔记
S
S
回复
0
查看
2K
SUNSTONE的Delphi笔记
S
I
回复
0
查看
481
import
I
后退
顶部