近日,学习了几种排序算法,做一梳理:
一、插入排序
插入排序的主要思想就是在放置第P个位置的值时认为前P-1个位置的值是按正确位置排序好的,
所以将P逐一与它之前位置的值比较后放置在合适的位置。主要算法:
void InsertionSort(int A[],int N)
{
int j,p;
int temp;
for(p=1;p<N;p++)
{
temp=A[p];
for(j=p;j>0&&A[j-1]>temp;j--)
{
A[j]=A[j-1];
}
A[j]=temp;
}
}
二、希尔排序
它的主要思想是通过比较相距一定间隔的元素来工作;各趟比较所用的距离随着算法的进行减少,直到只比较相邻元素的最后一趟
排序为止。主要算法:
void ShellSort(int A[],int N)
{
int j,p;
int increase;
int temp;
for(increase=N/2;increase>0;increase/=2)
{
for(p=increase;p<N;p++)
{
temp=A[p];
for(j=p;j>=increase;j-=increase)
{
if(A[j-increase]>temp)
A[j]=A[j-increase];
else
break;
}
A[j]=temp;
}
}
}
三、堆排序
它的主要思想是构建一个二叉堆,然后每次通过Delete操作得到一个最大值。主要算法:
#define LeftChild(i) (2*(i)+1)
void PercDown(int A[],int i,int N)
{
int child;
int temp;
for(temp=A[i];LeftChild(i)<N;i=child)
{
child=LeftChild(i);
if(child!=N-1&&A[child+1]>A[child])
child++;
if(temp<A[child])
A[i]=A[child];
else
break;
}
A[i]=temp;
}
void Swap(int *a,int *b)
{
int t=*a;
*a=*b;
*b=t;
}
void HeapSort(int A[],int N)
{
int i;
for(i=N/2;i>=0;i--)
PercDown(A,i,N);
for(i=N-1;i>=0;i--)
{
Swap(&A[0],&A[i]);
PercDown(A,0,i);
}
}
四、归并排序
它的主要思想是合并两个已排序的表。主要算法:
/*Lpos=start of the left half,Rpos=start of right half */
void Merge(int A[],int TmpArray[],int Lpos,int Rpos,int RightEnd)
{
int i,LeftEnd,numElements,TmpPos;
LeftEnd=Rpos-1;
TmpPos=Lpos;
numElements=RightEnd-Lpos+1;
while(Lpos<=LeftEnd&&Rpos<=RightEnd)
{
if(A[Lpos]<=A[Rpos])
TmpArray[TmpPos++]=A[Lpos++];
else
TmpArray[TmpPos++]=A[Rpos++];
}
while(Lpos<=LeftEnd) /*Copy rest of first half */
TmpArray[TmpPos++]=A[Lpos++];
while(Rpos<=RightEnd) /*Copy rest of second half */
TmpArray[TmpPos++]=A[Rpos++];
for(i=0;i<numElements;i++,RightEnd--)
A[RightEnd]=TmpArray[RightEnd]; //Not always definite from zero
}
void MSort(int A[],int TmpArray[],int Left,int Right)
{
int Center;
if(Left<Right)
{
Center=(Left+Right)/2;
MSort(A,TmpArray,Left,Center);
MSort(A,TmpArray,Center+1,Right);
Merge(A,TmpArray,Left,Center+1,Right);
}
}
void MergeSort(int A[],int N)
{
int *TmpArray;
TmpArray=malloc(N*sizeof(int));
if(TmpArray!=NULL)
{
MSort(A,TmpArray,0,N-1);
free(TmpArray);
}
else
exit(EXIT_FAILURE);
}
五、快速排序
它的主要思想是:
1、如果S中元素个数是0或1,则返回。
2、取S中任一元素v,称为pivot.
3、将S分为两个不相交的集合:S1和S2
4、返回{quicksort(S1)后,继随v,继而quicksort(S2)}
主要算法:
#define Cutoff(3)
int Median3(int A[],int Left,int Right)
{
int Center=(Left+Right)/2;
if(A[Left]>A[Center])
Swap(&A[Left],&A[Center]);
if(A[Left]>A[Right])
Swap(&A[Left],&A[Right]);
if(A[Center]>A[Right])
Swap(&A[Center],&A[Right]);
Swap(&A[Center],&A[Right-1]);
return A[Right-1];
}
void Qsort(int A[],int Left,int Right)
{
int i,j;
int pivot;
if(Left+Cutoff<=Right)
{
pivot=Median3(A,Left,Right);
i=Left;j=Right-1;
for(;;)
{
while(A[++i]<pivot){}
while(A[--j]>pivot){}
if(i<j)
Swap(&A[i],&A[j]);
else
break;
}
Swap(&A[i],&A[Right-1]);
Qsort(A,Left,i-1);
Qsort(A,i+1,Right);
}
else
InsertionSort(A+Left,Right-Left+1);
}
void QuickSort(int A[],int N)
{
Qsort(A,0,N-1);
}