几种常见的排序方法
(1)直接插入排序
顺序的把待排序的数据元素按其关键字的大小插入到已排序数据元素子集合的适当位置。当子集合的大小最终和集合大小相同时,排序完毕。(越接近有序时,直接插入排序的算法的时间效率越好。)
(2)希尔排序
把待排序的数据元素分成若干个小组,对同一小组内的数据元素用直接插入法排序;小组的个数逐渐减少;当完成了所有数据元素都在一个小组内的排序后,排序过程结束。希尔排序又称作缩小增量排序。
(3)冒泡排序
冒泡排序就是把小的元素往前调或者把大的元素往后调。比较是相邻的两个元素比较,交换也发生在这两个元素之间。所以,如果两个元素相等,我想你是不会再无聊地把他们俩交换一下的;如果两个相等的元素没有相邻,那么即使通过前面的两两交换把两个相邻起来,这时候也不会交换,所以相同元素的前后顺序并没有改变,所以冒泡排序是一种稳定排序算法。
(4)直接选择排序
从待排序的数据元素中选取关键字最小的数据元素并将它与与原始数据元素集合中的第一个数据元素交换位置;然后从不包括第一个位置上数据元素的集合中选取关键字最小的数据元素,并将它与原始数据元素集合中不包含第二个数据元素交换位置;如此重复,直到数据元素中只剩下一个数据元素为止。
(5)快速排序
设数组a中存放了n个数据元素,low为数组的低端下标,high为数组的高端下标,从数组a中任取一个元素(通常取a[low]作为标准),调整数组a中各个元素的位置,使排在标准元素前前面的关键字均小于标准元素的关键字,排在标准元素后面的关键字均大于或等于标准元素的关键字。
(6)堆排序
在直接选择排序中,待排序的数据元素集合构成一个线性结构,要从有n个数据元素的线性结构中选择出一个最小的数据元素需要比较n-1次。如果能把待排序的数据结构元素集合构成一个完全二叉树结构,则每次选择出一个最大(或最小)的数据元素只需要比较完全二叉树的深度次。首先把n个元素的数组a初始化创建为最大堆,然后循环执行如下过程直到数组为空为止:(1)把堆顶a[0]元素(为最大元素)和当前最大堆的最后一个元素交换;(2)最大堆元素个数减1;(3)由于第(1)步后不再满足最大堆的定义,所以调整根节点使之满足最大堆的定义。
(7)归并排序
设数组a中存放了n个数据元素,初始是把它们看成是n个长度为1的有序子数组,然后从第一个有序子数组开始,把相邻的有序子数组两两合并,得到n/2(
向上取整)个长度为2的新的有序子数组(当n为奇数时,最后一个新的有序子数组的长度为1),对这些新的有序子数组进行两两归并。如此重复,直到得到一个长度为n的有序数组为止。
(8)基数排序
基数排序也称桶排序,是一种当关键字为
整数类型时非常高效的排序方法,设待排序的数据元素关键字是m位d进制数(不足m位的关键字在高位补0),设置d个桶,令其编号为0,1,2……d-1,按照关键字
最低位的数值依次把各数据元素放到相应的桶中,然后按照从小到大收集,再次是
次低位,……一直到
最高位。
代码如下所示:其中分为order.h(排序函数声明),order.cpp(排序函数定义),LQueue.h(队列相关函数声明),LQueue.cpp(队列相关函数定义)以及main.cpp。
.......................................................................order.h........................................................
typedef int KeyType ;
typedef struct
{
KeyType key;
}DataType;
//冒泡排序
void BubbleSort(DataType a[],int n);
//直接插入排序
void InsertSort(DataType a[],int n);
//希尔排序
void ShellSort(DataType a[],int n,int d[],int numOfD);
//直接选择排序
void SelectSort(DataType a[],int n);
//快速排序
void QuickSort(DataType a[],int low,int high);
//归并排序
//基数排序
void RadixSort(DataType a[],int n,int m,int d);
//堆排序
void CreatHeap(DataType a[],int n,int h);
void InitCreatHeap(DataType a[],int n);
void HeapSort(DataType a[],int n);
//归并排序
void Merge(DataType a[],int n,DataType swap[],int k);
void MergeSort(DataType a[],int n);
....................................................................
...order.cpp
.......................................................
#include <stdlib.h>
#include <stdio.h>
#include "LQueue.h"
//冒泡排序
void BubbleSort(DataType a[],int n)
{
int i,j,flag=1;
DataType temp;
for(i=1;i<n&&flag==1;i++)
{
flag=0;
for(j=0;j<n-i;j++)
{
if(a[j].key>a[j+1].key)
{
flag=1;
temp=a[j];
a[j]=a[j+1];
a[j+1]=temp;
}
}
}
}
//直接插入排序
void InsertSort(DataType a[],int n)
{
int i,j;
DataType temp;
for(i=0;i<n-1;i++)
{
temp=a[i+1];
j=i;
while(j>-1&&temp.key<a[j].key)
{
a[j+1]=a[j];
j--;
}
a[j+1]=temp;
}
}
//希尔排序
void ShellSort(DataType a[],int n,int d[],int numOfD)
{
int i,j,k,m,span;
DataType temp;
for(m=0;m<numOfD;m++)
{
span=d[m];
for(k=0;k<span;k++)
{
for(i=k;i<n-span;i=i+span)
{
temp=a[i+span];
j=i;
while(j>-1&&temp.key<=a[j].key)
{
a[j+span]=a[j];
j=j-span;
}
a[j+span] = temp;
}
}
}
}
//直接选择排序
void SelectSort(DataType a[],int n)
{
int i,j,small;
DataType temp;
for(i=0;i<n-1;i++)
{
small=i;
for(j=i+1;j<n;j++)
if(a[j].key<a[small].key)
{ small=j;
}
if(small!=i)
{
temp=a[i];
a[i]=a[small];
a[small]=temp;
}
}
}
//快速排序
void QuickSort(DataType a[],int low,int high)
{
int i=low,j=high;
DataType temp=a[low];
while(i<j)
{
while(i<j&&temp.key<=a[j].key)j--;
if(i<j)
{
a[i]=a[j];
i++;
}
while(i<j&&a[i].key<temp.key)i++;
if(i<j)
{
a[j]=a[i];
j--;
}
}
a[i]=temp;
if(low<i)QuickSort(a,low,i-1);
if(i<high)QuickSort(a,j+1,high);
}
//基数排序(桶排序)
void RadixSort(DataType a[],int n,int m,int d){
int i,j,k,power=1;
LQueue *tub;
//把d个队列定义为动态数组
tub=(LQueue *)malloc(sizeof(LQueue)*d);
for(i=0;i<d;i++)
QueueInitiate(&tub[i]);//d个队列分别初始化
//进行m次放和收
for(i=0;i<m;i++)
{
if(i==0)power=1;
else power=power *d;
//将数据元素按关键字第k位的数值放到相应的队列中
for(j=0;j<n;j++)
{
k=a[j].key/power-(a[j].key/(power*d))*d;//计算k
QueueAppend(&tub[k],a[j]);//把a[j]放到第k个队列中
}
//顺序回收各个队列中的元素数据到数组a中
k=0;
for(j=0;j<d;j++)
while(QueueNotEmpty(tub[j])!=0)
{
QueueDelete(&tub[j],&a[k]);//从个队列中回收
k++;
}
}
}
//归并排序
void Merge(DataType a[],int n,DataType swap[],int k)
{
//k为有序子数组的长度,一次二路归并排序后的有序子序列存于数组swap中
int m=0,u1,l2,i,j,u2;
int l1=0;//第一个有序子数组下界为0
while(l1+k<=n-1)
{
l2=l1+k; //计算第二个有序子数组下界
u1=l2-1; //计算第一个有序子数组上界
u2=(l2+k-1<=n-1)?l2+k-1:n-1;//计算第二个有序子数组上界
//两个有序子数组合并
for(i=l1,j=l2;i<=u1&&j<=u2;m++)
{
if(a[i].key<=a[j].key)
{
swap[m]=a[i];
i++;
}
else
{
swap[m]=a[j];
j++;
}
}
//子数组2已归并完毕,将子数组1中剩余的元素存放到数组swap中
while(i<=u1)
{
swap[m]=a[i];
m++;
i++;
}
//子数组1已归并完毕,将子数组2中剩余的元素存放到数组swap中
while (j<=u2)
{
swap[m]=a[j];
m++;
j++;
}
l1=u2+1;
}
//将原始数组中只够一组的数据元素顺序存放到数组swap中
for(i=l1;i<n;i++,m++)swap[m]=a[i];
}
void MergeSort(DataType a[],int n)
{
void Merge(DataType a[],int n,DataType swap[],int k);
int i,k=1;
DataType *swap;
swap=(DataType *)malloc(sizeof(DataType)*n);//申请动态数组空间
while (k<n)
{
Merge(a,n,swap,k); //调用归并函数
for(i=0;i<n;i++)
a[i]=swap[i]; //将元素从临时数组swap放回数组a中
k=2*k;
}
free(swap);
}
//堆排序
void CreatHeap(DataType a[],int n,int h)
{
int i,j,flag;
DataType temp;
i=h;
j=2*i+1;
temp=a[i];
flag=0;
//沿左右孩子中值较大者重复向下筛选
while(j<n&&flag!=1)
{
if(j<n-1&&a[j].key<a[j+1].key) j++;
if(temp.key>a[j].key)
flag=1;
else
{
a[i]=a[j];
i=j;
j=2*i+1;
}
}
a[i]=temp;
}
void InitCreatHeap(DataType a[],int n)
{
void CreatHeap(DataType a[],int n,int h);
int i;
for(i=(n-2)/2;i>=0;i--)
CreatHeap(a,n,i);
}
void HeapSort(DataType a[],int n)
{
void InitCreatHeap(DataType a[],int n);
void CreatHeap(DataType a[],int n,int h);
int i;
DataType temp;
InitCreatHeap(a,n);
for(i=n-1;i>0;i--)
{
temp=a[0];
a[0]=a[i];
a[i]=temp;
CreatHeap(a,i,0);
}
}
#include "order.h"
typedef struct qnode
{
DataType data;
struct qnode *next;
}LQNode;
typedef struct
{
LQNode *front;
LQNode *rear;
}LQueue;
void QueueInitiate(LQueue *Q);//初始化
int QueueNotEmpty(LQueue Q);//非空否
void QueueAppend(LQueue *Q,DataType x);//入队列
int QueueDelete(LQueue *Q,DataType *x);//出队列
int QueueGet(LQueue *Q,DataType *x);//取队头数据元素
void Destroy(LQueue Q);//撤销动态申请空间
.......................................................................LQueue.cpp.......................................................
#include <stdlib.h>
#include <stdio.h>
#include <malloc.h>
#include "LQueue.h"
void QueueInitiate(LQueue *Q)//初始化
{
Q->front=NULL;
Q->rear=NULL;
}
int QueueNotEmpty(LQueue Q)//非空否
{
if(Q.front==NULL)return 0;
else return 1;
}
void QueueAppend(LQueue *Q,DataType x)//入队列
{
LQNode *p;
p=(LQNode *)malloc(sizeof(LQNode));
p->data=x;
p->next=NULL;
if(Q->rear!=NULL)Q->rear->next=p;
Q->rear=p;
if(Q->front==NULL)
Q->front=p;
}
int QueueDelete(LQueue *Q,DataType *x)//出队列
{
LQNode *p;
if(Q->front==NULL)
{
printf("队列已空无数据元素出队列!\n");
return 0;
}
else
{
*x=Q->front->data;
p=Q->front;
Q->front =Q->front->next;
if(Q->front==NULL)Q->rear=NULL;
free(p);
return 1;
}
}
int QueueGet(LQueue *Q,DataType *x)//取队头数据元素
{
if(Q->front==NULL)
{
printf("队列已空无数据元素出队列!\n");
return 0;
}
else
{
*x=Q->front->data;
return 1;
}
}
void Destroy(LQueue Q)//撤销动态申请空间
{
LQNode *p,*p1;
p=Q.front;
while(p!=NULL)
{
p1=p;
p=p->next;
free(p1);
}
}
.......................................................................main.cpp.......................................................
#include <stdlib.h>
#include <stdio.h>
#include <malloc.h>
#include "order.h"
int main( void )
{
int i,j,m,n=6,size=6,k,s;
size=size/2;
int D[3];
for(m=0;size>=1;m++)
{
D[m] = size;
size = size/2;
}
DataType InsertSortTest[6]={64,5,7,189,6,24};
DataType ShellSortTest[6]={64,5,7,189,6,24};
DataType BubbleSortTest[6]={64,5,7,189,6,24};
DataType SelectSortTest[6]={64,5,7,189,6,24};
DataType QuickSortTest[6]={64,5,7,189,6,24};
DataType HeapSortTest[6]={64,5,7,189,6,24};
DataType RadixSortTest[6]={64,5,7,189,6,24};
DataType MergeSortTest[6]={64,5,7,189,6,24};
DataType HeapSortSortTest[6]={64,5,7,189,6,24};
InsertSort(InsertSortTest,n);//直接插入法
ShellSort(ShellSortTest,n,D,m);//希尔排序
BubbleSort(BubbleSortTest,n);//冒泡排序
SelectSort(SelectSortTest,n);//直接选择排序
QuickSort(QuickSortTest,0,5);//快速排序
RadixSort(RadixSortTest,6,3,10);//基数排序
HeapSort(HeapSortTest,n);//堆排序
MergeSort(MergeSortTest,n);//归并排序
printf("直接插入法:\n");
for(i=0;i<n;i++){
printf("%d ",InsertSortTest[i].key);
}
printf("\n");
printf("希尔排序:\n");
for(i=0;i<n;i++){
printf("%d ",ShellSortTest[i].key);
}
printf("\n");
printf("冒泡排序:\n");
for(i=0;i<n;i++){
printf("%d ",BubbleSortTest[i].key);
}
printf("\n");
printf("直接选择排序:\n");
for(i=0;i<n;i++){
printf("%d ",SelectSortTest[i].key);
}
printf("\n");
printf("快速排序:\n");
for(i=0;i<n;i++){
printf("%d ",QuickSortTest[i].key);
}
printf("\n");
printf("基数排序:\n");
for(i=0;i<n;i++){
printf("%d ",RadixSortTest[i].key);
}
printf("\n");
printf("堆排序:\n");
for(i=0;i<n;i++){
printf("%d ",HeapSortTest[i].key);
}
printf("\n");
printf("归并排序:\n");
for(i=0;i<n;i++){
printf("%d ",MergeSortTest[i].key);
}
printf("\n");
system("pause");
}