【朝花夕拾之排序算法总结】 快速排序,堆排序总结

本文详细介绍了快速排序和堆排序的基本原理与实现方法。快速排序通过选取基准元素并进行分区来实现排序,而堆排序则利用完全二叉树的特性进行循环调整。文中提供了这两种排序算法的C语言实现。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

大二学的数据结构,现在回想起来还是有很多混淆的地方。在这里总结一下,简单的冒泡,插入,选择我这里不再赘述。

一、快速排序

我的理解(不对的地方欢迎指正,共同学习哈O(∩_∩)O):

快速排序的思想就是先选一个元素作为“轴”,升序排序的话,每一次将一个比轴小的元素移动到轴的左边和一个比轴大的移动到轴的右边。假如有这么10个数字等待排序 8,0,3,7,9,5,6,1,4,2 那么可以选第1个元素(下标为0的元素闲置不用)作为轴。那么这一次要做的就是:

1、从最右边(也就是第10个元素)开始往回找,找出一个比 8 小的元素,于是找到了2。于是直接将2与8交换位置变成 :2,0,3,7,9,5,6,1,4,8;

2、从刚刚8的下标开始(也就是最左边),找出一个比8大的数。于是找到了9,与8交换变成:2,0,3,7,8,5,6,1,4,9

3、从9的下标开始往回找一个比8小的数,找到了4。与8交换变成2,0,3,7,4,5,6,1,8,9

到了这里可以看到在轴(8)的左边,全都是比8小的数,在8的右边,全都是比8大的数。这就是一趟快排的调整。接下来只需要将轴的两边递归即可得出排序结果。

代码的实现跟上面的略有不同,就是轴每次都要与其他元素交换。我们其实可以发现轴的最终位置就是每一趟快排的调整最后移动的元素的位置。

所以可先将轴暂存起来,交换改为直接赋值,最后在将轴赋值给每一趟快排的调整最后移动的元素的位置即可。C语言代码实现如下:

//快速排序的调整函数
int QuickAdjust(int *array,int low,int high){
 int temp = array[low];//本次排序的轴元素
 while(low < high){
  //找出第一个比轴小的数
  while(low < high && array[high] > temp) --high;
  array[low] = array[high];
  //找出第一个比轴大的数
  while(low < high && array[low] < temp) ++low;
  array[high] = array[low];
 }
 array[low] = temp;
 return low;
}
//快速排序
void QuickSort(int *array,int low,int high){
	if(low < high){
	 int prov = QuickAdjust(array,low,high);
     QuickSort(array,low,prov - 1);
	 QuickSort(array,prov + 1,high);
	}
}

二、堆排序

堆排序借助的是完全二叉树的顺序存储结构的特点进行循环调整的一种排序算法。

比如 8,0,3,7,9,5,6,1,4,2存储一棵完全二叉树(下标从1开始),那么这棵二叉树的我们可以很容易画出来:


可以看出每一个节点的左子树下标就是这个节点的下标乘以2。这样我们便可以很方便地将这棵树进行调整。

升序排序的话是循环调整成为大顶堆(根节点比子树大的完全二叉树),堆排序的思想是首先将整个堆调整成为大顶堆,调整方法如下:

1、设有n个节点,选取第n/2个节点也就是9(最后一个具备子树的节点 ),9的子树中最大的节点的值若是比9的值大,那么将9与其子树中最大的节点互换;

2、然后按此法调整K之前的节点(显然都是具备子树的节点),每次只需判断直接的左右孩子即可,但是替换之后需调整替换之后的子树。比如在调整 0这个节点的时候,可以看到0的两个子树均是大顶堆,将子树中大的与0比较,因为9 > 0,所以互换。互换之后需要判断 换后的0 的子树,因为2>0,所以还是要继续将0与2互换。

上图调整之后会变成:


之后循环将根节点(也就是最上面的那个节点)与最后一个节点互换,互换之后,最后一个节点在以后的堆调整都不算在堆里面(因为这个已经是最大的数了)。相当于循环取出最大的数。C语言的实现如下:

//堆排序的调整函数,将节点s调整为大顶堆
void HeapAdjust(int *array,int s,int m){
 int a = 2*s,temp = array[s];
 while(a <= m){
  if(a < m && array[a] < array[a+1]) ++a; //取左右子树中最大的
  //若比根节点小,说明不用调换
  if(array[a] < temp) break;
  //调换位置调整成大顶堆
  array[s] = array[a];
  s = a; //继续调整子树成为大顶堆
  a *= 2;
 }
 array[s] = temp;
}
//对数组array进行堆排,len为该数组长度 
void HeapSort(int *array,int len){
 int i,temp;
 for(i = len/2;i > 0; --i)
     HeapAdjust(array,i,len);
 for(i = len;i > 1; --i){
         temp = array[1];
	 array[1] = array[i];
     array[i] = temp;
     HeapAdjust(array,1,i-1);
 }
}

内容概要:本文档定义了一个名为 `xxx_SCustSuplier_info` 的视图,用于整合和展示客户(Customer)和供应商(Supplier)的相关信息。视图通过连接多个表来获取组织单位、客户账户、站点使用、位置、财务代码组合等数据。对于客户部分,视图选择了与账单相关的记录,并提取了账单客户ID、账单站点ID、客户名称、账户名称、站点代码、状态、付款条款等信息;对于供应商部分,视图选择了有效的供应商及其站点信息,包括供应商ID、供应商名称、供应商编号、状态、付款条款、财务代码组合等。视图还通过外连接确保即使某些字段为空也能显示相关信息。 适合人群:熟悉Oracle ERP系统,尤其是应付账款(AP)和应收账款(AR)模块的数据库管理员或开发人员;需要查询和管理客户及供应商信息的业务分析师。 使用场景及目标:① 数据库管理员可以通过此视图快速查询客户和供应商的基本信息,包括账单信息、财务代码组合等;② 开发人员可以利用此视图进行报表开发或数据迁移;③ 业务分析师可以使用此视图进行数据分析,如信用评估、付款周期分析等。 阅读建议:由于该视图涉及多个表的复杂连接,建议读者先熟悉各个表的结构和关系,特别是 `hz_parties`、`hz_cust_accounts`、`ap_suppliers` 等核心表。此外,注意视图中使用的外连接(如 `gl_code_combinations_kfv` 表的连接),这可能会影响查询结果的完整性。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值