您的位置:首页 > 编程语言 > C语言/C++

排序算法实例精粹(windows c++ 验证)

2014-02-10 22:22 288 查看
//sort.hpp文件

/*
1.
插入排序

最好情况:元素数组本身是排好的;比较次数n-1;元素移动次数0;

最坏情况:元素数组是倒序的;比较次数KCN=n(n-1)/2 =n*2/2;元素移动次数 (n+4)(n-1)/2=n*n/2;

所以直接插入排序时间复杂度为O(n*n);

直接插入排序是一种稳定排序算法;
*/

template<class T>
void insertSort(T dataList[], const int left, const int right)
{
T tmp;
int i=0,j=0;

for(i= left+1; i<=right; i++)
{
if(dataList[i] < dataList[i-1])
{
tmp = dataList[i];
j= i-1;

do
{
dataList[j+1] = dataList[j];
j--;
}while (j>=left && tmp < dataList[j]);

dataList[j+1] = tmp;

}
}
}

/*
2.
折半插入排序

折半插入排序搜索速度比直接插入排序快。
元素比较次数与待排序元素序列的初始排序无关,仅依赖元素个数。
元素比较次数:n*log2n-n+1
元素移动次数 (n+4)(n-1)/2=n*n/2(和直接插入排序算法一样);
数据量较大时,比直接插入排序有优势
折半插入排序是稳定排序算法
*/
template<class T>
void binaryInsertSort(T dataList[], const int left, const int right)
{
for (int i=left+1; i<= right; i++)
{

if (dataList[i]<dataList[i-1])
{
T tmp = dataList[i];

int nLow = left;
int nHigh = i;

while(nLow < nHigh)
{

int nMid = (nHigh-nLow)/2+nLow;

if (tmp <= dataList[nMid])
{
nHigh = nMid-1;
}
else
{
nLow = nMid+1;
}
}

for (int k = i; k>nLow; k--)
{
dataList[k] = dataList[k-1];
}

dataList[nLow] = tmp;

}
}
}

/*
3.
希尔排序算法(又称为缩小增量排序 diminishing-incrementsort) 1959年希尔提出
算法思想:设带排序元素序列有n个元素,首先取一个整数gap(gap<n),作为间隔,将全部元素分为gap个子序列,
所有距离为gap的元素放在同一个子序列中,在每个子序列中分别进行直接插入排序。
然后缩小gap,例如gap=gap/2,重复上述的子序列划分和排序工作,直到gap==1,将所有元素放在同一个序列中排序为止。
元素移动次数:n的1.25次方-1.6*n的1.25次方

由于即使对于规模较大的序列(n<=1000),希尔排序都具有很高的效率,很多应用程序都选择希尔排序。
希尔排序是一种不稳定排序算法
*/

template<class T>
void shellSort(T dataList[], const int left, const int right)
{
int i=0;
int j=0;
int gap = right - left + 1;//增量的初始化值

T tmp = 0;
do
{

gap = gap / 3 + 1;//求下一增量值

for (i=left+gap; i<=right; i++)
{

if (dataList[i] < dataList[i-gap])
{

tmp = dataList[i];
j = i-gap;

do
{

dataList[j+gap] = dataList[j];

j = j - gap;

} while (j > left && tmp < dataList[j]);

dataList[j+gap] = tmp;

}

}

} while (gap > 1);
}

/*
4.
快速排序算法

快速排序算法是C.R.A.Hoare 于1992年提出的一种划分交换的方法,它采用分治法(divide-and-conquer)进行排序。基本思想就是任取待排序元素序列中的某个元素
作为基准,将大于这个数的放在右边,将小于这个数的放在左边,。然后分别对这两个子序列重复实施上述方法,直到所有元素都排在相应的位置为止。

*/

template<class T>
int Partion(T dataList[], const int left, const int right)
{
T  nBaseData = dataList[left];

int nPosCurBase = left;

for (int i=left+1; i<=right; i++)
{

if ( dataList[i] < nBaseData )
{

nPosCurBase++;
if(i != nPosCurBase)
{

T tmp = dataList[nPosCurBase];
dataList[nPosCurBase] = dataList[i];
dataList[i] = tmp;
}
}
}

dataList[left] = dataList[nPosCurBase];
dataList[nPosCurBase] = nBaseData;

return nPosCurBase;

}

template<class T>
void	quickSort(T dataList[], const int left, const int right)
{

if (left >= right)
{
return;
}

int nPosCurBase = Partion(dataList, left, right);

quickSort(dataList, left, nPosCurBase-1);
quickSort(dataList, nPosCurBase+1, right);

}

/*
5.
选择排序
*/

template<class T>
void	selectSort(T datalist[], const int nLeft, const int nRight)
{
for (int i=nLeft; i<nRight; i++)
{
int minIndex = i;

for (int j=i; j<=nRight; j++)
{
if (datalist[j] < datalist[minIndex])
{
minIndex = j;
}
}

if (minIndex != i)
{
T tmp = datalist[i];
datalist[i] = datalist[minIndex];
datalist[minIndex] = tmp;
}

}
}

