您的位置:首页 > 其它

堆排序

2018-03-17 14:04 162 查看
今天蓝桥杯练习系统炸了,正好就练习一下堆排序和快速排序。
两种排序都比冒泡要高级。快排利用的是递归算法,将key指定一个数(一般指定左边的数)。然后将所有大于key的数字扔在右边,所有小于key的扔在左边。然后分成两块以后,再将左边分成两块右边分成两块如此反复直到一块只有一个数字。
void kuai(int *a,int left,int right)
{
if (left>=right)
{
return;
}
int i=left;
int j=right;
int key=a[left];
while(i<j)
{
while(i<j&&a[j]>=key)
  {
j--;
  }
  a[i]=a[j];
  while(i<j&&a[i]<=key)
  {
i++;
  }
  a[j]=a[i];
}

a[i]=key;
kuai(a,left,i-1);
kuai(a,i+1,right);

}
上面a是待排序的数组,left和right在初始输入时为0和数组的个数。这里的技巧是巧妙运用while。一般初学者都觉得while是用来执行的。实际上,while在这里还可以过滤作用。就是不符合我期望的情况,我就让他过滤掉,一直到我的i或者j到达我所需要的点。

堆排序说实话理解起来有一定的难度。因为这里涉及一个大顶堆的概念,可以自行百度。堆排序要求从初始到最后一直都要是大顶堆,但是所含的个数是逐步减少的。
举个例子对int data[] = {6,5,8,4,7,9,1,3,2};这个数组进行堆排序。
#include<stdio.h>
void adjustHeap(int paraml,int j,int inNums[])//不要用*就用[] 
{
int temp=inNums[paraml];
int k;
for (k=2*paraml+1;k<j;k=k*2+1)
{
if (k+1<j&&inNums[k]<inNums[k+1])//k+1<j千万别漏了 
{
k++;
}
if (inNums[k]>temp)
{
inNums[paraml]=inNums[k];
paraml=k;
}
else
break;
}
inNums[paraml]=temp;
}
void HeapSort(int nums,int inNums[])
{
//造大根堆
int i,j;
for (i=nums/2-1;i>=0;i--)//这一块别写错成i++ 
{
adjustHeap(i,nums,inNums);

int temp;
for (j=nums-1;j>0;j--)
{
temp=inNums[0];
inNums[0]=inNums[j];
inNums[j]=temp;
adjustHeap(0,j,inNums);
}

}
int main() 
{
    int data[] = {6,5,8,4,7,9,1,3,2};
    int len = sizeof(data) / sizeof(int);//非常精巧,类似strlen 
    HeapSort(len,data);
    int i;
for (int i=0;i<len;i++)
printf("%d",data[i]); 
    return 0;
}

中间我自己写的时候也出过bug,正常把--写错++。这段程序很精巧的地方在于temp的使用。在快速排序中temp虽然有一定类似的感觉,但是只有在堆排序中,有这种不交换只复制的操作。所以在程序运行中,二叉树会出现有两个相同数字的情况。不用担心,那个丢掉的数字正在temp里。建议自己画一下二叉树。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  排序