几种常用排序算法总结

更新时间:2023-10-29 18:34:01 阅读量: 综合文库 文档下载

说明:文章内容仅供预览,部分内容可能不全。下载后的文档,内容与下面显示的完全一致。下载之前请确认下面内容是否您想要的,是否完整无缺。

排 序

一.插入排序

插入排序的基本思想是每步将一个待排序的记录按其排序码值的大小,插到前面已经排好的文件中的适当位置,直到全部插入完为止。插入排序方法主要有直接插入排序和希尔排序。

①.直接插入排序(稳定)

接插入排序的过程为:在插入第i个记录时,R1,R2,..Ri-1已经排好序,将第i个记录的排序码Ki依次和R1,R2,..,Ri-1的排序码逐个进行比较,找到适当的位置。使用直接插入排序,对于具有n个记录的文件,要进行n-1趟排序。 代码如下:

void Dir_Insert(int A[],int N) //直接插入排序 {

int j,t;

for(int i=1;i

t=A[i]; j=i-1;

while(A[j]>t) //j需要判断有效 {

A[j+1]=A[j]; j--; }

A[j+1]=t; } }

②.希尔排序(不稳定):

希尔(Shell)排序的基本思想是:先取一个小于n的整数d1作为第一个增量把文件的全部记录分成d1个组。所有距离为d1的倍数的记录放在同一个组中。先在各组内进行直接插入排序;然后,取得第二个增量d2

一般取d1=n/2,di+1=di/2。如果结果为偶数,则加1,保证di为奇数。

希尔排序是不稳定的,希尔排序的执行时间依赖于增量序列,其平均时间复杂度为O(n^1.3).

代码如下:

void Shell(int A[],int n) //Shell排序 {

int i,j,k,t;

(n/2)%2 == 0 ? k = n/2+1 : k = n/2; //保证增量为奇数 while(k > 0) {

for(j=k;j

t = A[j]; i = j - k;

while(i>=0 && A[i]>t) {

A[i+k]=A[i]; i=i-k; }

A[i+k]=t; }

if(k == 1) break;

(k/2)%2 ==0 ? k=k/2+1 : k=k/2; } }

二.选择排序

选择排序的基本思想是每步从待排序的记录中选出排序码最小的记录,顺序存放在已排序的记录序列的后面,直到全部排完。选择排序中主要使用直接选择排序和堆排序。

①.直接选择排序(不稳定)

直接选择排序的过程是:首先在所有记录中选出序码最小的记录,把它与第1个记录交换,然后在其余的记录内选出排序码最小的记录,与第2个记录交换......依次类推,直到所有记录排完为止。 无论文件初始状态如何,在第i趟排序中选出最小关键字的记录,需要做n-i次比较,因此,总的比较次数为n(n-1)/2=O(n^2)。当初始文件为正序时,移动次数为0;文件初态为反序时,每趟排序均要执行交换操作,总的移动次数取最大值3(n-1)。直接选择排序的平均时间复杂度为O(n^2)。直接选择排序是不稳定的。

代码如下:

void Dir_Choose(int A[],int n) //直接选择排序

{

int k,t;

for(int i=0;i

for(int j=i+1;j

if(A[j]

t=A[i]; A[i]=A[k]; A[k]=t; } } }

②.堆排序(不稳定)

堆排序是一种树形选择排序,是对直接选择排序的有效改进。n个关键字序列

K1,K2,...,Kn称为堆,当且仅当该序列满足(Ki<=K2i且Ki<=K2i+1)或(Ki>=K2i且Ki>=K2i+1),(1<=i<=n/2)。根结点(堆顶)的关键字是堆里所有结点关键字中最小者,称为小根堆;根结点的关键字是堆里所有结点关键字中最大者,称为大根堆。

若将此序列所存储的向量R[1..n]看作是一棵完全二叉树的存储结构,则堆实质上是满足如下性质的完全二叉树:树中任一非叶结点的关键字均不大于(或不小于)其左右孩子(若存在)结点的关键字。 堆排序的关键步骤有两个:一是如何建立初始堆;二是当堆的根结点与堆的最后一个结点交换后,如何对少了一个结点后的结点序列做调整,使之重新成为堆。堆排序的最坏时间复杂度为O(nlog2n),堆排序的平均性能较接近于最坏性能。由于建初始堆所需的比较 次数较多,所以堆排序不适宜于记录较少的文件。堆排序是就地排序,辅助空间为O(1),它是不稳定的排序方法。 代码

#include #define SIZE 10

#defineLeft(i) ((i)<<1) #defineRight(i) (((i)<<1)+1)

voidheapsort(inta[],intheapsize); voidmaxheapify(inta[],inti,intheapsize); voidswap(int*x,int*y);

int main(intargc,char**argv) {

int a[SIZE+1]={0,16,4,10,14,7,9,3,2,8,1}; /* note a[0] is not used */ inti,heapsize;

heapsize=SIZE; heapsort(a,heapsize);

for(i=1;i

return0; } /*

* heapsort: contains two procedures, one is to build the max-heap, * the other is to delete max to gain the sorted array. */

void heapsort(inta[],intheapsize) {

int i;

for(i=heapsize/2;i>=1;i--) /* build max-heap */ maxheapify(a,i,heapsize);

for(i=heapsize;i>=2;i--) /* delete max */ {

swap(&a[1],&a[i]); heapsize--;

maxheapify(a,1,heapsize); }

} /*

* maxheapify: used to let the value at a[i] \ * max-heap so that the subtree rooted at index i becomes a max-heap. */

voidmaxheapify(inta[],inti,intheapsize) {

int largest,left,right;

left=Left(i); right=Right(i);

if(left<=heapsize&&a[left]>a[i]) largest=left; else

largest=i;

if(right<=heapsize&&a[right]>a[largest]) largest=right;

if(largest!=i) {

swap(&a[i],&a[largest]);

maxheapify(a,largest,heapsize); /* recurrsion */ }

return; /* return when largest == i */ }

voidswap(int*x,int*y) {

int temp;

temp=*x; *x=*y; *y=temp; }

本文来源:https://www.bwwdw.com/article/umm2.html

Top