排序算法。

快速排序: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;
} 
相关推荐
数据分析螺丝钉2 分钟前
力扣第218题“天际线问题”
经验分享·python·算法·leetcode·面试
半截詩1 小时前
力扣Hot100-24两两交换链表中的节点(三指针)
算法
2401_857636391 小时前
Scala中的尾递归优化:深入探索与实践
大数据·算法·scala
点云侠1 小时前
matlab 干涉图仿真
开发语言·人工智能·算法·计算机视觉·matlab
2401_857638032 小时前
【深度解析】滑动窗口:目标检测算法的基石
人工智能·算法·目标检测
Czi橙2 小时前
玩玩快速冥(LeetCode50题与70题以及联系斐波那契)
java·算法·快速幂·斐波那契
Python大数据分析@2 小时前
用Python实现的10种聚类算法汇总
python·算法·聚类
橘子味的小橙3 小时前
leetCode-hot100-动态规划专题
java·算法·leetcode·动态规划
沿街3 小时前
【集成学习】基于python的stacking回归预测
人工智能·python·算法·机器学习·回归·集成学习
CylMK3 小时前
NOI大纲——普及组——二叉搜索树
开发语言·数据结构·c++·算法