栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > C/C++/C#

c语言排序(冒泡、hoare、插入、选择、归并、前后指针、挖坑)

C/C++/C# 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

c语言排序(冒泡、hoare、插入、选择、归并、前后指针、挖坑)

1、冒泡排序

冒泡排序是将前一个元素与后一个元素进行比较,符合条件就进行交换,最大的元素需要与后面的每一个元素进行交换;

最后的数一定是最大的,因此第二层for语句是for (int j = 1; j < n - i; j++),最后一个元素不进入循环。
void BubbleSort(int* a, int n)//a是数组名  n为数组内元素个数
{
	for (int i = 0; i < n; i++)
	{
		int exchange = 0;
        //将最大的元素往后挪,直到最后
		for (int j = 1; j < n - i; j++)
		{
			if (a[j - 1] > a[j])
			{
				Swap(&a[j - 1], &a[j]);
				exchange++;
			}
		}
		if (exchange == 0)//判断是否有交换,如果没有交换,说明排序已经成功,即使后面还有数据,
                          //但后面的数据已经是有序的
		{
			break;
		}
	}
}

void TEXTBubbleSort()
{
	int a[] = { 6,9,8,4,2,1,3,7,5 };
	BubbleSort(a, sizeof(a) / sizeof(int));
	PrintArray(a, sizeof(a) / sizeof(int));
}
2、插入排序

          保存插入的元素,如果前面的元素大于插入元素,则将前面元素后移一位,用循环语句,将前面有序数组中所有大于插入元素的元素都后移一位,这样在前面就会有个位置空余出来,然后再a[end + 1] = tmp将插入元素放入空位。

void InsertSort(int* a, int n)
{
	for (int i = 0; i < n-1;i++)
	{
		int end = i;
		int tmp = a[i + 1];//保存插入的元素
		while(end >= 0)
		{ 
			// 单趟排序:[0, end]有序 end+1位置的值,插入进入,保持他依旧有序
			if (a[end] > tmp)
			{
				a[end + 1] = a[end];//将前面大的元素往后放
				end--;
			}
			else
			{
				break;
			}
		}
			a[end + 1] = tmp;
	}
}
void TextInsertSort()
{
	int a[] = { 6,9,8,4,2,1,3,7,5 };
	InsertSort(a, sizeof(a) / sizeof(int));
	PrintArray(a, sizeof(a) / sizeof(int));
}
3、hoare排序(希尔排序)

    思路:如果使数组最左侧元素为key,则右侧先动,right- - 寻找比key小的数,找到后停止,随后left++,寻找比key大的数,找到后,a[right]与a[left]的元素交换,直到left与right相遇,再将a[key]与此时a[left]交换。

    这只是确定了如图中6的正确位置,后面使用递归发,将数组分成两个数组,6之前和6之后;

int PartSort1(int* a, int left, int right)
{
	int key = left;
	while (left < right)
	{
		while (left=a[key])//右侧寻找比key小的数
		{
			right--;
		}
		while (left= end) {
		return;
	}
	int keyi = PartSort1(a, begin, end);
	QuickSort(a, begin, keyi - 1);
	QuickSort(a, keyi+1, end);
}
4、选择排序      选择排序思路:假设最左边的元素为最小元素,下标为min,然后用left++寻找比它还要小的元素,找到就将这个元素的下标赋予min,遍历整个数组后,将min下标元素与left交换,这样,最小的元素就转移到最左侧。

void SelectSort(int* a, int n)
{
	int left = 0;
	int right = n - 1;
	while (left < right)
	{
		int min = left;
		for (int i = left + 1; i <= right; i++)//从左往右寻找最小的数
		{
			if (a[i] < a[min])
			{
				min = i;//一旦找到,就将元素下标赋予min
			}
		}
		Swap(&a[left], &a[min]);//将min下标既最小的数与最左边的元素交换
		left++;
	}
}
void TextSelectSort()
{
	int a[] = { 6,9,8,4,2,1,3,7,5 };
	SelectSort(a, sizeof(a) / sizeof(int));
	PrintArray(a, sizeof(a) / sizeof(int));
}

5、前后指针     前后指针思路:设最左元素下标left为key和pre,cur为left+1,随后cur++,遇到比key小的元素,pre++,并交换cur与pre下标所在元素,直到cur走出数组范围,pre停止,并交换pre和key下标所在元素。

int PartSort2(int* a, int* left , int* right)
{
	int pre = left;
	int cur = left + 1;
	int key = left;
	while (cur < right)
	{
		if (a[cur] < a[key]&&a[++pre]!=a[cur])
		{
			Swap(&a[pre], &a[cur]);
		}
		cur++;
	}
	Swap(&a[pre], &a[key]);

	return pre;
}

//递归
void QuickSort(int* a, int begin, int end)
{
	if (begin >= end) {
		return;
	}
	int keyi = PartSort2(a, begin, end);
	QuickSort(a, begin, keyi - 1);
	QuickSort(a, keyi+1, end);
}
6、挖坑法      用key保持最左侧元素,相当于将这个位置挖成一个坑,下标为pit,随后右侧right- -,寻找比key小的元素,找到后将right下标元素放入pit下标元素,并移动pit到right处(a[pit]=a[right],pit=right),相当于right下标元素挖坑.     然后left++,寻找比key大的元素,再将left下标元素放入pit中,将left赋予pit(a[pit]=a[left],pit=left)。知道left与right相遇,再将pit坑位放入key。

int PartSort3(int* a, int left, int right)
{
	int midi = GetMidIndex(a, left, right);
	Swap(&a[midi], &a[left]);

	int keyi = left;
	int prev = left, cur = left+1;
	while (cur <= right)
	{
		if (a[cur] < a[keyi] && a[++prev] != a[cur])
			Swap(&a[prev], &a[cur]);

		++cur;
	}
	Swap(&a[prev], &a[keyi]);

	return prev;
}

void QuickSort1(int* a, int begin, int end)
{
	// 子区间相等只有一个值或者不存在那么就是递归结束的子问题
	if (begin >= end)
		return;

	int keyi = PartSort3(a, begin, end);
	QuickSort1(a, begin, keyi - 1);
	QuickSort1(a, keyi+1, end);
}

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/879343.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号