八大排序(插入排序、希尔排序、选择排序、堆排序、冒泡排序、快速排序、归并排序、计数排序)

1、插入排序(升序)

void InsertSort(int* a,int n)
{
	for(int i=0;i<n-1;i++)
	{
		int end = i;
		int tmp = a[end+1];
		while(end > 0)
		{
			if(a[end]>tmp)
			{
				a[end+1] = a[end];
				--end;
			}
			else
				break;
		}
		a[end+1] = tmp;
	}
}

2、希尔排序

void ShellSort(int* a, int n)
{
	int gap = n;//gap>1时为预排序,gap=1时为直接插入排序
	while(gap>1)
	{
		gap = gap/3+1;//+1是保证最后一次排序gap是1
		for(int i=0;i<n-gap;++i)
		{
			int end = 1;
			int tmp = a[end+gap];
			while(end>0)
			{
				if(a[end]>tmp)
				{
					a[end+gap] = a[end];
					end-=gap;
				}
				else
					break;
			}
			a[end+gap] = tmp;
		}
	}
}

3、选择排序

void Swap(int* p1,int*p2)
{
	int tmp=*p1;
	*p1=*p2;
	*p2=tmp;
}
void SelectSort(int* a, int n)
{
	int begin=0,end=n-1;
	while(begin<end)
	{
		//[begin,end]选出一个最小的,选出一个最大的(下标)
		int mini=begin,maxi=end;
		for(int i=begin;i<=end;++i)
		{
			if(a[i]>a[maxi])
				maxi=i;
			if(a[i]<a[mini])
				mini=i;
		}
		Swap(&a[begin],&a[mini]);
		if(begin==maxi)
			maxi=mini;
		Swap(&a[end],&a[maxi]);
		++begin;
		--end;
	}
}

4、堆排序(排升序,建大堆)

void AdjustDwon(int* a, int n, int root)
{
	int parent=root;
	int child=parent*2+1;
	while(child<n)
	{
		if((child+1<n)&&(a[child+1]>a[child]));
			++child;
		if(a[parent]<a[child])
		{
			int tmp=a[parent];
			a[parent]=a[child];
			a[child]=tmp;
			parent=child;
			child=parent*2+1;
		}
		else
			break;
	}
}
void HeapSort(int* a, int n)
{
	for(int i=(n-1-1)/2;i>=0;--i)
		AdjustDown(a,n,i);
	int end=n-1;
	while(end>0)
	{
		//把堆顶当前最大数依次换到最后
		Swap(&a[0],&a[end]);
		AdjustDown(a,end,0);//调堆选出剩下的数中最大的
		--end;
	}
}

5、冒泡排序

void BubbleSort(int* a, int n)
{
	for(int end=n-1;end>0;--end)
	{
		int flag=0;
		for(int i=0;i<end;++i)
		{
			if(a[i]>a[i+1])
			{
				Swap(&a[i],&a[i+1]);
				flag=1;
			}
		}
		if(flag==0)
			break;
	}
}

6、快速排序

// 快速排序hoare版本
int PartSort1(int* a, int left, int right)
{
	int key=a[right];//right做key,左边先走;left做key,右边先走
	int keyindex=right;
	while(left<right)
	{
		while(left<right&&a[left]<=key)//left找大
			++left;
		while(left<right&&a[right]>=key)//right找小
			--right;
		Swap(&a[left],&a[right]);
	}
	Swap(&a[left],&a[keyindex]);
	return left;
}

//快速排序挖坑法
int PartSort2(int* a,int left,int right)
{
	int key=a[right];
	while(left<right)
	{
		while(left<right&&a[left]<key)//找大
			++left;
		a[right]=a[left];//找到大,扔到右边坑里,同时right形成新的坑
		while(left<right&&a[right]>=key)
			--right;
		a[left]=a[right];//找到小,扔到左边的坑里,同时left形成新的坑
	}
	a[left]=key;
	return left;
}

