数据结构--排序(冒泡)

1.冒泡排序

1.冒泡排序的原理是:从左到右,相邻元素进行比较。每次比较一轮,就会找到序列中最大的一个或最小的一个。这个数就会从序列的最右边冒出来。

以从小到大排序为例,第一轮比较后,所有数中最大的那个数就会浮到最右边;第二轮比较后,所有数中第二大的那个数就会浮到倒数第二个位置……就这样一轮一轮地比较,最后实现从小到大排序。每次排序的元素都会减少,直到没有任何一队元素需要比较。
比较时,每轮中第 n 次比较是新序列中第 n 个元素和第 n+1 个元素的比较(假如 n 从 1 开始)
时间复杂度:
最好情况:是有序的,只需遍历一遍即可 O(n)
最坏情况:全部无序,每次都要交换 O(n*2)

#include<stdio.h>
#include<assert.h>

//冒泡排序 -->每次确定一个最大的
void BubbleSort(int *a, int n)
{
	assert(a);
	for (size_t i = 0; i < n - 1; i++)//比较n-1轮,最后一个不需要比较
	{
		int exchange = 0;//设置一个标志位
		for (size_t j = 0; j < n - 1 - i; j++)//每一轮比较n-1-i次,每一轮少比较1次
		{
			if (a[j]>a[j + 1])//从小到大排序
			{
				//swap(&a[j], &a[j + 1]);//交换
				size_t tmp = a[j];
				a[j] = a[j + 1];
				a[j + 1] = tmp;
				exchange = 1;
			}
		}
		if (exchange == 0)//若没有发生交换,则直接退出,优化
			break;
	}
}
int main()
{
	int  a[10] = { 5, 88, 23, 14 };
	BubbleSort(a, 4);
	return 0;
}

2.二分查找(折半查找)

一个有序序列的高效查找算法
实现思路:

int mid = begin + ((end - begin) >> 1)
这样是防止溢出的写法(记住就好)

int BinarySearch(int *a, int n, int x)
{
	assert(a);
	int begin = 0;
	int end = n - 1;
	while (begin <= end)//两个相等时,判断的是最后一位
	{
		int mid = begin + ((end - begin) >> 1); 
		if (a[mid] < x)
		{
			begin = mid + 1;
		}
		else if (a[mid]>x)
		{
			end = mid - 1;
		}
		else
			return mid;
	}
	return -1;//查找失败
}
int main()
{	
	int  a[100] = { 1,3,4,6,7,8,10,13,14 };
	BinarySearch(a, 9, 4);
	printf("%d", BinarySearch(a, 9, 4));
}
	

3.插入排序

**思想:**直接插入排序是一种简单的插入排序法,其基本思想是:把待排序的记录按其关键码值的大小逐个插入到一个已经排好序的有序序列中,直到所有的记录插入完为止,得到一个新的有序序列 。
实际中我们玩扑克牌时,就用了插入排序的思想。
在这里插入图片描述

当插入第i(i>=1)个元素时,前面的array[0],array[1],…,array[i-1]已经排好序,此时用array[i]的排序码与array[i-1],array[i-2],…的排序码顺序进行比较,找到插入位置即将array[i]插入,原来位置上的元素顺序后移。
直接插入排序的特性总结:

  1. 元素集合越接近有序,直接插入排序算法的时间效率越高
  2. 时间复杂度:O(N^2)
  3. 空间复杂度:O(1),它是一种稳定的排序算法
  4. 稳定性:稳定

有序位置的最后一个位置向前遍历,找到第一个小于待插数据的位置,然后这个数据放入已经找到位置的下一个位置

代码实现:

void InsertSort(int* a, int lenth)
{
	int i, j, z, index;

	for (j = 1; j < lenth; j++)//待插入数据 从1开始 首元素为初始有序数列
	{
		for (i = j - 1; i >= 0; i--)//已排序数据
		{
			if (a[j] > a[i])//在已排序列中找到位置
			{
				break;
			}
		}
		index = a[j];//将待插入数据拷贝出来等待 下面数据后移时会覆盖该数据
		if (i != j - 1)//不是有序数据末尾
		{
			for (z = j; z > i; z--)//数据后移,留出待插空位
			{
				a[z] = a[z - 1];
			}
			a[i + 1] = index;
		}
	}
}
void InsertSort(int* a, int lenth)
{
	//假设第一个数据有序
	//要拍的[1,n)
	for (int i = 1; i < lenth; ++i)//代排的
	{
		int end = i - 1;
		int data = a[i];
		while (end >= 0 && a[end] >= data)
		{
			a[end + 1] = a[end];//大的向后移动
			--end;
		}//end=-1时退出
		a[end + 1] = data;//end位置是比待排数据要小的,
	}
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
十大经典排序算法是指在计算机科学中常用的排序算法,它们分别是: 1. 冒泡排序(Bubble Sort):重复地比较相邻的两个元素,将较大的元素逐渐向右移动。 2. 选择排序(Selection Sort):每次从未排序的部分选择最小(或最大)的元素,并放在已排序的部分的末尾。 3. 插入排序(Insertion Sort):将未排序的元素逐个插入到已排序的部分中的正确位置。 4. 希尔排序(Shell Sort):将待排序的数组按照一定步长进行分组,对每组进行插入排序,逐渐减小步长。 5. 归并排序(Merge Sort):将待排序的数组递归地分成两半,对每一半进行排序,然后合并两个有序数组。 6. 快速排序(Quick Sort):选择一个基准元素,将数组划分为两部分,左边部分都小于基准,右边部分都大于基准,递归地对两部分进行排序。 7. 堆排序(Heap Sort):将待排序的数组构建成一个最大堆(或最小堆),然后依次取出堆顶元素并调整堆结构。 8. 计数排序(Counting Sort):统计数组中每个元素出现的次数,然后根据统计结果对元素进行排序。 9. 桶排序(Bucket Sort):将待排序的数组划分为多个桶,对每个桶中的元素进行排序,最后将桶中的元素按顺序合并。 10. 基数排序(Radix Sort):按照元素的位数,将待排序的数组从低位到高位进行排序。 以上是十大经典排序算法,每种算法都有其适用的场景和性能特点,选择合适的排序算法可以提高程序的效率。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值