堆排序(如何构造堆,在堆排序过程中的比较方法)

ltolll 2008-04-07 03:27:40
题目:无序序列{59,11,26,34,17,91,25},要用堆排序得到{11,17,25},共执行多少次比较?

我的问题是:如何从无序序列构造堆?
我用的是清华严蔚敏的教材,上面说:'从一个无序序列建堆的过程就是一个反复"筛选"的过程.'
而从书上又可以了解到"筛选"是作用于二叉树的操作,这棵二叉树是从哪来的呢,书上给的例子也是直接就有一棵二叉树,这点我不太理解.如果说这棵二叉树是通过一定的规则构造的,那么我的问题是:如何从一组无序序列构造堆所对应的二叉树呢?

就以上面的无序序列作为例子吧.
...全文
2221 8 打赏 收藏 转发到动态 举报
写回复
用AI写文章
8 条回复
切换为时间正序
请发表友善的回复…
发表回复
随风秀舞 2011-12-26
  • 打赏
  • 举报
回复
crhacker 正解。建堆的时间复杂度O(n)
六六木木 2010-07-16
  • 打赏
  • 举报
回复
牛人真多。。
ltolll 2008-04-12
  • 打赏
  • 举报
回复
TO:探索
多谢.
无病呻吟2 2008-04-08
  • 打赏
  • 举报
回复
建堆思想:
首先将无序序列一次作为一个完全二叉树存储,也就是你上面的例子中59作为根,依次11,26作为孩子节点等等延续。
然后从第n/2个节点开始,一直到第一个节点59,进行堆的调整,这个过程叫建堆。

如果是大根堆,那么第一个元素就是最大的节点,取出最大节点和最后一个节点元素交换,然后堆的大小相应减1,然后从根开始调整堆!!
ltolll 2008-04-08
  • 打赏
  • 举报
回复
谢谢两位.
其实我只是想要建堆的思想,不用给我这么多代码,里面还有类模板,看不懂.

TO:非女
"...建堆算法应该在前面已经出现了,"
我之所以发问就是因为没找到,我用书后面的关键字索引查的也没有.
如果有,哪位知道,能否告诉我多少页?
太乙 2008-04-07
  • 打赏
  • 举报
回复
debug.h

class OutOfBounds
{
};

maxheap.h

#include <vector>
#include <iostream>
#include "debug.h"
using namespace std;

template<class T>
class MaxHeap
{
public:
MaxHeap(int MaxHeapSize=10);
~MaxHeap(){delete []heap;}
int Size()const{return CurrentSize;}
T Max()
{
if (CurrentSize==0)throw OutOfBounds();
return heap[1];
}
MaxHeap<T>&Insert(const T&x);
MaxHeap<T>&DeleteMax(T&x);
void Initialize(T a[],int size,int ArraySize);
void Deactivate(){heap=0;}
void ShowMaxHeap();
protected:
private:
void Print(int num,int c,vector<bool>&isend);
int CurrentSize,MaxSize;
T *heap;
};
template<class T>
MaxHeap<T>::MaxHeap(int MaxHeapSize/* =10 */)
{
MaxSize=MaxHeapSize;
heap=new T[MaxSize+1];
CurrentSize=0;
}
template<class T>
MaxHeap<T>&MaxHeap<T>::Insert(const T&x)
{
if (CurrentSize==MaxSize)
{
throw NoMem();
}
int i=++CurrentSize;
while (i!=1&&x>heap[i/2])
{
heap[i]=heap[i/2];
i/=2;
}
heap[i]=x;
return *this;
}
template<class T>
MaxHeap<T>&MaxHeap<T>::DeleteMax(T&x)
{
if (CurrentSize==0)
{
throw OutOfBounds();
}
x=heap[1];
T y=heap[CurrentSize--];
int i=1,ci=2;
while (ci<=CurrentSize)
{
if (ci<CurrentSize&&heap[ci]<heap[ci+1])
{
ci++;
}
if (y>=heap[ci])
{
break;
}
heap[i]=heap[ci];
i=ci;
ci*=2;
}
heap[i]=y;
return *this;
}
template<class T>
void MaxHeap<T>::Initialize(T a[],int size,int ArraySize)
{
delete []heap;
heap=a;
CurrentSize=size;
MaxSize=ArraySize;
for (int i=CurrentSize/2;i>=1;i--)
{
T y=heap[i];
int c=2*i;
while (c<=CurrentSize)
{
if (c<CurrentSize&&heap[c]<heap[c+1])
{
c++;
}
if (y>=heap[c])
{
break;
}
heap[c/2]=heap[c];
c*=2;
}
heap[c/2]=y;
}
}
template<class T>
void MaxHeap<T>::ShowMaxHeap()
{
if (!heap)
{
cout<<"空树!"<<endl;
exit(1);
}
vector<bool> bIsEnd;
bIsEnd.push_back(0);
bIsEnd[0]=1;
Print(1,0,bIsEnd);
cout<<endl;
}
template<class T>
void MaxHeap<T>::Print(int num, int c, vector<bool>& isend)
{
if (num>CurrentSize)
{
return;
}
if(num==1)
{
cout<<"Root:\n"<<heap[1]<<endl;
}
else
{
for(int j=0;j<c;j++)
{//─└├│
if(isend[j]==0)
if(j!=c-1)cout<<"│";
else cout<<"├";
else
if(j!=c-1)cout<<" ";
else cout<<"└";
if(j!=c-1)cout<<" ";
else cout<<"─";
}
cout<<" "<<heap[num];
if (num%2)
{
cout<<"R";
}
else cout<<"L";
cout<<endl;
}
int len=2;
if (num==CurrentSize/2&&!(CurrentSize%2))
{
len=1;
}
else if (num>CurrentSize/2)
{
len=0;
}
for(int i=1;i<=len;i++)
{
if(isend.size()==c)isend.push_back(0);

else isend[c]=0;
if(i==len)
if(isend.size()==c)isend.push_back(1);
else isend[c]=1;
if(i==1)Print(2*num,c+1,isend);
if(i==2)Print(2*num+1,c+1,isend);
}
}