//快速排序前后指针法
int PartSort3(int* a, int left, int right)
{
	int prev=left-1;
	int cur=left;
	int key=a[right];
	while(cur<right)//遇到key位置就结束
	{
		if(a[cur]<key&&++prev!=cur)
			Swap(&a[prev],&a[cur]);
		++cur;
	}
	++prev;
	Swap(&a[prev],&a[right];
	return prev;
}

//快速排序(递归)
void QuickSort(int* a, int left, int right)
{
	if(left>=right)
		return;
	int keyindex=PartSort(a,left,right);
	QuickSort(a,left,keyindex-1);
	QuickSort(a,keyindex+1,right);
}

//快速排序非递归实现(用栈来模拟)
void QuickSortNonR(int* a, int left, int right)
{
	Stack st;
	StackInit(&st);
	StackPush(&st, left);
	StackPush(&st, right);
	while (StackEmpty(&st) != 0) 
	{
		int end = StackTop(&st);
		StackPop(&st);
		int begin = StackTop(&st);
		StackPop(&st);
		int div = PartSort1(a, begin, end);
		if (begin < div - 1) 
		{
		 StackPush(&st, begin);
		 StackPush(&st, div - 1);
		}
		if (div + 1 < end) 
		{
		 StackPush(&st, div + 1);
		 StackPush(&st, end);
		}
	}
}

7、归并排序

//归并排序的递归实现
void _MergeSort(int* a, int left, int right, int* tmp)
{
	if (left >= right)
		return;
	int mid = left + ((right - left) >> 1);
	_MergeSort(a, left, mid, tmp);
	_MergeSort(a, mid+1, right, tmp);
	int begin1 = left, end1 = mid;
	int begin2 = mid + 1, end2 = right;
	int index = left;
	while (begin1 <= end1 && begin2 <= end2)
	{
		if (a[begin1] <= a[begin2])
			tmp[index++] = a[begin1++];
		else
			tmp[index++] = a[begin2++];
	}
	while (begin1 <= end1)
		tmp[index++] = a[begin1++];
	while (begin2 <= end2)
		tmp[index++] = a[begin2++];
	memcpy(a+left, tmp+left, sizeof(int)*(right - left+1));
}
void MergeSort(int* a, int n)
{
	assert(a);
	int* tmp = (int*)malloc(sizeof(int)*n);
	_MergeSort(a, 0, n - 1, tmp);
	free(tmp);
}

//归并排序的非递归实现
void merge(int* a, int left, int mid, int right, int* tmp)
{
	int begin1 = left, end1 = mid;
	int begin2 = mid + 1, end2 = right;
	int index = left;
	while (begin1 <= end1 && begin2 <= end2)
	{
		if (a[begin1] <= a[begin2])
			tmp[index++] = a[begin1++];
		else
			tmp[index++] = a[begin2++];
	}
	while (begin1 <= end1)
		tmp[index++] = a[begin1++];
	while (begin2 <= end2)
		tmp[index++] = a[begin2++];
	memcpy(a+left, tmp+left, sizeof(int)*(right - left+1));
}
//k用来表示每次k个元素归并
void mergePass(int *arr, int k, int n, int *temp)
{
    int i = 0;
    //从前往后,将2个长度为k的子序列合并为1个
    while(i < n - 2*k + 1)
    {
        merge(arr, i, i + k - 1, i + 2*k - 1, temp);
        i += 2*k;
    }
    //合并区间[i, n - 1]有序的左半部分[i, i + k - 1]以及不及一个步长的右半部分[i + k, n - 1]
    if(i < n - k )
    {
        merge(arr, i, i + k - 1,n-1, temp);
    }
}
void MergeSortNonR(int *arr,int length)
{
    int k = 1;
    int *temp = (int *)malloc(sizeof(int) * length);
    while(k < length)
    {
        mergePass(arr, k, length, temp);
        k *= 2;
    }
    free(temp);
}

8、计数排序

void CountSort(int* a, int n)
{
	int max=a[0],min=a[0];
	for(int i=0;i<n;i++)
	{
		if(a[i]>max)
			max=a[i];
		if(a[i]<min)
			min=a[i];
	}
	int range=max-min+1;
	int* countArr=(int*)malloc(range*sizeof(int));
	memset(countArr,0,sizeof(int)*range);
	//1.统计次数
	for(int i=0;i<n;++i)
		countArr[a[i]-min]++;
	//2.根据次数进行排序
	int j=0;
	for(int i=0;i<range;++i)
	{
		while(countArr[i]--)
			a[j++]=i+min;
	}
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值