热门排序各个版本代码 递归非递归都有 纯代码

8 篇文章 0 订阅
8 篇文章 0 订阅

    //小区间优化 —— 利用其他排序去优化归并排序 快速排序 降低归并排序和快速排序的递归深度
    //快排优化三路

后面文章会更新

比较复杂的我之前已经出过单独的文章了 这里就不再阐述

排序的算法实现  后面的代码是辅助非递归 也就是模拟递归栈的实现

#define _CRT_SECURE_NO_WARNINGS 1
#include"Stack_Queue.h"



void Swap(int* p1, int* p2)
{
	int tmp = *p1;
	*p1 = *p2;
	*p2 = tmp;
}


void InsertSort(int* arr, int sz)
{
	for (int i = 0; i < sz - 1; i++)
	{
		for (int j = i + 1; j >= 1; j--)
		{
			if (arr[j] < arr[j - 1])
			{
				Swap(&arr[j], &arr[j - 1]);
			}
			else
			{
				break;//将该元素安排到合适的位置之后就没必要再进行循环
			}
		}
	}
}
void Print(int* arr, int sz)
{
	for (int i = 0; i < sz; i++)
	{
		printf("%d ", arr[i]);
	}
	printf("\n");
}
//希尔排序

//void ShellSort(int* arr, int sz)//一组一组进行排序
//{
//	int gap = sz;
//	while (gap>1)
//	{
//		gap = gap / 3 + 1;
//		for (int i = 0;i<sz;i+=gap)
//		{
//			for (int j = i; j >=gap; j-=gap)
//			{
//				if (arr[j] < arr[j - gap])
//				{
//					Swap(&arr[j], &arr[j - gap]);
//				}
//				else
//				{
//					break;
//				}
//			}
//		}
//	}
//}

//void ShellSort(int* arr, int sz)//多组进行排序
//{
//	int gap = sz;
//	while (gap > 1)
//	{
//		gap = gap / 3 + 1;
//		for (int i = 0; i < sz-gap; i ++)
//		{
//			for (int j = i; j >= 0; j -= gap)
//			{
//				if (arr[j] > arr[j + gap])
//				{
//					Swap(&arr[j], &arr[j + gap]);
//				}
//				else
//				{
//					break;
//				}
//			}
//		}
//	}
//}
void ShellSort(int* arr, int sz)//多组进行排序
{
	int gap = sz;
	while (gap > 1)
	{
		gap = gap / 3 + 1;
		for (int i = 0; i < sz-gap; i++)
		{
			for (int j = i+gap; j >= gap; j -= gap)
			{
				if (arr[j] < arr[j - gap])
				{
					Swap(&arr[j], &arr[j - gap]);
				}
				else
				{
					break;
				}
			}
		}
	}
}


//选择排序 单趟
//void SelectSort(int* arr, int sz)
//{
//	//定义一个min 
//	for (int i = 0; i < sz; i++)
//	{
//		//int min = arr[i];
//		for (int j = i + 1; j < sz; j++)
//		{
//			//if (min > arr[j])
//			if(arr[i] > arr[j])
//			{
//				Swap(&arr[i], &arr[j]);
//			}
//		}
//	}
//}

//选择排序多趟进行
void SelectSort(int* arr, int sz)
{
	int left = 0, right = sz - 1;
	while (left <= right)
	{
		int min = left;
		int max = left;
		for (int i = left; i <= right; i++)
		{
			if (arr[i] < arr[min])
			{
				min = i;
			}
			if (arr[i] > arr[max])
			{
				max = i;
			}
		}
		Swap(&arr[left], &arr[min]);
		if (max == left)//特殊情况特殊处理 当一组数据中最大值出现在该数据的最左端 就会引起该情况
		{
			max = min;
		}
		Swap(&arr[max], &arr[right]);
		left++;
		right--;
	}
}



//堆排序
//向上调整建堆
void AdjustUp(int* arr, int sz)
{
	int children = sz;
	int parent = (children - 1) / 2;
	while (children >= 0)
	{
		if (arr[parent] < arr[children])
		{
			Swap(&arr[parent], &arr[children]);
			children = parent;
			parent = (children - 1) / 2;
		}
		else
		{
			break;
		}
	}
}

//向下调整 建堆
void AdjustDown1(int* arr, int i,int sz)
{
	int parent = i;
	int children = 2 * parent + 1;
	while (children < sz)
	{
		if (children + 1 < sz && arr[children] > arr[children + 1])
		{
			children++;
		}
		if (arr[parent] > arr[children])
		{
			Swap(&arr[parent], &arr[children]);
			parent = children;
			children = 2 * parent + 1;
		}
		else
		{
			break;
		}
	}
}