//main.cpp

#include "maxheap.h"
void Pause()
{
cout<<endl<<endl<<endl;
system("pause");
cout<<endl<<endl<<endl;
}
template<class T>
void HeapSort(T a[],int n)
{
MaxHeap<T>H(1);
H.Initialize(a,n,n);
cout<<"用输入的数初始化一个最大堆,结果如下:"<<endl;
H.ShowMaxHeap();
Pause();
T x;
for (int i=n-1;i>=1;i--)
{
H.DeleteMax(x);
cout<<"删除最大堆的根即最大元素"<<x<<",将其放入原数组中第"<<i+1<<"个位子!"<<endl;
a[i+1]=x;
cout<<endl<<"此时数组为:\n";
for (int j=i+1;j<=n;j++)
{
cout<<a[j]<<" ";
}
cout<<endl;
Pause();
cout<<"重建最大堆,结果为:"<<endl;
H.ShowMaxHeap();
Pause();
}
H.Deactivate();
}
void main()
{
try
{
cout<<"请输入要排序的个数:"<<endl;
int size;
cin>>size;
int *a=new int[size+1];
int e;
cout<<"请输入要排序的数:"<<endl;
for (int i=1;i<=size;i++)
{
cin>>e;
a[i]=e;
}
HeapSort(a,size);
cout<<"最后结果为:"<<endl;
for (i=1;i<=size;i++)
{
cout<<a[i]<<" ";
}
cout<<endl;
}
catch (OutOfBounds)
{
cout<<"越界!\n";
}

}

yydrewdrew 2008-04-07
  • 打赏
  • 举报
回复
#define PARENT(i)  ((i) / 2)
#define LEFT(i) ((i) * 2)
#define RIGHT(i) ((i) * 2 + 1)
#define RELOCAL(i) ((i) - 1)
template <class T>
void MaxHeapify(T *array,const size_t length,const size_t i)
{
if (NULL == array || length == 0 || 0 == i || i > length)
{
return;
}
if (LEFT(i) <= length)
{
if(array[RELOCAL(i)] < array[RELOCAL(LEFT(i))])
{
Swap(array[RELOCAL(i)],array[RELOCAL(LEFT(i))]);
}
}
if (RIGHT(i) <= length)
{
if (array[RELOCAL(i)] < array[RELOCAL(RIGHT(i))])
{
Swap(array[RELOCAL(i)],array[RELOCAL(RIGHT(i))]);
}
}
MaxHeapify(array,length,LEFT(i));
MaxHeapify(array,length,RIGHT(i));
return;
}
template <class T>
void BuildMaxHeap(T *array,const size_t length)
{
if (array == NULL || length <= 1)
{
return;
}
size_t i = length/2;
while (i != 0)
{
MaxHeapify(array,length,i);
--i;
}
return;
}
template <class T>
void HeapSort(T *array,const size_t length)
{
if (array == NULL || length <= 1)
{
return;
}
BuildMaxHeap(array,length);
size_t l = length;
while (l != 0)
{
swap(array[0],array[RELOCAL(l)]);
--l;
MaxHeapify(array,l,1);
}
return;
}

我弄得一个堆排序程序
medie2005 2008-04-07
  • 打赏
  • 举报
回复
通过建堆算法。
也就是建立你说的“书上给的例子也是直接就有一棵二叉树”的那棵二叉树。这是堆排序的先决条件。只有无序序列已经是堆了,用堆排序算法才可以起到排序的效果。建堆算法应该在前面已经出现了,所以作者才直接给出了无序序列的堆形式(也就是那棵二叉树)。

33,010

社区成员

发帖
与我相关
我的任务
社区描述
数据结构与算法相关内容讨论专区
社区管理员
  • 数据结构与算法社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