我的面试备忘录:各大排序算法程序

来源:互联网 发布:日本和服的来源知乎 编辑:程序博客网 时间:2024/06/05 09:48
排序 按照存储器,数量,分为内排,外排


内排按照排序过程中不同原则分为插入排序,交换排序,选择排序,归并排序,计数排序

内排按照排序过程中的工作量分为
(1)简单排序,时间复杂度为O(n*n)
(2)先进排序,时间复杂度为O(nlogn)
(3)基数排序,时间复杂度为O(d*n)

程序很容易看懂,在VC2005下测试通过,希望对大家有帮助,如下:
#include <iostream>#include <math.h>using namespace std ;#define EQ(a,b) ((a ) ==(b ))#define LT(a,b) ((a ) < (b ))#define GT(a,b) ((a ) > (b ))/************************************************************************//* 定义待排数据的类型 *//************************************************************************/#define MAXSIZE 20 // 用作实例的小顺序表的最大长度typedef int KeyType ;typedef struct {KeyType key; //关键字项//or other type;}RedType; //记录类型typedef struct {RedType r[ MAXSIZE+1]; //r[0]闲置或者用于哨兵int length; //顺序表长度}SqList;typedef SqList HeapType ;/************************************************************************//* 插入排序 *//************************************************************************///1、直接插入排序 复杂度 O(n*n)void InsertSort (SqList &L ){int i, j;for( i=2; i<= L. length; i++){if( LT( L. r[ i]. key, L. r[ i-1]. key)) //'<'把L.r[i] 插入有序子表{L. r[0]= L. r[ i]; //将待比较的项保存为哨兵L. r[ i]= L. r[ i-1];for( j= i-2; LT( L. r[0]. key, L. r[ j]. key); j--)L. r[ j+1]= L. r[ j]; //子表全体向后移动L. r[ j+1]= L. r[0]; //插入到正确的位置}}}//2、折半插入排序void BInsertSort (SqList &L ){int low=1; int high=1; int m=0;for ( int i=2; i<= L. length; i++){L. r[0]. key= L. r[ i]. key; //将 L.r[i]暂存到L.r[0]low=1; high= i-1;while( low<= high) //在 r[low.. high]中折半查找有序插入的位置{m=( low+ high)/2;if ( LT( L. r[0]. key, L. r[ m]. key)) high= m-1; //插入点在高半区else low= m+1; //插入点在低半区}for( int j= i-1; j>= high+1; j--) L. r[ j+1]= L. r[ j];L. r[ high+1]= L. r[0];}}//3、希尔排序void ShellInsert (SqList &L ,int dk ){int i, j;for( i= dk+1; i<= L. length; i++){if( LT( L. r[ i]. key, L. r[ i- dk]. key)){L. r[0]= L. r[ i];for( j= i- dk; j>0 && LT( L. r[0]. key, L. r[ j]. key); j-= dk)L. r[ j+ dk]= L. r[ j];L. r[ j+ dk]= L. r[0];}}}void ShellSort (SqList &L ,int delta [],int t ){for( int k=0; k< t; k++)ShellInsert(L,delta [k ]);delete [] delta;delta= NULL;}int* getDelta (SqList &L ,int t ){int * delta = new int[ L. length];delta[ t-1]=1;for( int i= t-2; i>=0; i--)delta[ i]=( delta[ i+1]+1)*2-1;return delta;}int getT (SqList &L ){int t=0, len= L. length;while( len/2) { t++; len/=2;}return t;}/************************************************************************//* 交换排序 *//************************************************************************///1、冒泡排序void BubbleSort (SqList &L ){bool change= false;for( int i=1; i< L. length; i++){change= false;for( int j=1; j<= L. length- i; j++){ //每一次总是最大的移到最后,所以 j<=L.length-iif( LT( L. r[ j+1]. key, L. r[ j]. key)){L. r[0]= L. r[ j+1]; L. r[ j+1]= L. r[ j]; L. r[ j]= L. r[0];change= true; //增加一个哨兵,提前判断结束}}if(! change)break;}}//2、快速排序int Partition (SqList &L ,int low ,int high ){//复杂度 knlnn,被认为是最好得内部排序//交换顺序表 L中的子表 r[low,high,使枢轴记录到尾,并且返回所在位置//此时前后的记录都不大(小)于它L. r[0]= L. r[ low]; //用子表的第一个记录做枢轴记录int pivotkey = L. r[ low]. key; //枢轴记录关键字while( low< high){ //从表的两端交替向中间扫描while( low< high && L. r[ high]. key>= pivotkey) high--; //将比枢轴小的记录移到低端L. r[ low]= L. r[ high];while( low< high && L. r[ low]. key<= pivotkey) low++; //将比枢轴大的记录移到高端L. r[ high]= L. r[ low];}L. r[ low]= L. r[0]; //枢轴记录到位return low; //返回枢轴位置}void QSort (SqList &L ,int low ,int high ){int pivotloc;if( low< high){pivotloc= Partition( L, low, high); //长度大于一QSort( L, low, pivotloc-1); //将 L.r[low....high]一分为二QSort( L, pivotloc+1, high);}}/************************************************************************//* 选择排序 *//************************************************************************///1、简单选择排序int selectMinKey (SqList &L ,int pos ){int min= L. r[ pos]. key;int j=0;for ( int i= pos; i<= L. length; i++){if ( LT( L. r[ i]. key, min)){min= L. r[ i]. key;j= i;}}return j;}void SelectSort (SqList &L ){int miniPos;for( int i=1; i< L. length; i++) //选择第 i小的记录,并且交换到位{miniPos= selectMinKey(L,i);//在 L[i..L.length]中选择key 最小的值if( miniPos!= i){L. r[0]= L. r[ i]; //交换L. r[ i]= L. r[ miniPos];L. r[ miniPos]= L. r[0];}}}//2、堆排序 nlognvoid HeapAdjust (HeapType &H ,int s ,int m ){RedType rc = H. r[ s];for( int j=2* s; j<= m; j*=2) //沿着 key较大的孩子结点向下筛选{if( j< m && LT( H. r[ j]. key, H. r[ j+1]. key)) ++ j; //取比较大的孩子if(! LT( rc. key, H. r[ j]. key))break;H. r[ s] = H. r[ j]; s= j; //交换,并且记录当前位置}H. r[ s]= rc;}void HeapSort (HeapType &H ){RedType temp;for( int i= H. length/2; i>0; i--) //把 H.r[1..H.length]建成大顶堆HeapAdjust( H, i, H. length);for ( int i= H. length; i>1; i--){temp= H. r[1]; //获得大顶堆顶部最大值,放入堆尾H. r[1]= H. r[ i];H. r[ i]= temp;HeapAdjust( H,1, i-1); //然后再把 H.r[1..i-1]排成大顶堆}}/************************************************************************//* 归并排序 *//************************************************************************///1、路归并排序void Merge (RedType SR [],RedType TR1 [],int i ,int m ,int n ){int k=0, j=0;//将有序的 SR[i..m]和SR[m+1..n] 归并为有序的 TR[i..n]for( j= m+1, k= i; i<= m&& j<= n; k++){if( LT( SR[ i]. key, SR[ j]. key)) TR1[ k]= SR[ i++];else TR1[ k]= SR[ j++];}if( i<= m){for( int t1= i; t1<= m; t1++)TR1[ k++]= SR[ t1];}if( j<= n){for( int t1= j; t1<= n; t1++)TR1[ k++]= SR[ t1];//memcpy(TR1+k,SR+j,(n-j)*sizeof(RedType));}}void MSort (RedType SR [],RedType TR1 [],int s ,int t ){int m=0;//RedType *TR2 = new RedType[t-s+1];//将 SR[s..t]归并排序为TR1[s..t]if ( s== t){ TR1[ s]= SR[ s];}else{m=( t+ s)/2;MSort( TR1, SR, s, m);MSort( TR1, SR, m+1, t);Merge( SR, TR1, s, m, t);}}void MergeSort (SqList &L ){SqList M= L;MSort( M. r, L. r,1, L. length);}void Display (SqList &L ){for ( int i=1; i<= L. length; i++){cout<< L. r[ i]. key<< " ";}cout<< endl;}int main (){SqList L;L. length=0;for ( int i=1; i<=10; i++){L. r[ i]. key= rand()%10+1;L. length++;}Display( L);//SelectSort(L);MergeSort( L);//L.r[0].key=5;//HeapSort(L);//QSort(L,1,L.length);//BubbleSort(L);//ShellSort(L,getDelta(L,getT(L)),getT(L));//InsertSort(L);//BInsertSort(L);Display( L);cin. get();return 0;}