快速排序:QuickSort
选标准值,将比标准值小的放在其左侧,将比标准值大的放在其右侧,左右两部分分别重复以上操作
1.挖坑填补法
拆东墙补西墙
先把第一个数拿出来用temp储存 然后从最后面遍历 找到比temp小的放到第一个位置 然后再从前面第二个开始遍历找比temp大的放在后面的空位上 重复操作 直到end和begin在一块 然后再在temp两边分别重复操作
#include<stdio.h>
int Find(int arr[],int nBegin,int nEnd)
{
int temp = arr[nBegin];
while(nBegin < nEnd)
{
//从后向前找比标准值小的
while(nEnd > nBegin)
{
if(arr[nEnd] < temp)
{
arr[nBegin] = arr[nEnd];
nBegin++;
break;
}
nEnd--;
}
//从前往后找比标准值大的
while(nBegin < nEnd)
{
if(arr[nBegin] > temp)
{
arr[nEnd] = arr[nBegin];
nEnd--;
break;
}
nBegin++;
}
}
//标准值放入
arr[nBegin] = temp;
return nBegin;
}
void QuickSort(int arr[],int nBegin,int nEnd)
{
if(arr == NULL || nBegin >= nEnd)return;
//确定标准值最终位置
int nStandard;
nStandard = Find(arr,nBegin,nEnd);
//将数据分成两部分 分别重复以上操作
QuickSort(arr,nBegin,nStandard-1);
QuickSort(arr,nStandard+1,nEnd);
}
void Print(int arr[],int length)
{
if(arr == NULL || length <=0)return;
int i;
for(int i=0;i<length;i++)
{
printf("%d ",arr[i]);
}
printf("\n");
}
int main()
{
int arr[] = {2,4,7,1,5,14,89,13,2};
QuickSort(arr,0,sizeof(arr)/sizeof(arr[0])-1);
Print(arr,sizeof(arr)/sizeof(arr[0]));
return 0;
}
2.区间分割法
small指向begin-1 begin从前向后遍历 遇见比end小的 就交换small+1与begin 最终将小于10的全放在一边
若 a = i++; 则等价于 a=i;i=i+1; 而 a = ++i; 则等价于 i=i+1;a=i;
#include<stdio.h>
int Find(int arr[],int nBegin,int nEnd)
{
int nSmall = nBegin-1;
for(nBegin;nBegin < nEnd;nBegin++)
{
if(arr[nBegin] < arr[nEnd])
{
if(++nSmall != nBegin)
{
arr[nSmall] = arr[nSmall]^arr[nBegin];
arr[nBegin] = arr[nSmall]^arr[nBegin];
arr[nSmall] = arr[nSmall]^arr[nBegin];
}
}
}
//将标准值放入
if(++nSmall != nEnd)
{
arr[nSmall] = arr[nSmall]^arr[nEnd];
arr[nEnd] = arr[nSmall]^arr[nEnd];
arr[nSmall] = arr[nSmall]^arr[nEnd];
}
return nSmall;
}
void QuickSort(int arr[],int nBegin,int nEnd)
{
if(arr == NULL || nBegin >= nEnd)return;
//确定标准值最终位置
int nStandard;
nStandard = Find(arr,nBegin,nEnd);
//将数据分成两部分 分别重复以上操作
QuickSort(arr,nBegin,nStandard-1);
QuickSort(arr,nStandard+1,nEnd);
}
void Print(int arr[],int length)
{
if(arr == NULL || length <=0)return;
int i;
for(int i=0;i<length;i++)
{
printf("%d ",arr[i]);
}
printf("\n");
}
int main()
{
int arr[] = {2,4,7,1,5,14,89,13,2};
QuickSort(arr,0,sizeof(arr)/sizeof(arr[0])-1);
Print(arr,sizeof(arr)/sizeof(arr[0]));
return 0;
}
MergeSort: 归并排序
将多个有序数组进行合并
#include<stdio.h>
#include<stdlib.h>
void Merge(int arr[],int nBegin,int nEnd)
{
int nBegin1 = nBegin;
int nEnd1 = nBegin+(nEnd-nBegin)/2;
int nBegin2 = nEnd1+1;
int nEnd2 = nEnd;
int *pTemp =NULL;
pTemp = (int*)malloc(sizeof(int)*(nEnd-nBegin+1));
int i=0;
//遍历两个数组
while(nBegin1 <= nEnd1 && nBegin2 <= nEnd2)
{
if(arr[nBegin2] < arr[nBegin1])
{
pTemp[i++] = arr[nBegin2++];
}
else
{
pTemp[i++] = arr[nBegin1++];
}
}
//将有剩余的数组元素放置
while(nBegin1 <= nEnd1)
{
pTemp[i++] = arr[nBegin1++];
}
while(nBegin2 <= nEnd2)
{
pTemp[i++] = arr[nBegin2++];
}
//放回
for(int i=0;i<nEnd-nBegin+1;i++)
{
arr[nBegin+i] = pTemp[i];
}
free(pTemp);
pTemp = NULL;
}
void MergeSort(int arr[],int nBegin,int nEnd)
{
if(arr == NULL || nBegin >= nEnd)return;
//分割
int nMid = nBegin + (nEnd-nBegin)/2;
MergeSort(arr,nBegin,nMid);
MergeSort(arr,nMid+1,nEnd);
//合并
Merge(arr,nBegin,nEnd);
}
void Print(int arr[],int length)
{
if(arr == NULL || length <=0)return;
int i;
for(int i=0;i<length;i++)
{
printf("%d ",arr[i]);
}
printf("\n");
}
int main()
{
int arr[] = {2,4,7,1,5,14,89,13,2};
MergeSort(arr,0,sizeof(arr)/sizeof(arr[0])-1);
Print(arr,sizeof(arr)/sizeof(arr[0]));
return 0;
}
冒泡排序:BubbleSort
相邻两个元素进行大小比较,如果前一个比后一个大,则二者发生交换
第一横:8和6比 8比6大 交换 8和3比 8比3大 交换 8和12比 没12大 不动 12和1比 比12大交换 12和7比 比12大交换 12没15大 不动
第二横;6和3比。。。。。。。
#include<stdio.h>
void BubbleSort(int arr[],int length)
{
if(arr == NULL || length<=0)return;
int i;
int j;
for(int i=0;i<length-1;i++) //总排n-1回
{
for(int j=0;j<length-i-1;j++) //每次固定一个大的,然后俩俩比较再-1
{
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];
}
}
}
}
void Print(int arr[],int length)
{
if(arr == NULL || length <=0)return;
int i;
for(int i=0;i<length;i++)
{
printf("%d ",arr[i]);
}
printf("\n");
}
int main()
{
int arr[] = {2,4,7,1,5,14,89,13,2};
BubbleSort(arr,sizeof(arr)/sizeof(arr[0]));
Print(arr,sizeof(arr)/sizeof(arr[0]));
return 0;
}
堆排序:HeapSort
先创建一个初始堆,从下到上调节父亲节点,使得每个父亲节点的值比两个孩子大,最大值就窜到最上面了,接着交换第一和最后,拿掉最后面的最大值,重复调整堆顶,拿出每个最大值
调整操作 先把两个孩子比一下取最大值跟爹比 要比爹大就交换 然后交换下来的爹也得看看他的儿子比不比他大
#include<stdio.h>
#define LEFT (2*nRootID+1)
#define RIGHT (2*nRootID+2)
void Adjust(int arr[],int length,int nRootID)
{
int MAX;
for(MAX = LEFT;MAX < length;MAX = LEFT)
{
//两个孩子
if(RIGHT < length)
{
if(arr[MAX] < arr[RIGHT])
{
MAX = RIGHT;
}
}
//比较大小
if(arr[nRootID] < arr[MAX])
{
//交换
arr[nRootID] = arr[nRootID]^arr[MAX];
arr[MAX] = arr[nRootID]^arr[MAX];
arr[nRootID] = arr[nRootID]^arr[MAX];
nRootID = MAX;
}
else
{
break;
}
}
}
void HeapSort(int arr[],int length)
{
if(arr == NULL || length <=0)return;
//建初始堆
int i;
for(i = length/2-1;i>=0;i--)
{
Adjust(arr,length,i);
}
//排序
for(i = length-1;i>0;i--)
{
//交换
arr[0] = arr[i]^arr[0];
arr[i] = arr[i]^arr[0];
arr[0] = arr[i]^arr[0];
//调整堆顶
Adjust(arr,i,0);
}
}
void Print(int arr[],int length)
{
if(arr == NULL || length <=0)return;
int i;
for(int i=0;i<length;i++)
{
printf("%d ",arr[i]);
}
printf("\n");
}
int main()
{
int arr[] = {2,4,7,1,5,14,89,13,2};
HeapSort(arr,sizeof(arr)/sizeof(arr[0]));
Print(arr,sizeof(arr)/sizeof(arr[0]));
return 0;
}
桶排序:BucketSort
数据分组,各组之内进行排序
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
typedef struct node
{
int value;
struct node *pNext;
}Bucket;
void Sort(Bucket *pHead)
{
if(pHead == NULL || pHead->pNext == NULL)return;
Bucket *pi = NULL;
Bucket *pj = NULL;
pi = pHead;
while(pi->pNext != NULL) // n-1趟
{
pj = pHead; // 每次遍历从表头开始
while(pj->pNext != NULL) // j和j的下一个进行比较 保证下一个有东西
{
if(pj->value > pj->pNext->value)
{
pj->value = pj->value^ pj->pNext->value;
pj->pNext->value = pj->value^ pj->pNext->value;
pj->value = pj->value^ pj->pNext->value;
}
pj = pj->pNext; // j++
}
pi = pi->pNext; // i++ 减少趟数
}
}
void BucketSort(int arr[],int length)
{
if(arr == NULL || length <=0)return;
//1.最大值 最小值
int nMin = arr[0];
int nMax = arr[0];
int i;
for(int i=1;i<length;i++)
{
if(arr[i] < nMin)
{
nMin = arr[i];
}
if(arr[i] > nMax)
{
nMax = arr[i];
}
}
//2.位数
int nCount = 1;
int nNum = nMax;
while(nNum)
{
nNum/=10;
nCount*=10;
}
nCount/=10; //863变100 23变10
//3.表头
int nMinIndex = nMin/nCount;
int nMaxIndex = nMax/nCount;
Bucket **pBucket = NULL;
pBucket = (Bucket**)malloc(sizeof(Bucket*)*(nMaxIndex-nMinIndex+1));
memset(pBucket,0,sizeof(Bucket*)*(nMaxIndex-nMinIndex+1));
//4.元素入桶
Bucket *pTemp = NULL;
for(int i=0;i<length;i++)
{
nNum = arr[i]/nCount-nMinIndex;
pTemp = (Bucket*)malloc(sizeof(Bucket));
pTemp->value = arr[i];
pTemp->pNext = pBucket[nNum];
pBucket[nNum] = pTemp;
}
//5.各桶之间元素排序
for(int i=0;i<nMaxIndex-nMinIndex+1;i++)
{
Sort(pBucket[i]);
}
//6.放回
nNum=0;
for(int i=0;i<nMaxIndex-nMinIndex+1;i++)
{
pTemp = pBucket[i];
while(pTemp)
{
arr[nNum] = pTemp->value;
nNum++;
pTemp = pTemp->pNext;
}
}
//7.释放
Bucket *pDel = NULL;
for(int 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;
}
void Print(int arr[],int length)
{
if(arr == NULL || length <=0)return;
int i;
for(int i=0;i<length;i++)
{
printf("%d ",arr[i]);
}
printf("\n");
}
int main()
{
int arr[] = {201,405,743,165,589,140,989,193,288};
BucketSort(arr,sizeof(arr)/sizeof(arr[0]));
Print(arr,sizeof(arr)/sizeof(arr[0]));
return 0;
}
选择排序:SelectSort
找最大值放到最后/最小值放在最前面
6和3比3大 6和9比没九大 max=9的下标 9和1比 然后一顿比 最大放在最后
#include<stdio.h>
void SelectSort(int arr[],int length)
{
if(arr == NULL || length<=0)return;
int i;
int j;
int min;
for(int i=0;i<length-1;i++)
{
min=i;
for(int j=i+1;j<length;j++)
{
if(arr[j]<arr[min])
{
min=j;
}
}
//最小值放入最前面
if(min!= i)
{
arr[i]=arr[i]^arr[min];
arr[min]=arr[i]^arr[min];
arr[i]=arr[i]^arr[min];
}
}
}
void Print(int arr[],int length)
{
if(arr == NULL || length <=0)return;
int i;
for(int i=0;i<length;i++)
{
printf("%d ",arr[i]);
}
printf("\n");
}
int main()
{
int arr[] = {2,4,7,1,5,14,89,13,2};
SelectSort(arr,sizeof(arr)/sizeof(arr[0]));
Print(arr,sizeof(arr)/sizeof(arr[0]));
return 0;
}
插入排序:InsertSort
将待排序数据分成两部分,一部分有序,一部分无序,将无序元素依次插入到有序中去完成排序
#include<stdio.h>
void InsertSort(int arr[],int length)
{
if(arr == NULL || length <=0)return;
int i; //无序的第一个
int j; //有序的最后一个
int temp;
for(int i=1;i<length;i++)
{
j=i-1;
temp=arr[i]; //无序的第一个元素
while(j>=0 && temp<arr[j])
{
arr[j+1] = arr[j];
j--;
}
arr[j+1]=temp;
}
}
void Print(int arr[],int length)
{
if(arr == NULL || length <=0)return;
int i;
for(int i=0;i<length;i++)
{
printf("%d ",arr[i]);
}
printf("\n");
}
int main()
{
int arr[] = {2,4,7,1,5,14,89,13,2};
InsertSort(arr,sizeof(arr)/sizeof(arr[0]));
Print(arr,sizeof(arr)/sizeof(arr[0]));
return 0;
}
希尔排序:ShellSort
将数据分组,各组之内插入排序,比原有插入排序更快,适合大量数据,不常用。
计数排序:CountingSort
核心思想:基于非比较的排序
1.找最大值和最小值
2.计数
3.排序
#include<stdio.h>
#include<stdlib.h>
#include<string.h> //memset
void CountingSort(int arr[],int length)
{
if(arr == NULL || length <=0)return;
int i;
int min = arr[0];
int max = arr[0];
//最大值最小值查找
for(int i=1;i<length;i++)
{
if(arr[i]<min)
{
min=arr[i];
}
if(arr[i]>max)
{
max=arr[i];
}
}
//计数空间
int *pCount=NULL;
pCount=(int*)malloc(sizeof(int)*(max-min+1));
memset(pCount,0,sizeof(int)*(max-min+1));
//计数
for(i=0;i<length;i++)
{
pCount[arr[i]-min]++;
}
//名次
for(int i=1;i<max-min+1;i++)
{
pCount[i]=pCount[i]+pCount[i-1];
}
//排序
int *pNew = (int*)malloc(sizeof(int)*length);
for(i=length-1;i>=0;i--)
{
pNew[pCount[arr[i]-min]-1]=arr[i];
pCount[arr[i]-min]--;
}
//放回原数组
for(int i=0;i<length;i++)
{
arr[i]=pNew[i];
}
free(pNew);
pNew=NULL;
free(pCount);
pCount=NULL;
}
void Print(int arr[],int length)
{
if(arr == NULL || length <=0)return;
int i;
for(int i=0;i<length;i++)
{
printf("%d ",arr[i]);
}
printf("\n");
}
int main()
{
int arr[] = {2,4,7,1,5,14,89,13,2};
CountingSort(arr,sizeof(arr)/sizeof(arr[0]));
Print(arr,sizeof(arr)/sizeof(arr[0]));
return 0;
}
基数排序:RadixSort
LSD:低位优先
MSD:高位优先
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
typedef struct node
{
int value;
struct node *pNext;
}Radix;
void RadixSort(int arr[],int length)
{
if(arr == NULL || length <= 0)return;
//找最大值
int nMax = arr[0];
int i;
for(int i=1;i<length;i++)
{
if(arr[i] > nMax)
{
nMax = arr[i];
}
}
//计算最大值位数
int nCount = 0;
while(nMax)
{
nMax/=10;
nCount++;
}
//按位处理
int nLoopTimes;
int nbase = 1;
//表头
Radix **pRadix = NULL;
pRadix = (Radix**)malloc(sizeof(Radix*)*10);
memset(pRadix,0,sizeof(Radix*)*10);
for(nLoopTimes = 1;nLoopTimes<=nCount;nLoopTimes++)
{
i = nLoopTimes;
while(i>1)
{
nbase*=10;
i--;
}
//数据入组
Radix *pTemp = NULL;
for(i = 0;i<length;i++)
{
pTemp = (Radix*)malloc(sizeof(Radix));
pTemp->value = arr[i];
pTemp->pNext = NULL;
//尾添加
if(pRadix[arr[i]/nbase%10] == NULL)
{
pRadix[arr[i]/nbase%10] = pTemp;
}
else
{
Radix *pNode = pRadix[arr[i]/nbase%10];
while(pNode->pNext)
{
pNode = pNode->pNext;
}
pNode->pNext = pTemp;
}
}
//放回
int j=0;
for(i=0;i<10;i++)
{
pTemp = pRadix[i];
while(pTemp)
{
arr[j]=pTemp->value;
pTemp = pTemp->pNext;
j++;
}
}
//释放
Radix *pDel = NULL;
for(int i=0;i<10;i++)
{
pTemp = pRadix[i];
while(pTemp)
{
pDel = pTemp;
pTemp = pTemp->pNext;
free(pDel);
pDel = NULL;
}
}
//清空
memset(pRadix,0,sizeof(Radix*)*10);
}
free(pRadix);
pRadix = NULL;
}
void Print(int arr[],int length)
{
if(arr == NULL || length <=0)return;
int i;
for(int i=0;i<length;i++)
{
printf("%d ",arr[i]);
}
printf("\n");
}
int main()
{
int arr[] = {53, 3, 542, 748, 14, 214, 154, 63, 616};
RadixSort(arr,sizeof(arr)/sizeof(arr[0]));
Print(arr,sizeof(arr)/sizeof(arr[0]));
return 0;
}