虽然是个老有关问题,还是基础没有打好,各位高人不要见谅

虽然是个老问题,还是基础没有打好,各位高人不要见谅!接触delphi不久,加上基础比较差。现在终于接触到算法一

虽然是个老问题,还是基础没有打好,各位高人不要见谅!
接触delphi不久,加上基础比较差。现在终于接触到算法一类的东西了。简单的说就是实现N各自然数的从小到大排序,数据库量在10000以内。求最快的排序方法。

[解决办法]
快速排序吧,参看TStringList.Sort的实现,或者自己看算法书
[解决办法]
10000以内,快速排序还是很快的。
如果数据量大,可以考虑哈希排序。

[解决办法]
一般是快速排序,平均O(nlogn),最坏O(n^2)
更快的是堆排序吧,O(nlogn)的
希尔排序好像平均更快一些
基数排序和桶排序好像最快,但是空间就要求比较大

[解决办法]
能不能贴些代码出来看看啊。。
[解决办法]
找一个《Delphi算法与数据结构》电子版那里面有详细的介绍
[解决办法]

探讨
本来数据都是放在数据库中的,然后对这个字段直接用SQL语句排序就好了,但是有时候也会有误差。

[解决办法]
给你一篇文章:

基本思路:通过一次分割,将无序序列分成两部分,其中一部分的元素值均不大于后一部分的元素值。然后用同样的方法对每一部分进行分割,一直到每一个子序列的长度小于或等于1为止。

 

具体过程:设序列P进行分割。首先,从第一个、中间一个、最后一个元素中选出中项,设为P[k],并将P[k]赋给t,再将序列中的第一个元素移到P[k]的位置上。然后,再设两个指针i、j分别指向起始和最后位置上:(1)将i逐渐增大,与此同时比较P[i]与t的大小,直到发现P[i]>t,将P[i]移到P[j]的位置上;(2)将j逐渐减小,与此同时比较P[j]与t的大小,直到发现P[j]<t,将P[j]移到P[i]的位置上;直到i=j为止,这时将t移到P[i]的位置上。最后就得到了排序结果。

 

C函数如下:

 

void prqck(p,n) 

int n;double p[]; 

{ 

 int m,i0,*i; 

 double *s; 

 void rsplit(); 

 i=&i0; 

 if(n>1) 

{ 

rsplit(p,n,i); 

m=i0;prqck(p,m); 

s=p+(i0+1);m=n-(i0+1);prqck(s,m); 

} 

 return; 

} 

static void rsplit(p,n,m) 

int n,*m;double[]; 

{ 

 int i,j,k,l; 

 double t; 

 i=0;j=n-1;k=(i+j)/2; 

 if((p[i]>=p[j])&&(p[j]>=p[k])) l=j; 

else if((p[i]>=p[k])&&(p[k]>=p[j])) l=k; 

 else l=i; 

 t=p[l];p[l]=p[i]; 

 while(i!=j) 

{ 

while((i<j)&&(p[j]>=t)) j=j-1; 

if(i<j) 

{ 

p[i]=p[j];i=i+1; 

while((i<j)&&(p[j]<=t)) i=i-1; 

if(i<j) 

{p[j]=p[i];j=j-1;} 

} 

} 

 p[i]=t;*m=i; 

 return; 

} 

 

************************

般来说,冒泡法是程序员最先接触的排序方法,它的优点是原理简单,编程实现容易,但它的缺点就是--程序的大忌--速度太慢。下面我介绍一个理解上简单但编程实现上不是太容易的排序方法,我不知道它是不是现有排序方法中最快的,但它是我见过的最快的。排序同样的数组,它所需的时间只有冒泡法的4%左右。我暂时称它为“快速排序法”。

“快速排序法”使用的是递归原理,下面我结合一个例子来说明“快速排序法”的原理。首先给出一个数组{53,12,98,63,18,72,80,46,32,21},先找到第一个数--53,把它作为中间值,也就是说,要把53放在一个位置,使得它左边的值比它小,右边的值比它大。{21,12,32,46,18,53,80,72,63,98},这样一个数组的排序就变成了两个小数组的排序--53左边的数组和53右边的数组,而这两个数组继续用同样的方式继续下去,一直到顺序完全正确。

我这样讲你们是不是很胡涂,不要紧,我下面给出实现的两个函数:

void quicksort(int n[], int left,int right)//n就是需要排序的数组,left和right是你需要排序的左界和友界,如果要排序上面那个数组,那么left和right分别是0和9

