1. 冒泡排序:
#include <stdio.h>
#include <stdlib.h>
//冒泡排序, pnData要排序的数据, nLen数据的个数
int BubbleSort(int* pnData, int nLen)
{
bool isOk = false; //设置排序是否结束的哨兵
//i从[0,nLen-1)开始冒泡,确定第i个元素
for (int i = 0; i < nLen - 1 && !isOk; ++i)
{
isOk = true; //假定排序成功
//从[nLen - 1, i)检查是否比上面一个小,把小的冒泡浮上去
for (int j = nLen- 1; j > i; --j)
{
if (pnData[j] < pnData[j - 1]) //如果下面的比上面小,交换
{
int nTemp = pnData[j];
pnData[j] = pnData[j - 1];
pnData[j - 1] = nTemp;
isOk = false;
}
}
}
return 1;
}
int main()
{
int nData[10] = {4,10,9,8,7,6,5,4,3,2}; //创建10个数据,测试
BubbleSort(nData, 10); //调用冒泡排序
for (int i = 0; i < 10; ++i)
{
printf("%d ", nData[i]);
}
printf("\n");
system("pause");
return 0;
}
2. 计数排序
#include <stdio.h>
#include <stdlib.h>
//计数排序
int CountSort(int* pData, int nLen)
{
int* pCout = NULL; //保存记数数据的指针
pCout = (int*)malloc(sizeof(int) * nLen); //申请空间
//初始化记数为0
for (int i = 0; i < nLen; ++i)
{
pCout[i] = 0;
}
//记录排序记数。在排序的值相应记数加1。
for (i = 0; i < nLen; ++i)
{
++pCout[pData[i]]; //增
}
//确定不比该位置大的数据个数。
for (i = 1; i < nLen; ++i)
{
pCout[i] += pCout[i - 1]; //不比他大的数据个数为他的个数加上前一个的记数。
}
int* pSort = NULL; //保存排序结果的指针
pSort = (int*)malloc(sizeof(int) * nLen); //申请空间
for (i = 0; i < nLen; ++i)
{
//把数据放在指定位置。因为pCout[pData[i]]的值就是不比他大数据的个数。
//为什么要先减一,因为pCout[pData[i]]保存的是不比他大数据的个数中包括了
//他自己,我的下标是从零开始的!所以要先减一。
--pCout[pData[i]]; //因为有相同数据的可能,所以要把该位置数据个数减一。
pSort[pCout[pData[i]]] = pData[i];
}
//排序结束,复制到原来数组中。
for (i = 0; i < nLen; ++i)
{
pData[i] = pSort[i];
}
//最后要注意释放申请的空间。
free(pCout);
free(pSort);
return 1;
}
int main()
{
int nData[10] = {8,6,3,6,5,8,3,5,1,0};
CountSort(nData, 10);
for (int i = 0; i < 10; ++i)
{
printf("%d ", nData[i]);
}
printf("\n");
system("pause");
return 0;
}
3. 堆排序
#include <stdio.h>
#include <stdlib.h>
//交换两个整数。注意一定要if判断是否两个相等,如果
//不相等才交换,如果相等也交换会出错的。a^a = 0
inline void Swap(int& a, int& b)
{
if (a != b)
{
a^= b;
b^= a;
a^= b;
}
}
//维持一个最大堆
int Heapify(int* npData, int nPos, int nLen)
{
int nMax = -1; //暂存最大值
int nChild = nPos * 2; //他的左孩子位置
while(nChild <= nLen) //判断他是否有孩子
{
nMax = npData[nPos]; //是当前最大值为他
if (nMax < npData[nChild]) //与左孩子比较
{
nMax = npData[nChild]; //如果比左孩子小,就时最大值为左孩子
}
//同理与右孩子比较,这里要注意,必须要保证有右孩子。
if (nChild + 1 <= nLen && nMax < npData[nChild + 1])
{
++nChild; //赋值最大值的时候把孩子变为右孩子,方便最后的数据交换
nMax = npData[nChild];
}
if (nMax != npData[nPos]) //判断是否该节点比孩子都打,如果不大
{
Swap(npData[nPos], npData[nChild]); //与最大孩子交换数据
nPos = nChild; //该节点位置变为交换孩子的位置
nChild *= 2; //因为只有交换后才使不满足堆得性质。
}
else //都最大了,满足堆得性质了。退出循环
{
break;
}
}
return 1; //维持结束。
}
//建立一个堆
int BuildHeap(int* npData, int nLen)
{
//从nLen / 2最后一个有叶子的数据开始,逐一的插入堆,并维持堆得平衡。
//因为堆是一个完全二叉树,所以nlen/2+1- nLen之间肯定都是叶子。
//叶子还判断什么呢。只有一个数据,肯定满足堆得性质咯。
for (int i = nLen / 2; i >= 1; --i)
{
Heapify(npData, i, nLen);
}
return 1;
}
//堆排序
int HeapSort(int* npData, int nLen)
{
BuildHeap(npData, nLen); //建立一个堆。
while(nLen >= 1) //逐一交和第一个元素交换数据到最后
{ //完成排序
Swap(npData[nLen], npData[1]);
--nLen;
Heapify(npData, 1, nLen);//交换之后一定要维持一下堆得性质。
} //不然小的成第一个元素,就不是堆了。
return 1;
}
//main函数,
int main()
{
int nData[11] = {0,9,8,7,6,5,4,3,2,1,0}; //测试数据,下标从1开始哦。
HeapSort(nData, 10); //堆排序
for (int i = 1; i <= 10; ++i) //输出排序结果。
{
printf("%d ", nData[i]);
}
printf("\n");
system("pause");
return 0;
}
4. 插入排序
#include <stdio.h>
#include <stdlib.h>
//插入排序从下到大,nData为要排序的数据,nNum为数据的个数,该排序是稳定的排序
bool InsertionSort(int nData[], int nNum)
{
for (int i = 1; i < nNum; ++i) //遍历数组,进行插入排序
{
int nTemp = nData[i];
for (int j = 0; j < i; ++j) //对该数,寻找他要插入的位置
{
if (nData[j] > nTemp) //找到位置,然后插入该位置,之后的数据后移
{
for (int k = i; k > j; --k) //数据后移
{
nData[k] = nData[k -1];
}
nData[j] = nTemp; //将数据插入到指定位置
break;
}
}
}
return true;
}
int main()
{
int nData[10] = {4,10,9,8,7,6,5,4,3,2}; //创建10个数据,测试
InsertionSort(nData, 10); //调用插入排序
for (int i = 0; i < 10; ++i)
{
printf("%d ", nData[i]);
}
printf("\n");
system("pause");
return 0;
}
5. 合并排序
#include <stdio.h>
#include <stdlib.h>
#define INT_MAX 2147483647
//合并排序的合并程序他合并数组nData中位置为[nP,nM) 和[nM,nR).这个是更接近标准的思路
bool MergeStandard(int nData[], int nP, int nM, int nR)
{
int n1 = nM - nP; //第一个合并数据的长度
int n2 = nR - nM; //第二个合并数据的长度
int *pnD1 = new int[n1 + 1]; //申请一个保存第一个数据的空间
int *pnD2 = new int[n2 + 1]; //申请二个保存第一个数据的空间
for (int i = 0; i < n1; ++i) //复制第一个数据到临时空间里面
{
pnD1[i] = nData[nP + i];
}
pnD1[n1] = INT_MAX; //将最后一个数据设置为最大值(哨兵)
for (i = 0; i < n2; ++i) //复制第二个数据到临时空间里面
{
pnD2[i] = nData[nM + i];
}
pnD2[n2] = INT_MAX; //将最后一个数据设置为最大值(哨兵)
n1 = n2 = 0;
while(nP < nR)
{
nData[nP++] = pnD1[n1] < pnD2[n2] ? pnD1[n1++] : pnD2[n2++]; //取出当前最小值到指定位置
}
delete pnD1;
delete pnD2;
return true;
}
//合并排序的合并程序他合并数组nData中位置为[nP,nM) 和[nM,nR).
bool Merge(int nData[], int nP, int nM, int nR)
{
//这里面有几个注释语句是因为当时想少写几行而至。看似短了,其实运行时间是一样的,而且不易阅读。
int nLen1 = nM - nP; //第一个合并数据的长度
int nLen2 = nR - nM; //第二个合并数据的长度
int* pnD1 = new int[nLen1]; //申请一个保存第一个数据的空间
int* pnD2 = new int[nLen2]; //申请一个保存第一个数据的空间
int i = 0;
for ( i = 0; i < nLen1; ++i) //复制第一个数据到临时空间里面
{
pnD1[i] = nData[nP + i];
}
int j = 0;
for (j = 0; j < nLen2; ++j) //复制第二个数据到临时空间里面
{
pnD2[j] = nData[nM + j];
}
i = j = 0;
while (i < nLen1 && j < nLen2)
{
//nData[nP++] = pnD1[i] < pnD2[j] ? pnD1[i++] : pnD2[j++]; //取出当前最小值添加到数据中
if (pnD1[i] < pnD2[j]) //取出最小值,并添加到指定位置中,如果pnD1[i] < pnD2[j]
{
nData[nP] = pnD1[i]; //取出pnD1的值,然后i++,定位到下一个个最小值。
++i;
}
else //这里同上
{
nData[nP] = pnD2[j];
++j;
}
++nP; //最后np++,到确定下一个数据
}
if (i < nLen1) //如果第一个数据没有结束(第二个数据已经结束了)
{
while (nP < nR) //直接把第一个剩余的数据加到nData的后面即可。
{
//nData[nP++] = pnD1[i++];
nData[nP] = pnD1[i];
++nP;
++i;
}
}
else //否则(第一个结束,第二个没有结束)
{
while (nP < nR) //直接把第一个剩余的数据加到nData的后面即可。
{
//nData[nP++] = pnD2[j++];
nData[nP] = pnD2[j];
++nP;
++j;
}
}
delete pnD1; //释放申请的内存空间
delete pnD2;
return true;
}
//合并的递归调用,排序[nBegin, nEnd)区间的内容
bool MergeRecursion(int nData[], int nBegin, int nEnd)
{
if (nBegin >= nEnd - 1) //已经到最小颗粒了,直接返回
{
return false;
}
int nMid = (nBegin + nEnd) / 2; //计算出他们的中间位置,便于分治
MergeRecursion(nData, nBegin, nMid); //递归调用,合并排序好左边一半
MergeRecursion(nData, nMid, nEnd); //递归调用,合并排序好右边一半
//Merge(nData, nBegin, nMid, nEnd); //将已经合并排序好的左右数据合并,时整个数据排序完成
MergeStandard(nData, nBegin, nMid, nEnd);//(用更接近标准的方法合并)
return true;
}
//合并排序
bool MergeSort(int nData[], int nNum)
{
return MergeRecursion(nData, 0, nNum); //调用递归,完成合并排序
}
int main()
{
int nData[10] = {4,10,3,8,5,6,7,4,9,2}; //创建10个数据,测试
MergeSort(nData, 10);
for (int i = 0; i < 10; ++i)
{
printf("%d ", nData[i]);
}
printf("\n");
system("pause");
return 0;
}
6. 快速排序1
#include <stdio.h>
#include <stdlib.h>
//化分区间,找到最后元素的排序位置。并返回分隔的点(即最后一数据排序的位置)。
//划分的区间是[nBegin, nEnd). pData是保存数据的指针
int Partition(int* pData, int nBeging, int nEnd)
{
int i = nBeging - 1; //分隔符号,最后nD保存在这里
--nEnd;
int nD = pData[nEnd]; //比较的数据。
int nTemp; // 交换用的临时数据
//遍历数据比较,找到nD的位置,这里注意,比较结果是,
//如果i的左边是小于等于nD的,i的右边是大于nD的
for (int j = nBeging; j < nEnd; ++j)
{
if (pData[j] <= nD) //如果数据比要比较的小,则在该数据的左边,与i+1交换
{
++i; //小于nD的数据多一个,所以要加1,i的左边数据都比nD小
nTemp = pData[i]; //交换数据
pData[i] = pData[j];
pData[j] = nTemp;
}
}
//最后不要忘了吧nD和i+1交换,因为这里就是nD的位置咯。
++i;
pData[nEnd] = pData[i];
pData[i] = nD;
return i; //返回nD的位置,就是分割的位置。
}
//排序的递归调用。
int QuickSortRecursion(int* pData, int nBeging, int nEnd)
{
if (nBeging >= nEnd -1) //如果区域不存在或只有一个数据则不递归排序
{
return 1;
}
//这里因为分割的时候,分割点处的数据就是排序中他的位置。
//也就是说他的左边的数据都小于等于他,他右边的数据都大于他。
//所以他不在递归调用的数据中。
int i = Partition(pData, nBeging, nEnd); //找到分割点
QuickSortRecursion(pData, nBeging, i); //递归左边的排序
QuickSortRecursion(pData, i + 1, nEnd); //递归右边的排序
return 1;
}
//快速排序
int QuickSort(int* pData, int nLen)
{
//递归调用,快速排序。
QuickSortRecursion(pData, 0, nLen);
return 1;
}
int main()
{
int nData[10] = {5,9,3,2,1,6,20,45,88,75}; //测试数据
QuickSort(nData, 10); //调用快速排序
for (int i = 0; i < 10; ++i) //输出结果
{
printf("%d ", nData[i]);
}
printf("\n");
system("pause");
return 0;
}
7. 快速排序2
// 快速排序的随机化版本,他和标准的版本没有什么质的区别,因为快速排序的最坏情况和平均情况效率差太远,所以用随机的版本来写一个更大概率平均的快速排序
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
//化分区间,找到最后元素的排序位置。并返回分隔的点(即最后一数据排序的位置)。
//划分的区间是[nBegin, nEnd). pData是保存数据的指针
int Partition(int* pData, int nBeging, int nEnd)
{
int i = nBeging - 1; //分隔符号,最后nD保存在这里
--nEnd;
int nD = pData[nEnd]; //比较的数据。
int nTemp; // 交换用的临时数据
//遍历数据比较,找到nD的位置,这里注意,比较结果是,
//如果i的左边是小于等于nD的,i的右边是大于nD的
for (int j = nBeging; j < nEnd; ++j)
{
if (pData[j] <= nD) //如果数据比要比较的小,则在该数据的左边,与i+1交换
{
++i; //++i小于nD的数据多一个,所以要加1
nTemp = pData[i]; //交换数据
pData[i] = pData[j];
pData[j] = nTemp;
}
}
//最后不要忘了吧nD和i+1交换,因为这里就是nD的位置咯。
++i;
pData[nEnd] = pData[i];
pData[i] = nD;
return i; //返回nD的位置,就是分割的位置。
}
int RandomPartition(int* pData, int nBeging, int nEnd)
{
int i = nBeging + rand() % (nEnd - nBeging - 1);
int nTemp = pData[i];
pData[i] = pData[nEnd - 1];
pData[nEnd - 1] = nTemp;
return Partition(pData, nBeging, nEnd);
}
//排序的递归调用。
int QuickSortRecursion(int* pData, int nBeging, int nEnd)
{
if (nBeging >= nEnd -1) //如果区域不存在或只有一个数据则不递归排序
{
return 1;
}
//这里因为分割的时候,分割点处的数据就是排序中他的位置。
//也就是说他的左边的数据都小于等于他,他右边的数据都大于他。
//所以他不在递归调用的数据中。
int i = RandomPartition(pData, nBeging, nEnd); //找到分割点
QuickSortRecursion(pData, nBeging, i); //递归左边的排序
QuickSortRecursion(pData, i + 1, nEnd); //递归右边的排序
return 1;
}
//快速排序
int QuickSort(int* pData, int nLen)
{
srand(time(NULL));
//递归调用,快速排序。
QuickSortRecursion(pData, 0, nLen);
return 1;
}
int main()
{
int nData[10] = {5,9,3,2,1,6,20,45,88,75}; //测试数据
QuickSort(nData, 10); //调用快速排序
for (int i = 0; i < 10; ++i) //输出结果
{
printf("%d ", nData[i]);
}
printf("\n");
system("pause");
return 0;
}
8. 快速排序3
#include <stdio.h>
#include <stdlib.h>
//化分区间,找到最后元素的排序位置。并返回分隔的点(即最后一数据排序的位置)。
//划分的区间是[nBegin, nEnd). pData是保存数据的指针
int Partition(int* pData, int nBeging, int nEnd)
{
//这里是和hoare的最初快速排序的版本。
int x = pData[nBeging];
--nBeging;
while (nBeging < nEnd)
{
--nEnd;
//从后向前,找到比X小的元素位置
while(pData[nEnd] > x)
{
--nEnd;
}
//小的区域增加,找到一个不比x小的元素
++nBeging;
while (pData[nBeging] < x)
{
++nBeging;
}
//把不比x小的元素存放在大的区域内。nEnd刚好预留了此位置。
if (nBeging < nEnd)
{
int nTemp = pData[nBeging];
pData[nBeging] = pData[nEnd];
pData[nEnd] = nTemp;
}
else
{
break;
}
}
//注意这里并没有给分割点排序,只是做了分割,办证nEnd+1的左边小于
//nEnd + 1的右边。
return nEnd + 1; //返回nD的位置,就是分割的位置。
}
//排序的递归调用。
int QuickSortRecursion(int* pData, int nBeging, int nEnd)
{
if (nBeging >= nEnd -1) //如果区域不存在或只有一个数据则不递归排序
{
return 1;
}
//也就是说他的左边的数据都小于等于他,他右边的数据都大于他。
//所以他不在递归调用的数据中。
int i = Partition(pData, nBeging, nEnd); //找到分割点
QuickSortRecursion(pData, nBeging, i); //递归左边的排序
QuickSortRecursion(pData, i, nEnd); //递归右边的排序
return 1;
}
//快速排序
int QuickSort(int* pData, int nLen)
{
//递归调用,快速排序。
QuickSortRecursion(pData, 0, nLen);
return 1;
}
int main()
{
int nData[10] = {5,9,3,2,1,6,20,45,88,75}; //测试数据
QuickSort(nData, 10); //调用快速排序
for (int i = 0; i < 10; ++i) //输出结果
{
printf("%d ", nData[i]);
}
printf("\n");
system("pause");
return 0;
}
9. 快速排序4
// 这是最初版本的和随机版本的结合,我也修改了一下最初版本的小点东西,思路还是最初版的思路,只是我把分割符中的数据排好了而已。
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
//化分区间,找到最后元素的排序位置。并返回分隔的点(即最后一数据排序的位置)。
//划分的区间是[nBegin, nEnd). pData是保存数据的指针
int Partition(int* pData, int nBeging, int nEnd)
{
int i = nBeging + rand()%(nBeging - nEnd);
//这里是和hoare的思路写的,和原版本不是完全一样,思路是一样的。
int x = pData[i];
pData[i] = pData[nBeging];
pData[nBeging] = x;
//int x = pData[nBeging];
--nEnd;
while (nBeging < nEnd)
{
//从后向前,找到比X小的元素位置
while(pData[nEnd] > x)
{
--nEnd;
}
//把x小的元素位置提前,nBegin处刚好能保存比x小的元素
if (nBeging < nEnd)
{
pData[nBeging] = pData[nEnd];
pData[nEnd] = x; //这里是为了做一个哨兵,防止小区域增加时越界。
++nBeging;
}
//小的区域增加,找到一个不比x小的元素。
while (pData[nBeging] < x)
{
++nBeging;
}
//把不比x小的元素存放在大的区域内。nEnd刚好预留了此位置。
if (nBeging < nEnd)
{
pData[nEnd] = pData[nBeging];
--nEnd;
}
}
pData[nBeging] = x; //这里一定要赋值,不然如果是nEnd退出循环,他是保存着以前的大值,会出错。
return nBeging; //返回nD的位置,就是分割的位置。
}
//排序的递归调用。
int QuickSortRecursion(int* pData, int nBeging, int nEnd)
{
if (nBeging >= nEnd -1) //如果区域不存在或只有一个数据则不递归排序
{
return 1;
}
//这里因为分割的时候,分割点处的数据就是排序中他的位置。
//也就是说他的左边的数据都小于等于他,他右边的数据都大于他。
//所以他不在递归调用的数据中。
int i = Partition(pData, nBeging, nEnd); //找到分割点
QuickSortRecursion(pData, nBeging, i); //递归左边的排序
QuickSortRecursion(pData, i + 1, nEnd); //递归右边的排序
return 1;
}
//快速排序
int QuickSort(int* pData, int nLen)
{
srand((unsigned int)time(NULL));
//递归调用,快速排序。
QuickSortRecursion(pData, 0, nLen);
return 1;
}
int main()
{
int nData[10] = {2,6,3,4,1,5,7,8,10,9}; //测试数据
QuickSort(nData, 10);
for (int i = 0; i < 10; ++i)
{
printf("%d ", nData[i]);
}
printf("\n");
system("pause");
return 0;
}
10. 基数排序
#include <stdio.h>
#include <stdlib.h>
//计数排序,npRadix为对应的关键字序列,nMax是关键字的范围。npData是具体要
//排的数据,nLen是数据的范围,这里必须注意npIndex和npData对应的下标要一致
//也就是说npIndex[1] 所对应的值为npData[1]
int RadixCountSort(int* npIndex, int nMax, int* npData, int nLen)
{
//这里就不用说了,计数的排序。不过这里为了是排序稳定
//在标准的方法上做了小修改。
int* pnCount = (int*)malloc(sizeof(int)* nMax); //保存计数的个数
for (int i = 0; i < nMax; ++i)
{
pnCount[i] = 0;
}
for (i = 0; i < nLen; ++i) //初始化计数个数
{
++pnCount[npIndex[i]];
}
for (i = 1; i < 10; ++i) //确定不大于该位置的个数。
{
pnCount[i] += pnCount[i - 1];
}
int * pnSort = (int*)malloc(sizeof(int) * nLen); //存放零时的排序结果。
//注意:这里i是从nLen-1到0的顺序排序的,是为了使排序稳定。
for (i = nLen - 1; i >= 0; --i)
{
--pnCount[npIndex[i]];
pnSort[pnCount[npIndex[i]]] = npData[i];
}
for (i = 0; i < nLen; ++i) //把排序结构输入到返回的数据中。
{
npData[i] = pnSort[i];
}
free(pnSort); //记得释放资源。
free(pnCount);
return 1;
}
//基数排序
int RadixSort(int* nPData, int nLen)
{
//申请存放基数的空间
int* nDataRadix = (int*)malloc(sizeof(int) * nLen);
int nRadixBase = 1; //初始化倍数基数为1
bool nIsOk = false; //设置完成排序为false
//循环,知道排序完成
while (!nIsOk)
{
nIsOk = true;
nRadixBase *= 10;
for (int i = 0; i < nLen; ++i)
{
nDataRadix[i] = nPData[i] % nRadixBase;
nDataRadix[i] /= nRadixBase / 10;
if (nDataRadix[i] > 0)
{
nIsOk = false;
}
}
if (nIsOk) //如果所有的基数都为0,认为排序完成,就是已经判断到最高位了。
{
break;
}
RadixCountSort(nDataRadix, 10, nPData, nLen);
}
free(nDataRadix);
return 1;
}
int main()
{
//测试基数排序。
int nData[10] = {123,5264,9513,854,9639,1985,159,3654,8521,8888};
RadixSort(nData, 10);
for (int i = 0; i < 10; ++i)
{
printf("%d ", nData[i]);
}
printf("\n");
system("pause");
return 0;
}
11. 选择排序
#include <stdio.h>
#include <stdlib.h>
//选择排序, pnData要排序的数据, nLen数据的个数
int SelectSort(int* pnData, int nLen)
{
//i从[0,nLen-1)开始选择,确定第i个元素
for (int i = 0; i < nLen - 1; ++i)
{
int nIndex = i;
//遍历剩余数据,选择出当前最小的数据
for (int j = i + 1; j < nLen; ++j)
{
if (pnData[j] < pnData[nIndex])
{
nIndex = j;
}
}
//如果当前最小数据索引不是i,也就是说排在i位置的数据在nIndex处
if (nIndex != i)
{
//交换数据,确定i位置的数据。
int nTemp = pnData[i];
pnData[i] = pnData[nIndex];
pnData[nIndex] = nTemp;
}
}
return 1;
}
int main()
{
int nData[10] = {4,10,9,8,7,6,5,4,3,2}; //创建10个数据,测试
SelectSort(nData, 10); //调用选择排序
for (int i = 0; i < 10; ++i)
{
printf("%d ", nData[i]);
}
printf("\n");
system("pause");
return 0;
}
12. 希尔排序
#include <stdio.h>
#include <stdlib.h>
//对单个组排序
int SortGroup(int* pnData, int nLen, int nBegin,int nStep)
{
for (int i = nBegin + nStep; i < nLen; i += nStep)
{
//寻找i元素的位置,
for (int j = nBegin; j < i; j+= nStep)
{
//如果比他小,则这里就是他的位置了
if (pnData[i] < pnData[j])
{
int nTemp = pnData[i];
for (int k = i; k > j; k -= nStep)
{
pnData[k] = pnData[k - nStep];
}
pnData[j] = nTemp;
}
}
}
return 1;
}
//希尔排序, pnData要排序的数据, nLen数据的个数
int ShellSort(int* pnData, int nLen)
{
//以nStep分组,nStep每次减为原来的一半。
for (int nStep = nLen / 2; nStep > 0; nStep /= 2)
{
//对每个组进行排序
for (int i = 0 ;i < nStep; ++i)
{
SortGroup(pnData, nLen, i, nStep);
}
}
return 1;
}
int main()
{
int nData[10] = {4,10,9,8,7,6,5,4,3,2}; //创建10个数据,测试
ShellSort(nData, 10); //调用希尔排序
for (int i = 0; i < 10; ++i)
{
printf("%d ", nData[i]);
}
printf("\n");
system("pause");
return 0;
}
以上源码来源:
http://www.cppblog.com/shongbee2/archive/2009/04/25/81058.html
13.二分查找算法:
1) 递归方法实现:
/*在下届为low,上界为high的数组a中折半查找数据元素x*/
int BSearch(int a[],int x,int low,int high)
{
int mid;
if(low>high)
return -1;
mid=(low+high)/2;
if(x==a[mid])
return mid;
if(x<a[mid])
return(BSearch(a,x,low,mid-1));
else
return(BSearch(a,x,mid+1,high));
}
2) 非递归方法实现:
//2) 非递归方法实现:
int BSearch1(int a[], int key,int n)
{
int low,high,mid;
low=0;
high=n-1;
while(low<=high)
{
mid=(low+high)/2;
if(a[mid]==key)
return mid;
else
if(a[mid]<key)
low=mid+1;
else
high=mid-1;
}
return -1;
}