七种基本的排序算法

113 阅读1分钟

七种基本的排序算法

冒泡排序

/*冒泡排序*/
void BubbleSort(int* h, size_t len)
{
	if (h == NULL)	return;
	if (len <= 1)	return;
	for (int i = 0; i < len - 1; ++i)
	{
		for (int j = 0; j < len - 1 - i; ++j)
		{
			if (h[j] > h[j + 1])
				swap(h[j], h[j + 1]);
		}
	}
	return;
}

选择排序

/*选择排序*/
void SelectionSort(int* h, size_t len)
{
	if (h == NULL)	return;
	if (len <= 1)	return;

	int minindex, i, j;		//i:排序好的个数,j:未排序的第一个元素
	for (i = 0; i < len; i++)
	{
		minindex = i;
		for (j = i + 1; j < len; j++)
		{
			if (h[j] < h[minindex])	minindex = j;
		}
		swap(h[i], h[minindex]);
	}
	return;
}

插入排序

/*插入排序*/
void InsertSort(int* h, size_t len)
{
	if (h == NULL)	return;
	if (len <= 1)	return;
	int i, j;	//i:排序好的个数	j:未排序的第一个数
	for (int i = 1; i < len; i++)
	{
		for (int j = i; j > 0; j--)
		{
			if (h[j] < h[j - 1])	swap(h[j], h[j - 1]);
			else break;
		}
	}
	return;
}

快速排序

```/*快速排序*/
void QuickSort(int* h, int left, int right)
{
	/*
	1、随机选择key放在最左边
	2、把小于key的放在左边,大于等于key的放在右边,在赋值的时候,被移动的原值会被视为空洞 h[i] = h[j], h[j]为空洞
	3、将key赋值个空洞
	*/
	if (h == NULL)	return;
	if (left >= right)	return;

	srand((unsigned)time(NULL));	//一般与rand()配合使用
	int len = right - left + 1;
	int kindex = rand() % len + left;	//找到一个随机数
	swap(h[left], h[kindex]);		//将left与kindex交换位置

	int key = h[left], i = left, j = right;
	while (i < j)	//将当前的left当作一个空洞,用key保存起来,后面再用key进行填充
	{
		//把小于key的放在左边,大于等于key的放在右边
		while (h[j] >= key && i < j) --j;	//找到右边第一个小于key的值
		if (i < j) h[i] = h[j];
		while (h[i] < key && i < j) ++i;	//找到左边第一个大于右边的值
		if (i < j) h[j] = h[i];
	}

	h[i] = key;
	QuickSort(h, left, i - 1);
	QuickSort(h, j + 1, right);
}

归并排序

/*归并排序*/
void MergeArray(int* arr, size_t left, size_t mid, size_t right, int* temp)	//将两个有序数组合成一个有序数组
{
	if (arr == NULL)	return;

	size_t i = left, j = mid + 1, k = 0;
	//将left到right范围内的两部分数组进行排序,每一部分最小的长度为2,两边最多差距为1
	while (i <= mid && j <= right)
	{
		if (arr[i] <= arr[j])
		{
			temp[k++] = arr[i++];
			continue;
		}
		temp[k++] = arr[j++];
	}

	while (i <= mid)
		temp[k++] = arr[i++];
	while (j <= right)
		temp[k++] = arr[j++];
	memcpy(&arr[left], temp, k * sizeof(int));	//将left到right排序好后的数组temp,重新装入以&arr[left]开头的数组
	return;
}
void MMergeSort(int* arr, size_t left, size_t right, int* temp)		//递归找到两个数组(长度为一),进行MergeArray排序
{
	if (left < right)
	{
		//数组都分为左边跟右边,最小分为len为2数组
		size_t mid = (left + right) / 2;
		MMergeSort(arr, left, mid, temp);
		MMergeSort(arr, mid + 1, right, temp);
		MergeArray(arr, left, mid, right, temp);
	}
}
void MergeSort(int* h, size_t len)
{
	if (h == NULL)	return;
	if (len <= 1)	return;
	int* temp = (int*)calloc(len, sizeof(int));
	MMergeSort(h, 0, len - 1, temp);
	memcpy(h, temp, sizeof(int) * len);
	free(temp);
	return;
}

堆排序

/*堆排序*/
void AdjustHeap(int* h, int node, int len)
{
	int index = node;
	int child = 2 * index + 1;
	while (child < len)
	{
		if (child + 1 < len && h[child] < h[child + 1])
		{
			child++;
		}
		if (h[index] >= h[child])	break;
		swap(h[index], h[child]);
		index = child;
		child = 2 * index + 1;
	}
}
void MakeHeap(int* h, int len)
{
	for (int i = len / 2; i >= 0; --i)
	{
		AdjustHeap(h, i, len);
	}
}
void HeapSort(int* h, int len)
{
	MakeHeap(h, len);
	for (int i = len - 1; i >= 0; i--)
	{
		swap(h[i], h[0]);	//将每个数组的头部,也就是树的头部放在最后
		AdjustHeap(h, 0, i);	//调节树,使其维持最大堆的性质
	}
}

希尔排序

/*希尔排序*/
void ShellSort(int* h, size_t len)
{
	if (h == NULL) return;
	if (len <= 1)	return;
	for (int div = len / 2; div >= 1; div /= 2)
	{
		for (int k = 0; k < div; k++)
		{
			for (int i = div + k; i < len; i += div)
			{
				for (int j = i; j > k; j -= div)
				{
					if (h[j] < h[j - div])	swap(h[j], h[j - div]);
					else break;
				}
			}
		}
	}
}

代码转自->www.cnblogs.com/fnlingnzb-l…