{

int dp;

if (left<right) {

dp=partition(n,left,right);//这就是下面要讲到的函数,按照上面所说的,就是把所有小于53的数放到它的左边,大的放在右边,然后返回53在整理过的数组中的位置。

quicksort(n,left,dp-1);

quicksort(n,dp+1,right);//这两个就是递归调用,分别整理53左边的数组和右边的数组



}

}

 

我们上面提到先定位第一个数,然后整理这个数组,把比这个数小的放到它的左边,大的放右边,然后返回这中间值的位置,下面这函数就是做这个的。

int partition(int n[],int left,int right)

{

int lo,hi,pivot,t;

pivot=n[left];

lo=left-1;

hi=right+1;

while(lo+1!=hi) {

if(n[lo+1]<=pivot)

lo++;

else if(n[hi-1]>pivot)

hi--;

else {

t=n[lo+1];

n[++lo]=n[hi-1];

n[--hi]=t;

}

}

n[left]=n[lo];

n[lo]=pivot;

return lo;

}

这段程序并不难,应该很好看懂,我把过程大致讲一下,首先你的脑子里先浮现一个数组和三个指针,第一个指针称为p指针,在整个过程结束之前它牢牢的指向第一个数,第二个指针和第三个指针分别为lo指针和hi指针,分别指向最左边的值和最右边的值。lo指针和hi指针从两边同时向中间逼近,在逼近的过程中不停的与p指针的值比较,如果lo指针的值比p指针的值小,lo++,还小还++,再小再++,直到碰到一个大于p指针的值,这时视线转移到hi指针,如果hi指针的值比p指针的值大,hi--,还大还--,再大再--,直到碰到一个小于p指针的值。这时就把lo指针的值和hi指针的值做一个调换。持续这过程直到两个指针碰面,这时把p指针的值和碰面的值做一个调换,然后返回p指针新的位置。

我知道我怎么说你们还是不太明白,其实只要看程序就行了,有很多程序的语言是用人类的语言无法表达的。有什么问题,email我:allexit@hotmail.com。

*********************************

数据都保存在Items中

function RSplit(Left, Right: integer): integer;

var

L, H, P, T: integer;

begin

P := Items[Left];

L := Left - 1;

H := Right + 1;

while L + 1 <> H do

begin

if Items[L + 1] <= P then

Inc(L)

else if Items[H - 1] > P then

Dec(H)

else begin

T := Items[L + 1];

Inc(L);

Items[L] := Items[H - 1];

Dec(H);

Items[H] := T;

end;

end;

Items[Left] := Items[L];

Items[L] := P;

Result := L;

end;

 

procedure QuickSort(iStart, iEnd: integer);

var

Position: integer;

i, j, t: integer;

begin

if iStart < iEnd then

begin

Position := RSplit(iStart, iEnd);

QuickSort(iStart, Position - 1);

QuickSort(Position + 1, iEnd);

end;

end;

Invoke: QuickSort(0,Items.Count -1);

 

---------------------------------------

 

{ 

 The following procedure sorts an Array with the 

 fast Shell-Sort algorithm. 

 Invented by Donald Shell in 1959, 

 the shell sort is the most efficient of the O(n2) 

 class of sorting algorithms 

} 

 

{ 

 Die folgende Prozedur Sortiert ein Array mit 

 dem schnellem Shell-Sort Algorithmus. 

} 

 

Procedure Sort_Shell(var a: array of Word); 

var 

bis, i, j, k: LongInt; 

h: Word; 

begin 

bis := High(a); 

k := bis shr 1;// div 2 

while k > 0 do 

begin 

for i := 0 to bis - k do 

begin 

j := i; 

while (j >= 0) and (a[j] > a[j + k]) do 

begin 

h := a[j]; 

a[j] := a[j + k]; 

a[j + k] := h; 

if j > k then 

Dec(j, k) 

else 

j := 0; 

end; // {end while] 

end; // { end for} 

k := k shr 1; // div 2 

end; // {end while} 

 

end;
[解决办法]


楼主要求最快的排序算法,这个跟具体语言没有关系吧

找个所谓的“最快”排序算法,改写为Delphi的,或者去找个其他人写的算法的函数封装也可以.....
[解决办法]

探讨
一般是快速排序,平均O(nlogn),最坏O(n^2)
更快的是堆排序吧,O(nlogn)的
希尔排序好像平均更快一些
基数排序和桶排序好像最快,但是空间就要求比较大


[解决办法]
快速排序吧
[解决办法]
快速排序这种,VCL里都有的,TLIST里就有