最近重新学习了一遍排序算法,写了几种排序算法这里分享给大家
1.优化版的冒泡排序
#include<stdio.h>
void BubblseSort(int arr[],int nLength)
{
if(arr == NULL || nLength <= 0)return;
int i;
int j;
int nFlag;
int nCount = 0;
for(i = 0;i<nLength-1;i++)
{
nFlag = 0;
for(j = 0;j<nLength-1-i;j++)
{
if(arr[j] > arr[j+1])
{
arr[j] = arr[j]^arr[j+1];
arr[j+1] = arr[j]^arr[j+1];
arr[j] = arr[j]^arr[j+1];
nFlag = j+1;
}
nCount++;
}
if(nFlag == 0)
{
break;
}
i = nLength-nFlag-1;
}
printf("%d\n",nCount);
}
int main()
{
int arr[] = {8,2,19,28,0,37,87,112,231};
BubblseSort(arr,sizeof(arr)/sizeof(arr[0]));
int i;
for(i = 0;i<sizeof(arr)/sizeof(arr[0]);i++)
{
printf("%d ",arr[i]);
}
return 0;
}
2.选择排序
#include<stdio.h>
void SelectSort(int arr[],int nLength)
{
if(arr == NULL || nLength <= 0)return;
int i;
int j;
int nMin;
for(i = 0;i<nLength-1;i++)
{
nMin = i;
for(j = i+1;j<nLength;j++)
{
if(arr[j] < arr[nMin])
{
nMin = j;
}
}
if(i != nMin)
{
arr[i] = arr[nMin]^arr[i];
arr[nMin] = arr[nMin]^arr[i];
arr[i] = arr[nMin]^arr[i];
}
}
}
int main()
{
int arr[] = {8,2,19,28,0,37,87,112,231};
SelectSort(arr,sizeof(arr)/sizeof(arr[0]));
int i;
for(i = 0;i<sizeof(arr)/sizeof(arr[0]);i++)
{
printf("%d ",arr[i]);
}
return 0;
}
3.插入排序
#include<stdio.h>
void InsertSort(int arr[],int nLength)
{
if(arr == NULL || nLength <= 0)return;
int i;
int j;
int temp;
for(i = 1;i<nLength;i++)
{
j = i-1;//有序的最后位置
temp = arr[i]; //无序的第一个元素
//倒序遍历有序数组
while(temp < arr[j] && j >= 0)
{
//向后移动
arr[j+1] = arr[j];
j--;
}
//无序元素放入
arr[j+1] = temp;
}
}
int main()
{
int arr[] = {8,2,19,28,0,37,87,112,231};
InsertSort(arr,sizeof(arr)/sizeof(arr[0]));
int i;
for(i = 0;i<sizeof(arr)/sizeof(arr[0]);i++)
{
printf("%d ",arr[i]);
}
return 0;
}
4.计数排序
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
void CountSort(int arr[],int nLength)
{
if(arr == NULL || nLength <= 0)return;
//找到最大值 最小值
int i;
int nMax;
int nMin;
nMax = arr[0];
nMin = arr[0];
for(i = 1;i<nLength;i++)
{
if(arr[i] > nMax)
{
nMax = arr[i];
}
if(arr[i] < nMin)
{
nMin = arr[i];
}
}
//申请计数数组
int *pCount = NULL;
pCount = (int*)malloc(sizeof(int)*(nMax-nMin+1));
memset(pCount,0,sizeof(int)*(nMax-nMin+1));
//计数
for(i = 0;i< nLength;i++)
{
pCount[arr[i]-nMin]++;
}
//排序
int j = 0;
for(i = 0;i<nMax-nMin+1;i++)
{
while(pCount[i] != 0)
{
arr[j] = i+nMin;
j++;
pCount[i]--;
}
}
//释放
free(pCount);
pCount = NULL;
}
int main()
{
int arr[] = {8,2,9,8,0,3,8,2,3};
CountSort(arr,sizeof(arr)/sizeof(arr[0]));
int i;
for(i = 0;i<sizeof(arr)/sizeof(arr[0]);i++)
{
printf("%d ",arr[i]);
}
return 0;
}
5.快速排序
#include<stdio.h>
int Sort(int arr[],int nLow,int nHigh)
{
int temp;
temp = arr[nLow];
while(nLow < nHigh)
{
//从后向前找比标准值小的
while(nHigh > nLow)
{
if(arr[nHigh] < temp)
{
//放前面的坑
arr[nLow] = arr[nHigh];
nLow++;
break;
}
nHigh--;
}
//从前向后找比标准值大的
while(nLow < nHigh)
{
if(arr[nLow] > temp)
{
//放后面的坑
arr[nHigh] = arr[nLow];
nHigh--;
break;
}
nLow++;
}
}
//标准值放入
arr[nLow] = temp;
return nLow;
}
int Sort2(int arr[],int nLow,int nHigh)
{
int nSmall = nLow-1;
for(nLow ;nLow < nHigh;nLow++)
{
if(arr[nLow] < arr[nHigh])
{
//用小区间的下一位置和当前元素交换
if(++nSmall != nLow)
{
arr[nSmall] = arr[nSmall]^arr[nLow];
arr[nLow] = arr[nSmall]^arr[nLow];
arr[nSmall] = arr[nSmall]^arr[nLow];
}
}
}
//标准值放入
if(++nSmall != nHigh)
{
arr[nSmall] = arr[nSmall]^arr[nHigh];
arr[nHigh] = arr[nSmall]^arr[nHigh];
arr[nSmall] = arr[nSmall]^arr[nHigh];
}
return nSmall;
}
void QuickSort(int arr[],int nLow,int nHigh)
{
if(arr == NULL || nHigh <= nLow)return;
//找标准值位置
int nStandard;
nStandard = Sort2(arr,nLow,nHigh);
//根据标准值位置 分成两部分
QuickSort(arr,nLow,nStandard-1);
QuickSort(arr,nStandard+1,nHigh);
}
int main()
{
int arr[] = {8,2,19,28,0,37,87,112,231};
QuickSort(arr,0,sizeof(arr)/sizeof(arr[0])-1);
int i;
for(i = 0;i<sizeof(arr)/sizeof(arr[0]);i++)
{
printf("%d ",arr[i]);
}
return 0;
}
6.希尔排序
#include<stdio.h>
void ShellSort(int arr[],int nLength)
{
if(arr == NULL || nLength <= 0)return;
int nGap;
int i;
int j;
int k;
int temp;
for(nGap = nLength/2;nGap>=1;nGap/=2)
{
//组
for(i =0;i<nGap;i++)
{
//各组之内插入排序
for(j = i+nGap;j < nLength;j+=nGap)
{
k = j-nGap;//有序的最后一个
temp = arr[j]; //无序元素
while(temp < arr[k] && k>=i)
{
arr[k+nGap] = arr[k];
k-=nGap;
}
//元素放入
arr[k+nGap] = temp;
}
}
}
}
int main()
{
int arr[] = {8,2,19,28,0,37,87,112,231};
ShellSort(arr,sizeof(arr)/sizeof(arr[0]));
int i;
for(i = 0;i<sizeof(arr)/sizeof(arr[0]);i++)
{
printf("%d ",arr[i]);
}
return 0;
}
7.归并排序
#include<stdio.h>
#include<stdlib.h>
void Sort(int arr[],int nLow,int nHigh)
{
int nBegin1;
int nBegin2;
int nEnd1;
int nEnd2;
nBegin1 = nLow;
nEnd1 = nLow+(nHigh-nLow)/2;
nBegin2 = nEnd1+1;
nEnd2 = nHigh;
int *pTemp = NULL;
pTemp = (int*)malloc(sizeof(int)*(nHigh-nLow+1));
int i = 0;
//合并
while(nBegin1 <= nEnd1 && nBegin2 <= nEnd2)
{
if(arr[nBegin2] < arr[nBegin1])
{
pTemp[i] = arr[nBegin2];
i++;
nBegin2++;
}
else
{
pTemp[i] = arr[nBegin1];
i++;
nBegin1++;
}
}
//将有剩余的数组元素继续放
while(nBegin1 <= nEnd1)
{
pTemp[i] = arr[nBegin1];
i++;
nBegin1++;
}
while(nBegin2 <= nEnd2)
{
pTemp[i] = arr[nBegin2];
i++;
nBegin2++;
}
//放回原数组
for(i = 0;i<nHigh-nLow+1;i++)
{
arr[nLow+i] = pTemp[i];
}
//释放
free(pTemp);
pTemp = NULL;
}
void MergeSort(int arr[],int nLow,int nHigh)
{
if(arr == NULL || nLow >= nHigh)return;
int nMid;
nMid = nLow+(nHigh-nLow)/2;
//分组
MergeSort(arr,nLow,nMid);
MergeSort(arr,nMid+1,nHigh);
//合并
Sort(arr,nLow,nHigh);
}
int main()
{
int arr[] = {8,2,19,28,0,37,87,112,231};
MergeSort(arr,0,sizeof(arr)/sizeof(arr[0])-1);
int i;
for(i = 0;i<sizeof(arr)/sizeof(arr[0]);i++)
{
printf("%d ",arr[i]);
}
return 0;
}
8.堆排序
#include<stdio.h>
#define LEFT 2*nRootID+1
#define RIGHT 2*nRootID+2
void Adjust(int arr[],int nLength,int nRootID)
{
while(1)
{
//两个孩子
if(RIGHT < nLength)
{
//比较两个孩子大小
if(arr[LEFT] > arr[RIGHT])
{
//大的和父亲比较
if(arr[LEFT] > arr[nRootID])
{
arr[LEFT] = arr[LEFT]^arr[nRootID];
arr[nRootID] = arr[LEFT]^arr[nRootID];
arr[LEFT] = arr[LEFT]^arr[nRootID];
nRootID = LEFT;
continue;
}
break;
}
else
{
if(arr[RIGHT] > arr[nRootID])
{
arr[RIGHT] = arr[RIGHT]^arr[nRootID];
arr[nRootID] = arr[RIGHT]^arr[nRootID];
arr[RIGHT] = arr[RIGHT]^arr[nRootID];
nRootID = RIGHT;
continue;
}
break;
}
}
//一个孩子
else if(LEFT < nLength)
{
if(arr[LEFT] > arr[nRootID])
{
arr[LEFT] = arr[LEFT]^arr[nRootID];
arr[nRootID] = arr[LEFT]^arr[nRootID];
arr[LEFT] = arr[LEFT]^arr[nRootID];
nRootID = LEFT;
continue;
}
break;
}
//无孩子
else
{
break;
}
}
}
void HeapSort(int arr[],int nLength)
{
if(arr == NULL || nLength <= 0)return;
//建初始堆
int i;
for(i = nLength/2-1;i>=0;i--)
{
//调整
Adjust(arr,nLength,i);
}
//排序
for(i = nLength-1;i>0;i--)
{
//交换
arr[0] = arr[0]^arr[i];
arr[i] = arr[0]^arr[i];
arr[0] = arr[0]^arr[i];
//调整堆顶
Adjust(arr,i,0);
}
}
int main()
{
int arr[] = {10,5,91,9,2,36,108,222,9100};
HeapSort(arr,sizeof(arr)/sizeof(arr[0]));
int i;
for(i = 0;i<sizeof(arr)/sizeof(arr[0]);i++)
{
printf("%d ",arr[i]);
}
return 0;
}
9.桶排序
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
typedef struct bucket
{
int nValue;
struct bucket *pNext;
struct bucket *pPre;
}Bucket;
void Sort(Bucket *pHead)
{
if(pHead == NULL || pHead->pNext == NULL)return;
Bucket *pSort = NULL;
Bucket *pUnsort = NULL;
int temp;
pUnsort = pHead->pNext;
while(pUnsort != NULL)
{
pSort = pUnsort->pPre;
temp = pUnsort->nValue;
while(pSort != NULL && pSort->nValue > temp)
{
pSort->pNext->nValue = pSort->nValue;
pSort = pSort->pPre;
}
if(pSort == NULL)
{
pHead->nValue = temp;
}
else
{
pSort->pNext->nValue = temp;
}
pUnsort = pUnsort->pNext;
}
}
void BucketSort(int arr[],int nLength)
{
if(arr == NULL || nLength <= 0)return;
//找最大值 最小值
int nMin;
int nMax;
nMax = arr[0];
nMin = arr[0];
int i;
for(i = 1;i<nLength;i++)
{
if(arr[i] > nMax)
{
nMax = arr[i];
}
if(arr[i] < nMin)
{
nMin = arr[i];
}
}
//计算位数
int nCount = 1;
int nNum = nMin;
while(nNum)
{
nCount*=10;
nNum/=10;
}
nCount/=10;
int nMinIndex;
int nMaxIndex;
nMinIndex = nMin/nCount;
nMaxIndex = nMax/nCount;
//桶
Bucket **pBucket = (Bucket**)malloc(sizeof(Bucket*)*(nMaxIndex-nMinIndex+1));
memset(pBucket,0,sizeof(Bucket*)*(nMaxIndex-nMinIndex+1));
//入桶
Bucket *pTemp = NULL;
int nIndex;
for(i = 0;i<nLength;i++)
{
pTemp = (Bucket*)malloc(sizeof(Bucket));
pTemp->nValue = arr[i];
pTemp->pNext = NULL;
pTemp->pPre = NULL;
nIndex = arr[i]/nCount - nMinIndex ;
//添加
pTemp->pNext = pBucket[nIndex];
if(pBucket[nIndex] != NULL)
{
pBucket[nIndex]->pPre = pTemp;
}
pBucket[nIndex] = pTemp;
}
//各桶之内排序
for(i = 0;i<nMaxIndex-nMinIndex+1;i++)
{
Sort(pBucket[i]);
}
//元素放回原数组
int j = 0;
for(i = 0;i<nMaxIndex-nMinIndex+1;i++)
{
pTemp = pBucket[i];
while(pTemp)
{
arr[j] = pTemp->nValue;
j++;
pTemp = pTemp->pNext;
}
}
//释放
Bucket *pDel = NULL;
for(i = 0;i<nMaxIndex-nMinIndex+1;i++)
{
pTemp = pBucket[i];
while(pTemp)
{
pDel = pTemp;
pTemp = pTemp->pNext;
free(pDel);
pDel = NULL;
}
}
free(pBucket);
pBucket = NULL;
}
int main()
{
int arr[] = {104,335,961,922,452,736,108,222,910};
BucketSort(arr,sizeof(arr)/sizeof(arr[0]));
int i;
for(i = 0;i<sizeof(arr)/sizeof(arr[0]);i++)
{
printf("%d ",arr[i]);
}
return 0;
}
10.基数排序
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
typedef struct radix
{
int nValue;
struct radix *pNext;
}Radix;
void Sort(int arr[],int nLoopTimes,Radix **pRadix,int nBegin)
{
int nBase = 1;
//计算被除基数
while(nBegin > 1)
{
nBase*=10;
nBegin--;
}
Radix *pTemp = NULL;
int nIndex;
int i;
Radix *pNode = NULL;
for(i = 0;i<nLoopTimes;i++)
{
nIndex = arr[i]/nBase%10;
pTemp = (Radix*)malloc(sizeof(Radix));
pTemp->nValue = arr[i];
pTemp->pNext = NULL;
//尾添加
if(pRadix[nIndex] == NULL)
{
pRadix[nIndex] = pTemp;
}
else
{
pNode = pRadix[nIndex];
while(pNode->pNext != NULL)
{
pNode = pNode->pNext;
}
pNode->pNext = pTemp;
}
}
//数据放回原数组
int j = 0;
for(i = 0;i<10;i++)
{
pTemp = pRadix[i];
while(pTemp)
{
arr[j] = pTemp->nValue;
j++;
pTemp = pTemp->pNext;
}
}
//释放小链表
for(i = 0;i<10;i++)
{
pTemp = pRadix[i];
while(pTemp)
{
pNode = pTemp;
pTemp = pTemp->pNext;
free(pNode);
pNode = NULL;
}
}
//清空表头
memset(pRadix,0,sizeof(Radix*)*10);
}
void RadixSort(int arr[],int nLength)
{
if(arr == NULL || nLength <= 0)return;
//最大值
int i;
int nMax;
nMax = arr[0];
for(i =1;i<nLength;i++)
{
if(arr[i] > nMax)
{
nMax = arr[i];
}
}
//计算最大值位数
int nLoopTimes = 0;
while(nMax)
{
nMax/=10;
nLoopTimes++;
}
Radix **pRadix = (Radix**)malloc(sizeof(Radix*)*10);
memset(pRadix,0,sizeof(Radix*)*10);
//按照各位进行入桶
for(i = 1;i<=nLoopTimes;i++)
{
Sort(arr,nLength,pRadix,i);
}
//释放
free(pRadix);
pRadix = NULL;
}
int main()
{
int arr[] = {10,5,91,9,2,36,108,222,9100};
RadixSort(arr,sizeof(arr)/sizeof(arr[0]));
int i;
for(i = 0;i<sizeof(arr)/sizeof(arr[0]);i++)
{
printf("%d ",arr[i]);
}
return 0;
}