C++实现堆排序实例介绍

 更新时间:2021年12月22日 09:21:55   作者:NEU!  
大家好,本篇文章主要讲的是C++实现堆排序实例介绍,感兴趣的同学赶快来看一看吧,对你有帮助的话记得收藏一下,方便下次浏览

概述:

堆排序是利用构建“堆”的方法确定具有最大值的数据元素,并把该元素与最后位置上的元素交换。可将任意一个由n个数据元素构成的序列按照(a1,a2,...,an),按照从左到右的顺序按层排列构成一棵与该序列对应的完全二叉树。

一棵完全二叉树是一个堆,当且仅当完全二叉树的每棵子树的根值ai≥其左子树的根值a2i,同时ai≥其右子树的根值a 2i+1 (1<i<n/2)。

实现堆排序需要实现两个问题:

如何由无序序列建成一个堆?如何在输出堆顶元素之后,调整剩余元素成为一个新的堆?

思路:

堆排序算法思想:

1、从最后一个非叶子节点逐步到树根,对每个子树进行调整堆。

2、重复n-1次如下处理:将堆的根与最后一个叶子交换,除最后一个叶子之外剩余部分再调整为堆。

调整堆算法思想:

1、将树根与其左右子树根值最大者交换;(大顶堆)

2、对交换后的左(或右)子树重复过程1,直到左(或右)子树为堆。

时间复杂度O(nlogn)

代码:

调整堆算法:

void HeapAdjust(int *array,int i,int length){	//调整堆 
	int leftChild=2*i+1;		//定义左右孩子 
	int rightChild=2*i+2;
	int max=i;		//初始化,假设左右孩子的双亲节点就是最大值 
	if(leftChild<length&&array[leftChild]>array[max]){
		max=leftChild;
	}
	if(rightChild<length&&array[rightChild]>array[max]){
		max=rightChild;
	}
	if(max!=i){		//若最大值不是双亲节点,则交换值 
		swap(array[max],array[i]);
		HeapAdjust(array,max,length);	//递归,使其子树也为堆 
	}
}

堆排序算法:

void HeapSort(int *array,int length){	//堆排序 
	for(int i=length/2-1;i>=0;i--){		//从最后一个非叶子节点开始向上遍历,建立堆 
		HeapAdjust(array,i,length);
	}
	for(int j=length-1;j>0;j--){		//调整堆 ,此处不需要j=0  
		swap(array[0],array[j]);
		HeapAdjust(array,0,j);		//因为每交换一次之后,就把最大值拿出(不再参与调整堆),第三个参数应该写j而不是length 
		Print(array,length); 
	}
}

完整代码:

//堆排序
#include <iostream> 
using namespace std;
void Print(int array[],int length){	//每执行一次打印一次序列 
	for(int i=0;i<length;i++){
		cout<<array[i]<<" ";
	}
	cout<<endl;
}
void HeapAdjust(int *array,int i,int length){	//调整堆 
	int leftChild=2*i+1;		//定义左右孩子 
	int rightChild=2*i+2;
	int max=i;		//初始化,假设左右孩子的双亲节点就是最大值 
	if(leftChild<length&&array[leftChild]>array[max]){
		max=leftChild;
	}
	if(rightChild<length&&array[rightChild]>array[max]){
		max=rightChild;
	}
	if(max!=i){		//若最大值不是双亲节点,则交换值 
		swap(array[max],array[i]);
		HeapAdjust(array,max,length);	//递归,使其子树也为堆 
	}
}
void HeapSort(int *array,int length){	//堆排序 
	for(int i=length/2-1;i>=0;i--){		//从最后一个非叶子节点开始向上遍历,建立堆 
		HeapAdjust(array,i,length);
	}
	for(int j=length-1;j>0;j--){		//调整堆 ,此处不需要j=0  
		swap(array[0],array[j]);
		HeapAdjust(array,0,j);		//因为每交换一次之后,就把最大值拿出(不再参与调整堆),第三个参数应该写j而不是length 
		Print(array,length); 
	}
}
int main(){
	int array[]={49,38,65,97,76,13,27,49};
	int length=sizeof(array)/sizeof(*array);
	Print(array,length);			//先打印原始序列 
	HeapSort(array,length);
	return 0;
}

运行示例:

第一行是原始序列,第二到八行分别是经过7次调整堆所得到的序列。

到此这篇关于C++实现堆排序实例介绍的文章就介绍到这了,更多相关C++堆排序内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • C++类与对象及构造函数析构函数基础详解

    C++类与对象及构造函数析构函数基础详解

    这篇文章主要为大家介绍了C++类与对象及构造函数析构函数基础详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-04-04
  • 详解C++ 编写String 的构造函数、拷贝构造函数、析构函数和赋值函数

    详解C++ 编写String 的构造函数、拷贝构造函数、析构函数和赋值函数

    这篇文章主要介绍了详解C++ 编写String 的构造函数、拷贝构造函数、析构函数和赋值函数的相关资料,这里提供实例帮助大家理解掌握这部分内容,需要的朋友可以参考下
    2017-08-08
  • C++实现汉诺塔算法经典实例

    C++实现汉诺塔算法经典实例

    这篇文章主要介绍了C++实现汉诺塔算法经典实例,代码简洁高效,对于学习算法的朋友有一定的借鉴价值,需要的朋友可以参考下
    2014-07-07
  • C++OOP对象和类的详细讲解

    C++OOP对象和类的详细讲解

    这篇文章主要介绍了C++面相对象编程中的类与对象的特性与概念,OOP面向对象语言相对C语言这样面相过程的语言来说具有类和对象以及方法这样的特性,需要的朋友可以参考下
    2021-08-08
  • C++详解如何实现两个线程交替打印

    C++详解如何实现两个线程交替打印

    这篇文章主要介绍了使用C++库实现两个线程交替打印,一个线程打印奇数、一个线程打印偶数,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2022-08-08
  • C++ pimpl机制详细讲解

    C++ pimpl机制详细讲解

    PIMPL 是 C++ 中的一个编程技巧,意思为指向实现的指针。具体操作是把类的实现细节放到一个单独的类中,并用一个指针进行访问
    2022-08-08
  • C语言利用EasyX实现绘制足球图案

    C语言利用EasyX实现绘制足球图案

    这篇文章主要为大家详细介绍了C语言如何利用EasyX绘图库实现绘制一个简单的足球图案,文中的示例代码讲解详细,感兴趣的小伙伴可以了解一下
    2022-11-11
  • c++仿函数和函数适配器的使用详解

    c++仿函数和函数适配器的使用详解

    这篇文章主要介绍了c++仿函数和函数适配器的使用详解,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2020-12-12
  • 详解如何将Spire.PDF for C++集成到C++程序中

    详解如何将Spire.PDF for C++集成到C++程序中

    Spire.PDF for C++ 是一个专业的 PDF 库,供开发人员在任何类型的 C++ 应用程序中阅读、创建、编辑和转换 PDF 文档,本文主要介绍了两种不同的方式将 Spire.PDF for C++ 集成到您的 C++ 应用程序中,希望对大家有所帮助
    2023-11-11
  • C语言的动态内存管理你了解吗

    C语言的动态内存管理你了解吗

    这篇文章主要为大家详细介绍了C语言的动态内存管理,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下,希望能够给你带来帮助
    2022-03-03

最新评论