您的位置:首页 > 理论基础 > 数据结构算法

堆数据结构与堆排序的个人理解

2013-09-11 19:25 330 查看
关于堆排序,已经研究了整整一个星期,不论是从网络论坛CSDN或者图书馆书籍中,都获益匪浅,但是知识内容都是差不多的,如何理解是自己的。这里我就写一下自堆排序的认识。


首先要弄清楚的观点是:

1、堆是一种数据结构

通常来说,一种数据结构所必备的操作有三个:初始化,插入数据,删除数据。堆也不例外。因此一旦我们写出了数据结构的基本操作,我们可以将其封装起来,用于其它的地方。比如可以用堆这种数据结构来进行其它的排序操作的实现。上升只看父节点,下降只看儿子。

2、本文中堆的存储是基于顺序数组的

因为数组的实现可以是链式或者顺序,这里实现的时候是一般情况,就是基于顺序数组的,使用顺序数组来存储堆的内容。


其中会用到的一个交换两个元素的小函数:

void exchange(int *a,int *b)
{
int temp=*a;
*a=*b;
*b=temp;
}


数据结构中的:


插入方法:

我们每次思考插入方法的时候,堆中的数据都是从数组的最后一个元素插入的。因此每次在插入一个元素以后,这个数组不再满足一个堆的条件,因此要恢复堆,基本思想就是将插入的值a[i]与他的父亲比较,再决定是否交换两者的值,一直循环,直到堆顶,直观上来看,就是新插入的元素,由堆底像堆顶上升的过程:



//堆的插入操作
void MinHeapFixUp(int a[],int i)//在结点位子插入,然后上升
{
int j;
j=(i-1)/2;
while(j>=0&&i!=0)
{
if (a[j]<a[i]) break;
exchange(&a[i],&a[j]);
i=j;
j=(i-1)/2;
}
}


void MinHeapAddNumber(int a[],int n,int nNum)//每次加入都是从数组末尾加入进去
{
a
=nNum;
MinHeapFixUp(a,n);
}


删除方法:

按照堆的定义,堆中每次都只能删除第0个数据。因此为了便于恢复堆,实际的操作是将最后一个数据的数据的值赋值给根的结点,然后再从根的结点开始进行一次从上向下的调整。调整时现在左右儿子中找最小的,如果父亲结点比这个最小的还要小,说明不需要调整。反之,交换两者,继续考虑其父亲。其过程相当于,从根结点将一根数据下沉的过程。

/堆删除操作:每次都删除第i个数据,然后用最后一个数据来填充删除的位子,然后恢复成最小堆
//参数中i表示从节点i开始调整,就是说i的父亲以上都已经调整完毕,n代表里面的结点总数
void MinHeapFixdown(int a[],int i,int n)
{

int left=2*i+1;
int right=left+1;
int small=left;
while(left<n)//父节点比儿子的两个结点还要小,就停止循环
{
//找出左右孩子最大的
if(right<n)
{
if (a[left]<=a[right])
{
small=left;
}
else small=right;
if (a[small]<a[i])
{
exchange(&a[small],&a[i]);
}
else break;
}
else
{
small=left;
if (a[small]<a[i])
{
exchange(&a[small],&a[i]);
}
else break;
}
i=small;
left=2*i+1;
right=left+1;
}
}



void MinHeapDeleteNumber(int a[],int n)
{
exchange(&a[0],&a[n-1]);
MinHeapFixdown(a,0,n-1);
}


初始化:

初始化有两种产生最小堆的方法:一个是利用Fixdown,另外一个是利用Fixup;

void MakeMinHeap1(int a[], int n)
{
for (int i = n/2-1; i >= 0; i--)
MinHeapFixdown(a, i, n);
}


void MakeMinHeap2(int a[],int n)
{
for (int i=0;i<n;i++)
{
MinHeapFixUp(a,i);
}
}


最后:利用堆这种数据结构实现堆排序:

void MinheapsortTodescendarray(int a[], int n)
{
for (int i = n; i >=1 ; i--)
{
MinHeapDeleteNumber(a,i);
}
}


void main()
{
int arr[]={0,1,5,4,2,7,6,8};
//MakeMinHeap1(arr,8);
MinheapsortTodescendarray(arr,8);
for (int i=0;i<8;i++)
{
printf("%d ",arr[i]);
}
printf("\n");

MakeMinHeap1(arr,8);
for (int i=0;i<8;i++)
{
printf("%d ",arr[i]);
}
printf("\n");
MakeMinHeap2(arr,8);
for (int i=0;i<8;i++)
{
printf("%d ",arr[i]);
}
printf("\n");

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: