当前位置: 首页 > news >正文

C++ 排序(1)

以下是一些插入排序的代码

1.插入排序

1.直接插入排序

// 升序
// 最坏:O(N^2)  逆序
// 最好:O(N)    顺序有序
void InsertSort(vector<int>& a, int n)
{
	for (int i = 1; i < n; i++)
	{
		int end = i - 1;
		int tmp = a[i];
		// 将tmp插入到[0,end]区间中,保持有序
		while (end >= 0)
		{
			if (tmp < a[end])
			{
				a[end + 1] = a[end];
				--end;
			}
			else
			{
				break;
			}
		}

		a[end + 1] = tmp;
	}
}
//一个一个插入  一个  一个排序

2.折半插入排序 

折半插入排序本质上就是 插入排序 +二分查找

// 折半插入排序函数
void binaryInsertionSort(std::vector<int>& arr) {
	int n = arr.size();
	for (int i = 1; i < n; ++i) {
		int key = arr[i];
		int left = 0, right = i - 1;

		// 二分查找插入位置
		while (left <= right) {
			int mid = left + (right - left) / 2;
			if (arr[mid] > key) {
				right = mid - 1;
			}
			else {
				left = mid + 1;
			}
		}

		// 将元素后移
		for (int j = i - 1; j >= left; --j) {
			arr[j + 1] = arr[j];
		}

		// 插入元素
		arr[left] = key;
	}
}

3.希尔排序

//希尔排序
void ShellSort(vector<int>&a, int n)
{
	/*int gap = 3;
	for (int j = 0; j < gap; j++)
	{
		for (int i = j; i < n - gap; i += gap)
		{
			int end = i;
			int tmp = a[i + gap];
			while (end >= 0)
			{
				if (tmp < a[end])
				{
					a[end + gap] = a[end];
					end -= gap;
				}
				else
				{
					break;
				}
			}
			a[end + gap] = tmp;
		}
	}*/

	// gap > 1 预排序
	// gap == 1 直接插入排序
	int gap = n;
	while (gap > 1)
	{
		//gap /= 2;
		gap = gap / 3 + 1;//除2是不用+1的 因为你能保证最后gap一定是1   gap为1就是直接插入排序  但是/3就不能保证了!

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

		//PrintArray(a, n);
	}
}

希尔排序的这两种实现方式的时间复杂度是一模一样的  只是遍历的方式不一样

2.选择排序

1.直接选择排序 

void Swap(int& a, int& b) {
    int temp = a;
    a = b;
    b = temp;
}

// 直接选择排序函数
void SelectSort(int* a, int n) {
    for (int i = 0; i < n - 1; ++i) {
        int minIndex = i;
        for (int j = i + 1; j < n; ++j) {
            if (a[j] < a[minIndex]) {
                minIndex = j;
            }
        }
        if (minIndex != i) {
            Swap(a[i], a[minIndex]);
        }
    }
}

可以对其进行优化   比如我一次选两个数出来

但是这个时候swap的时候要确认一下特殊情况

同时如果是有序的就可以直接break了 不用那么麻烦


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


void BubbleSort(int* a, int n)
{
	for (int j = 0; j < n; j++)
	{
		bool exchange = false;
		for (int i = 1; i < n-j; i++)
		{
			if (a[i - 1] > a[i])
			{
				Swap(&a[i - 1], &a[i]);
				exchange = true;
			}
		}

		if (exchange == false)
		{
			break;
		}
	}
}

2.堆排序

// 左右子树都是大堆/小堆
void AdjustDown(int* a, int n, int parent)
{
	int child = parent * 2 + 1;
	while (child < n)
	{
		// 选出左右孩子中大的那一个
		if (child + 1 < n && a[child + 1] > a[child])
		{
			++child;
		}

		if (a[child] > a[parent])
		{
			Swap(&a[child], &a[parent]);
			parent = child;
			child = parent * 2 + 1;
		}
		else
		{
			break;
		}
	}
}


//堆排序
void HeapSort(int* a, int n)
{
	// 建堆 -- 向下调整建堆 -- O(N)
	for (int i = (n - 1 - 1) / 2; i >= 0; --i)
	{
		AdjustDown(a, n, i);
	}

	// 自己先实现 -- O(N*logN)
	int end = n - 1;
	while (end > 0)
	{
		Swap(&a[end], &a[0]);
		AdjustDown(a, end, 0);

		--end;
	}
}

 3.交换排序

1.冒泡排序


//冒泡排序

// 最坏:O(N^2)
// 最好:O(N)
void BubbleSort(int* a, int n)
{
	for (int j = 0; j < n; j++)
	{
		bool exchange = false;
		for (int i = 1; i < n - j; i++)
		{
			if (a[i - 1] > a[i])
			{
				Swap(&a[i - 1], &a[i]);
				exchange = true;
			}
		}

		if (exchange == false)
		{
			break;
		}
	}
}

http://www.dtcms.com/a/113146.html

相关文章:

  • Kotlin 枚举类
  • 网络安全之前端学习(css终章)
  • 31天Python入门——第25天:文件和目录操作
  • 单片机实现多线程的方法汇总
  • 为招聘推荐系统进行相应修改的 Python 实现方案(含协同过滤推荐算法)
  • 【Vue】 核心特性实战解析:computed、watch、条件渲染与列表渲染
  • deepseek回答ollama 下载模型的命令
  • 04.游戏开发-unity编辑器详细-工具栏、菜单栏、工作识图详解
  • 某碰瓷国赛美赛,号称第三赛事的数模竞赛
  • SQLmap工具使用
  • 详解 MySQL 三层 B+ 树能存多少数据的计算方法
  • 中国移动启动数字乡村“五新升级”:年底前,行政村5G覆盖达95%
  • 【leetcode】记录与查找:哈希表的题型分析
  • MySQL篇(六)MySQL 分库分表:应对数据增长挑战的有效策略
  • 群体智能避障革命:RVO算法在Unity中的深度实践与优化
  • 小刚说C语言刷题——第15讲 多分支结构
  • 紫檀博物馆一游与软件开发
  • Kerberos协议详解
  • 基于 Netty 框架的 Java TCP 服务器端实现,用于启动一个 TCP 服务器来处理客户端的连接和数据传输
  • FPGA实现按键切换流水灯不同亮灭模式
  • 【FPGA开发】利用状态机思想点亮流水灯/初学hdlbitsFPGA教程网站
  • P9752 [CSP-S 2023] 密码锁题解
  • CNN 里面能自然起到防止过拟合的办法
  • 推荐系统(二十二):基于MaskNet和WideDeep的商品推荐CTR模型实现
  • 基于大模型的重症肌无力的全周期手术管理技术方案
  • Mydumper备份数据库
  • 操作系统内存管理
  • 深入解析 RocketMQ 中的 BrokerOuterAPI 组件​
  • 使用VSCode编写C#程序
  • 低代码开发平台:飞帆中新增控件、修改他人控件