我的面試備忘錄:各大排序算法程序

排序 按照存儲器,數量,分爲內排,外排


內排按照排序過程中不同原則分爲插入排序,交換排序,選擇排序,歸併排序,計數排序

內排按照排序過程中的工作量分爲
(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-i
if( 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、堆排序 nlogn
void 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;

}


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章