//向下调整不建堆
void AdjustDown(int* arr, int sz)
{
	int parent = 0;
	int children = 2 * parent + 1;
	while (children < sz)
	{
		if (children + 1 < sz && arr[children] < arr[children + 1])
		{
			children++;
		}
		if (arr[parent] < arr[children])
		{
			Swap(&arr[parent], &arr[children]);
		}
		else
		{
			break;
		}
		parent = children;
		children = 2 * parent + 1;
	}
}
void HeapSort(int* arr, int sz)
{
	//建堆
	//向上调整建堆
	for (int i = 0; i < sz; i++)
	{
		AdjustUp(arr, i);//建的是小堆
	}
	//向下调整建堆
	/*for (int i = (sz-1-1)/2; i >= 0; i--)//建立的小堆
	{
		AdjustDown1(arr, i,sz);
	}*/
	for (int i = sz - 1; i > 0; i--)
	{
		Swap(&arr[0], &arr[i]);
		AdjustDown(arr,i-1);
	}

}

//三数取中
int ThreeNumsMid(int* arr, int left, int right)
{
	int mid = (right - left) + left;
	if (arr[left] < arr[right])
	{
		if (arr[left] < arr[mid])
		{
			return mid;
		}
		else if(arr[arr[right]<arr[mid]])
		{
			return right;
		}
		else
		{
			return left;
		}
	}
	else//arr[left]>=arr[right]
	{
		if (arr[left] > arr[mid])
		{
			return mid;
		}
		else if (arr[mid] > arr[left])
		{
			return left;
		}
		else
		{
			return right;
		}
	}
}

//快速排序
//Hoare版本 起始版本
void _QuickSort1(int* arr, int left, int right)
{
	if (left >= right)
	{
		return;
	}
	int begin = left, end = right;
	int key = arr[left];
	while (begin < end)
	{
		while (begin < end && arr[end] >= key)
		{
			end--;
		}
		while (begin < end && arr[begin] <= key)
		{
			begin++;
		}
		Swap(&arr[begin], &arr[end]);
	}
	Swap(&arr[left], &arr[begin]);
	int keyi = begin;
	_QuickSort1(arr, left, keyi - 1);
	_QuickSort1(arr, keyi + 1, right);
}
//快速排序挖坑版本 
void _QuickSort2(int* arr, int left,int right)
{
	if (left >= right)
	{
		return;
	}
	int begin = left, end = right;
	int key = arr[begin];
	int keyi = left;
	while (begin < end)
	{
		while (begin < end && key <= arr[end])
		{
			end--;
		}
		arr[begin] = arr[end];
		while (begin < end && key >= arr[begin])
		{
			 begin++;
		}
		arr[end] = arr[begin];
	}
	arr[begin] = key;
	_QuickSort2(arr, left, begin - 1);
	_QuickSort2(arr, begin + 1, right);
}

//前后指针法
void _QuickSort3(int* arr, int left, int right)
{
	if (left >= right)
	{
		return;
	}
	int cur = left + 1, prev = left + 1;
	int key = arr[left];
	while (prev <= right)
	{
		if (arr[prev] >= key)
		{
			prev++;
		}
		else
		{
			Swap(&arr[prev], &arr[cur]);
			prev++;
			cur++;
		}
	}
	Swap(&arr[left], &arr[cur-1]);
	int keyi = cur - 1;
	_QuickSort3(arr, left, keyi - 1);
	_QuickSort3(arr, keyi + 1, right);
}
void QuickSort(int* arr, int sz)
{
	//_QuickSort1(arr, 0, sz - 1);//Hoare
	//_QuickSort2(arr, 0, sz - 1);//挖坑法
	_QuickSort3(arr, 0, sz - 1);//前后指针
}

void _MergeSort(int* arr, int left, int right,int* tmp)
{
	if (left >= right)
	{
		return;
	}
	int mid = (right - left) / 2 + left;
	_MergeSort(arr, left, mid,tmp);
	_MergeSort(arr, mid + 1, right,tmp);
	int i = left;
	int begin1 = left, end1 = mid;
	int begin2 = mid + 1, end2 = right;
	while (begin1 <= end1 && begin2 <= end2)
	{
		if (arr[begin1] <= arr[begin2])
		{
			tmp[i++] = arr[begin1++];
		}
		else
		{
			tmp[i++] = arr[begin2++];
		}
	}
	while (begin1 <= end1)
	{
		tmp[i++] = arr[begin1++];
	}
	while (begin2 <= end2)
	{
		tmp[i++] = arr[begin2++];
	}
	int j = 0;
	for (j = left; j <= right; j++)
		arr[j] = tmp[j];
}
//归并排序
void MergeSort(int* arr, int sz)
{
	int* tmp = (int*)malloc(sizeof(int) * sz);
	_MergeSort(arr, 0, sz - 1,tmp);
	free(tmp);
	tmp = NULL;
}

