排序查找算法源码

来源:互联网 发布:windows 位置不可用 编辑:程序博客网 时间:2024/05/22 17:09

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;
}

 

 

原创粉丝点击