您的位置:首页 > 理论基础 > 数据结构算法

几种排序

2010-12-01 09:36 197 查看
Sort排序是经典问题,关于排序的算法也有很多,根据平时的使用习惯,下面简单总结了几种常见的,简单易懂的排序算法。其中部分内容参考了数据结构自考网,还有各位大神,小鬼的blog。 目录:(按策略划分)交换排序       冒泡排序(BubbleSort)       快速排序(QuickSort)插入排序       直接插入排序(InsertionSort)       希尔排序(Shell Sort)选择排序       直接选择排序(Selection Sort)       堆排序(HeapSort)以上几种排序方法比较 BubbleSort经典冒泡排序,两项比较,如果大小关系和关键字相反就交换位置#include<stdio.h>void main(){       int i,j,t;       int a[9]={9,2,1,5,6,3,4,7,8};       for(i=1;i<9;i++)              for(j=0;j<8;j++)                     if(a[j]>a[i])                     {                            t=a[j];a[j]=a[i];a[i]=t;                     }       for(i=0;i<9;i++)              printf("%d ",a[i]);       printf("/n");}另:算法思想:将被排序的记录数组R[1..n]垂直排列,每个记录R[i]看作是重量为R[i].key的气泡。根据轻气泡不能在重气泡之下的原则,从下往上扫描数组R:凡扫描到违反本原则的轻气泡,就使其向上"飘浮"。如此反复进行,直到最后任何两个气泡都是轻者在上,重者在下为止。QuickSort快速排序(qsort),分治递归思想制定标志变量,以其分割数组,并对前数组,后数组分别递归调用函数,直到数组长度为1,则完成排序#include <iostream>   #include <stdlib.h>   #include <ctime>   using namespace std;   int partition(int *A,int p,int r)  //数组分割 {       int i,j,x;       x=A[r];       //指定标志值    i=p-1;            //保证第一次找到的小于,等于X的数被换到    for(j=p;j<r;j++)  //a[0],第二个放到a[1]……        if(A[j] <= x) //大于X的数不会使i变大        {               i++;            swap<int>(A[i],A[j]);             }       swap<int>(A[i+1],A[r]);   //前i个数都小于a[r]    return i+1;     //返回a[r],即分割数组的标志值位置}   void quicksort(int *A,int p,int r)   {       if(p >= r)           return ;       int q=partition(A,p,r);       quicksort(A,p,q-1);   //q位置的数不用参与排序,因为当前位置就是    quicksort(A,q+1,r);   //其正确位置}   void Show(int *A,int p,int r)   {       for(int i=p;i<=r;i++)           cout<<A[i]<<" ";       cout<<endl;   }   void main()   {       int i;       int A[10];       srand((unsigned int)time(NULL));       for(i=0;i<10;i++)           A[i]=rand()%20;       Show(A,0,9);       quicksort(A,0,9);       Show(A,0,9);       system("pause");      } InsertionSort插入排序,每次将一个待排序的记录,按其关键字大小插入到前面已经排好序的子文件中的适当位置,直到全部记录插入完成为止。默认当前项前面的序列有序,并在前面的序列中查找第一个比当前项大(小)的数,找到后,把该数以及其后面的数全部后移一位,空出来的位置就是当前的位置。插入排序的操作很类似打牌时整理手中的牌,很有意思的方法。#include<stdio.h>void main(){       int i,j,t;       int a[9]={9,2,1,5,6,3,4,7,8};       for(i=1;i<9;i++)       {              if(a[i]<a[i-1])//若R[i].key大于等于有序区中所有的keys,则R[i]                       //应在原有位置上              {                     t=a[i];                     for(j=i-1;j>=0;j--)                            if(a[j]>t)                            {                                   a[j+1]=a[j];                                   a[j]=t;                            }                            else break;              }       }       for(i=0;i<9;i++)              printf("%d ",a[i]);       printf("/n");} 另:希尔排序实质上就是分组插入排序,效率较直接插入排序有很大提高,但是不稳定。 SelectionSort选择排序,在待排数据中查找最小(大)值放在第一位,然后在剩下的数中查找第二小(大)的数放在第二位,……依次操作#include<stdio.h>void main(){       int i,j,t,min;       int a[9]={9,2,1,5,6,3,4,7,8};       for(i=0;i<9;i++)       {              min=i;              for(j=i+1;j<9;j++)                     if(a[j]<a[min])                            min=j;                  t=a[i];a[i]=a[min];a[min]=t; //t做存储单元,也可以用a[0]做存储单元       }       for(i=0;i<9;i++)              printf("%d ",a[i]);       printf("/n");} 直接选择排序时就地排序,是不稳定的排序。 HeapSort堆排序堆实质上是满足如下性质的完全二叉树:树中任一非叶结点的关键字均不大于(或不小于)其左右孩子(若存在)结点的关键字。根结点(亦称为堆顶)的关键字是堆里所有结点关键字中最小者的堆称为小根堆。根结点的关键字是堆里所有结点关键字中最大者,称为大根堆。堆中任一子树亦是堆。堆排序可通过树形结构保存部分比较结果,可减少比较次数。堆排序利用了大根堆(或小根堆)堆顶记录的关键字最大(或最小)这一特征,使得在当前无序区中选取最大(或最小)关键字的记录变得简单。步骤:建堆(假设是大根堆),把堆顶元素a[1]和最后一个元素a
交换位置,则a
就是最大值;然后以a[1]到a[n-1]为对象,调整建堆,再把堆顶元素和最后一个元素(现在是a[n-1])交换,则a[n-1]到a
就是有序的了。以此重复操作即可。  以上几种排序方法比较平均时间:(1)    平方阶(O(n2))排序一般称为简单排序,例如直接插入、直接选择和冒泡排序;(2)线性对数阶(O(nlgn))排序     如快速、堆排序;(3)O(n1+£)阶排序     £是介于0和1之间的常数,即0<£<1,如希尔排序;各种排序方法比较     简单排序中直接插入最好,快速排序最快,当文件为正序时,直接插入和冒泡均最佳。影响排序效果的因素     因为不同的排序方法适应不同的应用环境和要求,所以选择合适的排序方法应综合考虑下列因素:       1待排序的记录数目n;2记录的大小(规模);3关键字的结构及其初始状态;4对稳定性的要求;5语言工具的条件;6存储结构;7时间和辅助空间复杂度等。不同条件下,排序方法的选择
(1)若n较小(如n≤50),可采用直接插入或直接选择排序。     当记录规模较小时,直接插入排序较好;否则因为直接选择移动的记录数少于直接插入,应选直接选择排序为宜。(2)若文件初始状态基本有序(指正序),则应选用直接插入、冒泡或随机的快速排序为宜;(3)若n较大,则应采用时间复杂度为O(nlgn)的排序方法:快速排序、堆排序;     快速排序是目前基于比较的内部排序中被认为是最好的方法,当待排序的关键字是随机分布时,快速排序的平均时间最短;     堆排序所需的辅助空间少于快速排序,并且不会出现快速排序可能出现的最坏情况。这两种排序都是不稳定的。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息