//Hoare版本非递归
int _QuickSortNonR1(int* arr, int left, int right)
{
	if (left >= right)return-1;
	int begin = left, end = right;
	while (begin < end)
	{
		while (begin < end && arr[end] >= arr[left])
			end--;
		while (begin < end && arr[begin] <= arr[left])
			begin++;
		Swap(&arr[end], &arr[begin]);
	}
	Swap(&arr[left], &arr[begin]);
	return begin;
}
//挖坑法非递归版本
int _QuickSortNonR2(int* arr, int left, int right)
{
	if (left >= right)return -1;
	int begin = left, end = right;
	int tmp = arr[left];
	while (begin < end)
	{
		while (begin < end && arr[end] >= tmp)
			end--;
		arr[begin] = arr[end];
		while (begin < end && arr[begin] <= tmp)
			begin++;
		arr[end] = arr[begin];
	}
	arr[begin] = tmp;
	return begin;
}

//前后指针法非递归版本
int _QuickSortNonR3(int* arr, int left, int right)
{
	if (left >= right)return-1;
	int cur = 0, prev = 1;
	while (prev <= right)
	{
		if (arr[prev] < arr[left])
		{
			prev++;
		}
		else
		{
			prev++;
			cur++;
			Swap(&arr[cur], &arr[prev]);
		}
	}
	return cur;
}
//非递归版本
void QuickSortNonR(int* arr, int sz)
{
	Stack st;
	StackInti(&st);
	StackPush(&st, sz - 1);//将右区间末端存入栈
	StackPush(&st, 0);//将左区间末端存入栈
	while (!StackEmpty(&st))
	{
		int left = StackTop(&st);
		StackPop(&st);
		int right = StackTop(&st);
		StackPop(&st);
		//int keyi = _QuickSortNonR1(arr, left, right);
		int keyi = _QuickSortNonR2(arr, left, right);

		if (keyi != -1)
		{
			StackPush(&st, right);
			StackPush(&st, keyi + 1);
			StackPush(&st, keyi - 1);
			StackPush(&st, left);
		}


	}
	StackDestroy(&st);
}

void MergeSortNonR(int* arr, int n)
{
	//开临时空间
	int* tmp = (int*)malloc(sizeof(int) * n);
	if (tmp == NULL)
	{
		return;
	}

	int gap = 1;
	while (gap < n)
	{
		int j = 0;//为了控制 tmp
		for (int i = 0; i < n; i +=2*gap)
		{
			int begin1 = i, end1 = i + gap - 1;
			int begin2 = i + gap, end2 = i + gap * 2 - 1;
			//该部分如果满足就不会再向下运行代码 那还不如结束循环
			if (end1 >= n || begin2 >= n)
			{
				break;
			}
			//if (end1 >= n)
			//{
			//	end1 = n - 1;

			//	//[begin2,end2]修改成不存在的区间
			//	begin2 = n;
			//	end2 = n - 1;
			//}
			//else if (begin2 >= n)
			//{
			//	//修改成不存在的区间
			//	begin2 = n;
			//	end2 = n - 1;
			//}
			if (end2 >= n)
			{
				end2 = n - 1;
			}
			while (begin1 <= end1 && begin2 <= end2)
			{
				if (arr[begin1] <= arr[begin2])
				{
					tmp[j++] = arr[begin1++];
				}
				else
				{
					tmp[j++] = arr[begin2++];
				}
			}
			while (begin1 <= end1)
			{
				tmp[j++] = arr[begin1++];
			}
			while (begin2 <= end2)
			{
				tmp[j++] = arr[begin2++];
			}

			//将tmp中的数据拷贝到原数组中为下次排序做准备

			//当然在上面那写超出范围后修正的区间 并没有移动 
			memcpy(arr + i, tmp + i, sizeof(int) * (end2 - i + 1));
		}
		gap *= 2;
	}
	free(tmp);
}

