通常,在排序过程中需要进行下列两种操作:(1)比较两个关键字的大小;(2)将记录从一个位置移到另一个位置。前一个操作对大多数排序方法来说都是必须的,而后一个操作可以通过改变记录的存储方式来予以避免。
待排序的记录序列可有一下三种存储方式:(1)待排序的一组记录存储在地址连续的一组存储单元上。它类似于线性表的数序存储结构,在序列中相邻的两个记录Rj和Rj+1,它们的存储位置也相邻。在这种存储方式中,记录之间的次序关系由其存储位置决定,则实现排序必须借助移动记录;(2)一组待排序记录存放在静态链表中,记录之间的次序关系有指针表示,则实现不需要移动记录,仅需修改指针即可;(3)待排序记录本身存储在一组地址连续的存储单元,同时另设一个指示各个记录存储位置的地址向量,在排序过程中不易懂记录本身,而移动地址向量中这些记录的“地址”,在排序结束后再按照地址向量中的值调整记录的存储位置。在第二种存储方式下实现的排序又称(链)表排序,在第三种排序方式下实现的排序又称为地址排序。
直接插入排序(Straight Insert Sort)是一种最简单的排序方法,它的基本操作是将一个记录插入到已排好序的有序表中,从而得到一个新的、记录数增1的有序表。
void SInsertSort(ArrayType R[], int n)
{
int i, j, temp;
for(i=1;i<n;i++) //i从第二个元素开始
{
temp = R[i]; //将待排序元素放入临时变量
j = i-1; //从第i个元素的前一个元素开始查找
while((temp<R[j]) && (j>=0))
{
R[j+1] = R[j]; //元素向后移动
j--; //向左继续查找
}
R[j+1] = temp; //将元素插入相应位置
}
}
折半插入排序(Binary Insertion Sort)是利用二元搜索的方法对每一个R[i]找其插入位置。具体实现是用两个指针:一个头指针h,初始指向第一个记录;一个尾指针t,初始指向带插入记录的前面一个位置。每次将待插记录的关键字与它前面一段的中间位置的关键字比较,确定待插记录的位置。
void BInsertSort(ArrayType R[], int n)
{
int i, j, temp, middle;
int head, tail;
for(i=1;i<n;i++)
{
temp = R[i];
head = 1; //在R[head]到R[tail]中折半查找插入位置
tail = i - 1;
while(head <= tail)
{
middle = (head + tail)/2; //折半
if(temp < R[middle])
tail = m-1; //插入点在低半区
else
head = m+1; //插入点在高半区
}
for(j = i-1;j >= tail+1;--j) //将tail之后的元素后移
R[j+1] = R[j];
R[tail + 1] = temp; //插入
}
}
选择排序:
void selectSort(int *x, int n)
{
int i, j, min, t;
for(i=0; i<n-1; i++)//要选择的次数
{
min = i;
for(j=i+1; j<n; j++)//找出最小的数的下标
{
if(*(x+j) < *(x+min))
{
min = j;
}
}
if(min != i)
{
t = *(x+i);
*(x+i) = *(x+min);
*(x+min) = t;
}
}
}
冒泡排序:
void bubbleSort(int *x, int n)
{
int j, k, h, t;
int flag=1;
for(h=n-1; h>0; h=k) //一直循环到没有比较范围
{
for(j=0,k=0; j<h; j++) //每次预设k=0,循环扫描完成后更新k
{
if(*(x+j)>*(x+j+1)) //大的沉下去,小的浮上来
{
t = *(x+j);
*(x+j) = *(x+j+1);
*(x+j+1) = t;
k = j; //保存最后下沉位置,这样k后面的都是排序完成的
flag = 0;
}
}
if(flag)
{
break; //如果一次都未交换,说明已经排好序
}
}
}
希尔排序:
void shellSort(int *x, int n)
{
int h, j, k, t;
for(h=n/2; h>0; h/=2) //控制增量
{
for(j=h; j<n; j++) //这个实际就是直接插入排序
{
t = *(x+j);
for(k=j-h; k>=0&&t<*(x+k); k-=h)
{
*(x+k+h) = *(x+k);
}
*(x+k+h) = t;
}
}
}
快速排序:
void quickSort(int *x, int low, int high)
{
int i, j, t;
if(low < high) //要排序元素的下标,以下标为low的元素为基准点
{
i = low;
j = high;
t = *(x+low); //暂存基准点的数
while(i<j)
{
while(i<j && *(x+j)>t)
//在右边的,只要比基准点大的元素仍放在右边
{
j--; //前移一个位置
}
if(i<j)
{
*(x+i) = *(x+j);
//上面的循环退出,即出现比基准点小的数,替换左边的数
i++; //后移一个位置
}
while(i<j && *(x+i)<=t)
//在基准点左边的数,只要比基准点小的元素仍放在左边
{
i++;
}
if(i<j)
{
*(x+j) = *(x+i);
j--;
}
}
*(x+i) = t;//放入适当位置
quickSort(x, low, i-1);//对基准点左边的数进行快排
quickSort(x, i+1, high);//对基准点右边的数进行快排
}
}
以上仅仅写出了大体算法,由于没有实际编译,所以不排除有细节问题,如有发现,请指正,谢谢。