数据结构一一堆排序
2018-01-29 11:51
197 查看
堆排序:一种树形选择排序,是对直接选择排序的有效改进。
综上描述,它的实现需要解决两个问题:
1、如何由一个无序序列构建成一个堆?
2、如何在输出堆顶元素后,调整剩余元素成为一个新的堆?
无序序列构建成一个堆的代码如下:
/**
* 初始堆进行调整
* 将L->iElem[0..length-1]建成堆
* 调整完之后第一个元素是序列的最小的元素
*/
void BuildingHeap(SqList* L)
{
//最后一个有孩子的节点的位置 i= (length -1) / 2
for (int i = (L->iLength -1) / 2 ; i >= 0; --i)
HeapAdjust(L,i,L->iLength);
}
#include <iostream>
#include <time.h>
using namespace std;
#define MAX_SIZE 9
typedef struct
{
int iElem[MAX_SIZE];
int iLength;
}SqList;
void PrintList(SqList L)
{
for (int i=0;i<L.iLength;i++)
{
cout<<L.iElem[i]<<" ";
}
cout<<endl;
}
void CreateList(SqList* L)
{
int i = 0;
L->iLength = 0;
srand((unsigned)time(NULL));
int iData[MAX_SIZE]={50,10,90,30,70,40,80,60,20};
for (i=0; i<MAX_SIZE; i++)
{
//L->iElem[i] = rand()%100;
L->iElem[i] = iData[i];
L->iLength++;
}
PrintList(*L);
}
void Swap(SqList* L,int a,int b)
{
int temp = L->iElem[a];
L->iElem[a] = L->iElem[b];
L->iElem[b] = temp;
}
void HeapAdjust(SqList* L,int s, int length)
{
int tmp = L->iElem[s];
int child = 2*s+1; //左孩子结点的位置。(i+1 为当前调整结点的右孩子结点的位置)
while (child < length)
{
if(child+1 <length && L->iElem[child]<L->iElem[child+1]) // 如果右孩子大于左孩子(找到比当前待调整结点大的孩子结点)
{
++child ;
}
if(L->iElem[s]<L->iElem[child]) // 如果较大的子结点大于父结点
{
L->iElem[s] = L->iElem[child]; // 那么把较大的子结点往上移动,替换它的父结点
s = child; // 重新设置s ,即待调整的下一个结点的位置
child = 2*s+1;
}
else // 如果当前待调整结点大于它的左右孩子,则不需要调整,直接退出
{
break;
}
L->iElem[s] = tmp; // 当前待调整的结点放到比其大的孩子结点位置上
}
PrintList(*L);
}
/**
* 初始堆进行调整
* 将L->iElem[0..length-1]建成堆
* 调整完之后第一个元素是序列的最小的元素
*/
void BuildingHeap(SqList* L)
{
//最后一个有孩子的节点的位置 i= (length -1) / 2
for (int i = (L->iLength -1) / 2 ; i >= 0; --i)
HeapAdjust(L,i,L->iLength);
}
/**
* 堆排序算法
*/
void HeapSort(SqList* L)
{
//初始堆
BuildingHeap(L);
//从最后一个元素开始对序列进行调整
for (int i = L->iLength - 1; i > 0; --i)
{
//交换堆顶元素L->iElem[0]和堆中最后一个元素
Swap(L,0,i);
//每次交换堆顶元素和堆中最后一个元素之后,都要对堆进行调整
HeapAdjust(L,0,i);
}
}
int main()
{
SqList L;
CreateList(&L);
HeapSort(&L);
return 0;
}运行结果:
综上描述,它的实现需要解决两个问题:
1、如何由一个无序序列构建成一个堆?
2、如何在输出堆顶元素后,调整剩余元素成为一个新的堆?
无序序列构建成一个堆的代码如下:
/**
* 初始堆进行调整
* 将L->iElem[0..length-1]建成堆
* 调整完之后第一个元素是序列的最小的元素
*/
void BuildingHeap(SqList* L)
{
//最后一个有孩子的节点的位置 i= (length -1) / 2
for (int i = (L->iLength -1) / 2 ; i >= 0; --i)
HeapAdjust(L,i,L->iLength);
}
void HeapAdjust(SqList* L,int s, int length) { int tmp = L->iElem[s]; int child = 2*s+1; //左孩子结点的位置。(i+1 为当前调整结点的右孩子结点的位置) while (child < length) { if(child+1 <length && L->iElem[child]<L->iElem[child+1]) // 如果右孩子大于左孩子(找到比当前待调整结点大的孩子结点) { ++child ; } if(L->iElem[s]<L->iElem[child]) // 如果较大的子结点大于父结点 { L->iElem[s] = L->iElem[child]; // 那么把较大的子结点往上移动,替换它的父结点 s = child; // 重新设置s ,即待调整的下一个结点的位置 child = 2*s+1; } else // 如果当前待调整结点大于它的左右孩子,则不需要调整,直接退出 { break; } L->iElem[s] = tmp; // 当前待调整的结点放到比其大的孩子结点位置上 } PrintList(*L); }将堆顶元素输出,即与最后一个元素进行交换,然后调整剩余元素成为一个新的堆
//从最后一个元素开始对序列进行调整 for (int i = L->iLength - 1; i > 0; --i) { //交换堆顶元素L->iElem[0]和堆中最后一个元素 Swap(L,0,i); //每次交换堆顶元素和堆中最后一个元素之后,都要对堆进行调整 HeapAdjust(L,0,i); }整体代码实现如下:
#include <iostream>
#include <time.h>
using namespace std;
#define MAX_SIZE 9
typedef struct
{
int iElem[MAX_SIZE];
int iLength;
}SqList;
void PrintList(SqList L)
{
for (int i=0;i<L.iLength;i++)
{
cout<<L.iElem[i]<<" ";
}
cout<<endl;
}
void CreateList(SqList* L)
{
int i = 0;
L->iLength = 0;
srand((unsigned)time(NULL));
int iData[MAX_SIZE]={50,10,90,30,70,40,80,60,20};
for (i=0; i<MAX_SIZE; i++)
{
//L->iElem[i] = rand()%100;
L->iElem[i] = iData[i];
L->iLength++;
}
PrintList(*L);
}
void Swap(SqList* L,int a,int b)
{
int temp = L->iElem[a];
L->iElem[a] = L->iElem[b];
L->iElem[b] = temp;
}
void HeapAdjust(SqList* L,int s, int length)
{
int tmp = L->iElem[s];
int child = 2*s+1; //左孩子结点的位置。(i+1 为当前调整结点的右孩子结点的位置)
while (child < length)
{
if(child+1 <length && L->iElem[child]<L->iElem[child+1]) // 如果右孩子大于左孩子(找到比当前待调整结点大的孩子结点)
{
++child ;
}
if(L->iElem[s]<L->iElem[child]) // 如果较大的子结点大于父结点
{
L->iElem[s] = L->iElem[child]; // 那么把较大的子结点往上移动,替换它的父结点
s = child; // 重新设置s ,即待调整的下一个结点的位置
child = 2*s+1;
}
else // 如果当前待调整结点大于它的左右孩子,则不需要调整,直接退出
{
break;
}
L->iElem[s] = tmp; // 当前待调整的结点放到比其大的孩子结点位置上
}
PrintList(*L);
}
/**
* 初始堆进行调整
* 将L->iElem[0..length-1]建成堆
* 调整完之后第一个元素是序列的最小的元素
*/
void BuildingHeap(SqList* L)
{
//最后一个有孩子的节点的位置 i= (length -1) / 2
for (int i = (L->iLength -1) / 2 ; i >= 0; --i)
HeapAdjust(L,i,L->iLength);
}
/**
* 堆排序算法
*/
void HeapSort(SqList* L)
{
//初始堆
BuildingHeap(L);
//从最后一个元素开始对序列进行调整
for (int i = L->iLength - 1; i > 0; --i)
{
//交换堆顶元素L->iElem[0]和堆中最后一个元素
Swap(L,0,i);
//每次交换堆顶元素和堆中最后一个元素之后,都要对堆进行调整
HeapAdjust(L,0,i);
}
}
int main()
{
SqList L;
CreateList(&L);
HeapSort(&L);
return 0;
}运行结果:
相关文章推荐
- 第十六周--数据结构--项目一-- 插入排序之直接插入排序
- 数据结构――排序(php代码实现)
- 数据结构--排序
- 【Java数据结构】排序
- 数据结构 排序 插入排序
- 数据结构--排序
- 数据结构和算法总结(二):排序
- 数据结构中的三种排序(java)
- 数据结构中的排序-快速排序法(四)
- 【数据结构第八周】排序(下)【快速排序】
- 数据结构-排序算法-直接插入排序
- 数据结构--快速排序
- 数据结构:外排序-多路归并
- 数据结构- 快速排序
- C++代码,数据结构-内部排序-交换排序-起泡排序
- 数据结构中有关“排序”的习题
- 数据结构-选择排序
- 数据结构之基数排序
- 【数据结构】将一组数据升序排序(利用堆排序)
- 数据结构排序之快速排序