void BubbleSort(int* arr, int sz)
{
	for (int i = 0; i < sz - 1; i++)
	{
		int falg = 0;
		for (int j = 0; j < sz - i - 1; j++)
		{
			if (arr[j] > arr[j + 1])
			{
				falg = 1;
				Swap(&arr[j], &arr[j + 1]);
			}
		}
		if (falg == 0)
		{
			break;
		}
	}
}
void CountSort(int* arr, int sz)
{
	int max = INT_MIN;
	int min = INT_MAX;
	for (int i = 0; i < sz; i++)//寻找该数据的区间端点
	{
		min = min > arr[i] ? arr[i] : min;
		max = max < arr[i] ? arr[i] : max;
	}
	int* tmp = (int*)calloc((max - min + 1), sizeof(int));
	int d = max - min;
	for (int i = 0; i < sz; i++)
	{
		tmp[arr[i]-min]++;
	}
	int j = 0;//控制arr数组下标
	for (int i = 0; i < sz; i++)
	{
		while(tmp[i]!=0)
		{
			arr[j++] = min + i;
			tmp[i]--;
		}
	}
}
int main()
{

	//int arr[] = { 3,2,1 };
	int arr[] = { 9,8,7,6,5,4,3,2,1,10,12,0,11};
	int sz = sizeof(arr) / sizeof(arr[0]);
	//Print(arr, sz);

	//非递归——快排
	//QuickSortNonR(arr, sz);
	//MergeSortNonR(arr, sz);

	//Print(arr, sz);




	Print(arr, sz);
	/*printf("插入排序:");
	InsertSort(arr, sz);*/
	printf("希尔排序:");
	CountSort(arr, sz);
	//BubbleSort(arr, sz);
	//ShellSort(arr, sz);
	//SelectSort(arr, sz);
	//HeapSort(arr, sz);
	//QuickSort(arr,sz);
	//MergeSort(arr, sz);
	//快速排序非递归
	//归并排序非递归
	//三数取中
	

	//
	//小区间优化 —— 利用其他排序去优化归并排序 快速排序 降低归并排序和快速排序的递归深度
	//快排优化三路
	Print(arr, sz);

	//Stack st;
	//StackInti(&st);
	//if (!StackEmpty(&st))
	//{
	//	printf("栈为空\n");
	//}
	//StackPush(&st, 1);
	//StackPush(&st, 2);
	//StackPush(&st, 3);
	//StackPush(&st, 4);
	//StackPush(&st, 5);
	//StackPush(&st, 6);

	//StackPop(&st);
	//StackPop(&st);
	//StackPop(&st);

	//printf("%d \n", StackTop(&st));

	//if (StackEmpty(&st))
	//{
	//	printf("栈为不为空\n");
	//}

	//StackDestroy(&st);



	return 0;
}

栈的实现

stack.h

#define _CRT_SECURE_NO_WARNINGS 1

#include<stdio.h>
#include<stdlib.h>
#include<stdbool.h>

typedef int StackData;
typedef struct Stack
{
	StackData* arr;
	int sz;
	int capacity;
}Stack;

//栈的初始化
void StackInti(Stack* st);
//栈的插入
void StackPush(Stack* st,StackData x);
//出栈
StackData StackTop(Stack* st);
//栈的删除
void StackPop(Stack* st);
//栈的判空
bool StackEmpty(Stack* st);
//栈的销毁
void StackDestroy(Stack* st);

stack.c

#define _CRT_SECURE_NO_WARNINGS 1

#include"Stack_Queue.h"

void StackInti(Stack* st)
{
	st->arr = NULL;
	st->capacity = st->sz = 0;
}

void StackPush(Stack* st, StackData x)
{
	if (st->capacity == st->sz)
	{
		int newcapacity = (st->capacity == 0) ? 4: st->capacity * 2;
		StackData* tmp = (StackData*)realloc(st->arr, sizeof(StackData) * newcapacity);
		if (tmp == NULL)
		{
			printf("failed to allocate memory.\n");
			return;
		}
		st->arr = tmp;
		st->capacity = newcapacity;
	}
	st->arr[st->sz++] = x;
}

void StackPop(Stack* st)
{
	if(!StackEmpty(st))
		st->sz--;
}
StackData StackTop(Stack* st)
{
	if (!StackEmpty(st))
	{
		return st->arr[st->sz-1];
	}
}
bool StackEmpty(Stack* st)
{
	return st->sz == 0;
}


void StackDestroy(Stack* st)
{
	st->arr = NULL;
	st->capacity = st->sz = 0;
}

希望给位大佬指点一二 如有不对评论区指教或私信~ 代码有点小多 就不做文字讲解

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

菜鸡爱玩

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值