/*
6.
归并排序
*/

template<class T>
void merge(T datalist[], int nLeft, int nMid, int nRight)
{
int nLenLeft = nMid - nLeft + 1;
int nLenRight = nRight - nMid;

T *pLeft = new T[nLenLeft];
T *pRight = new T[nLenRight];

int i=0;
int j=0;
for ( i=0; i<nLenLeft; i++)
{
pLeft[i] = datalist[i+nLeft];
}

for ( j=0; j<nLenRight; j++)
{
pRight[j] = datalist[nMid+j+1];
}

i=0;
j=0;
int k = nLeft;
for (k=nLeft; k<nRight; k++)
{
if (!(i<nLenLeft && j <nLenRight))
{
break;
}

if (pLeft[i]<pRight[j])
{
datalist[k] = pLeft[i];
i++;
}
else
{
datalist[k] = pRight[j];
j++;
}
}

while(i<nLenLeft)
{
datalist[k++] = pLeft[i];
i++;
}

while(j<nLenRight)
{
datalist[k++] = pRight[j];
j++;
}

if (pLeft)
{
delete []pLeft;
pLeft = NULL;
}

if (pRight)
{
delete [] pRight;
pRight = NULL;
}
}

template<class T>
void mergeSort(T datalist[], int nLeft, int nRight)
{
if (nLeft>=nRight)
{
return;
}

int nMid = (nRight+nLeft)/2;
mergeSort(datalist, nLeft, nMid);
mergeSort(datalist, nMid+1, nRight);

merge(datalist, nLeft, nMid, nRight);

}

/*
7.
冒泡排序应该是最垃圾的一种排序算法,而选择排序是冒泡排序的一种升级
2014年2月18日18:16:58
*/
template<class T>
void paopaoSort(T datalist[], int nLeft, int nRight)
{

for (int i=nLeft; i<nRight; i++)
{
for (int j=i+1; j<=nRight; j++)
{
if (datalist[j] < datalist[i])
{
T tmp = datalist[i];
datalist[i] = datalist[j];
datalist[j] = tmp;
}
}
}

}
/*
8.
分配排序之桶式排序*/
/*
9.
分配排序之基数排序*/

/*内部排序算法的分析*/
//sort.hpp 完


//main.cpp -------------------------------------------------------------------------------------------------------------------

#include "sort.hpp"

template<class T>
void show(T *p, int nlen)
{
for (int i=0; i<nlen; i++)
{
std::cout<<p[i]<<"-";
}
std::cout<<std::endl;

}

int a[]={2,3,4,5,4,3,3,3,4,5,6,5,3,56,7,7,5,3};
int b[]={2,3,4,5,4,3,3,3,4,5,6,5,3,56,7,7,5,3};
int c[]={2,3,4,5,4,3,3,3,4,5,6,5,3,56,7,7,5,3};
int d[]={2,3,4,5,4,3,3,3,4,5,6,5,3,56,7,7,5,3};
int e[]={2,3,4,5,4,3,3,3,4,5,6,5,3,56,7,7,5,3};
int f[]={2,3,4,5,4,3,3,3,4,5,6,5,3,56,7,7,5,3};
int g[]={2,3,4,5,4,3,3,3,4,5,6,5,3,56,7,7,5,3};
int _tmain(int argc, _TCHAR* argv[])
{

int nLen = sizeof(a)/sizeof(int);

insertSort(a, 0, nLen-1);
show<int>(a, nLen);

binaryInsertSort<int>(b, 0, nLen-1);
show<int>(b, nLen);

shellSort<int>(c, 0, nLen-1);
show<int>(c, nLen);

quickSort<int>(d, 0, nLen-1);
show<int>(d, nLen);

selectSort<int>(e, 0, nLen-1);
show<int>(e, nLen);

mergeSort<int>(f, 0, nLen-1);
show<int>(f, nLen);

paopaoSort<int>(g, 0, nLen-1);
show<int>(g, nLen);
return 0;
}
//main.cpp完


输出结果:

2-3-3-3-3-3-3-4-4-4-5-5-5-5-6-7-7-56-

3-3-3-2-3-4-3-4-5-3-5-4-5-5-7-6-7-56-

2-3-3-3-3-3-3-4-4-4-5-5-5-5-6-7-7-56-

2-3-3-3-3-3-3-4-4-4-5-5-5-5-6-7-7-56-

2-3-3-3-3-3-3-4-4-4-5-5-5-5-6-7-7-56-

2-3-3-3-3-3-3-4-4-4-5-5-5-5-6-7-7-56-

2-3-3-3-3-3-3-4-4-4-5-5-5-5-6-7-7-56-

请按任意键继续. . .
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: