堆排序

以下内容为程序代码:
int heapsort(int p[],int n);

/*
* 堆排序算法在 1964 年由 J. Williams 发明。
* 不稳定,不需要辅助空间。
*/
static int insertheap(int p[],int i,int n);

int heapsort(int p[],int n)
{
int op=0;
int i,temp;

/* 从叶子节点建立对应的上级根节点来建造堆 */
for (i=n/2-1; i>=0; i--) {
  op+=insertheap(p,i,n);
}
/* 选择堆顶的最大值与尾部的值交换,
  * 把这个值重新插入堆 */
for (i=n-1; i>=1; i--) {
  temp=p[0];
  p[0]=p;
  p=temp;
  op++;
  op+=insertheap(p,0,i);

}
return op; /* 返回比较操作数 */
}

static int insertheap(int p[],
    int i, /* 要插入的元素的位置 */
    int n) /* 列表长度 */
{
int op=0;
int j,temp;
temp=p; /* 要插入的元素已经在根节点位置上,保存它的值 */
j=i*2+1; /* 要比较的节点位置是当前根节点的左子节点 */

/* 要比较的节点位置在列表范围内 */
while (j<n) {
  /* 要比较的左子节点有对应的子节点,并且
   * 当前根节点的左子节点小于右子节点 */
  if (j<n-1 && p[j]<p[j+1])
   j++; /* 要比较的节点位置是当前根节点的右子节点 */
  /* 要插入的值小于当前做比较的子节点 */
  if (temp<p[j]) {
   p=p[j];  /* 做比较的子节点的值上移到当前根节点 */
   i=j; /* 当前根节点下移到做比较的子节点的位置上 */
   j=i*2+1; /* 要比较的节点位置是当前根节点的的左子节点 */
  }
  /* 要插入的值小于当前做比较的子节点 */
        else
   break; /* 停止下移 */
  op+=2;
  /* 分别与左右子节点做比较操作。
   * 这是堆排序比快速排序多做比较操作的根源 */
}
p=temp; /* 插入要插入的值 */
op++;
return op;
}

/* 要比较的节点位置在列表范围内 */
while (j<n) {
  /* 要比较的左子节点有对应的子节点,并且
   * 当前根节点的左子节点小于右子节点 */
  if (j<n-1 && p[j]<p[j+1])
   j++; /* 要比较的节点位置是当前根节点的右子节点 */
  /* 要插入的值小于当前做比较的子节点 */
  if (temp<p[j]) {
   p=p[j];  /* 做比较的子节点的值上移到当前根节点 */
   i=j; /* 当前根节点下移到做比较的子节点的位置上 */
   j=i*2+1; /* 要比较的节点位置是当前根节点的的左子节点 */
  }
  /* 要插入的值小于当前做比较的子节点 */
        else
   break; /* 停止下移 */
  op+=2;
  /* 分别与左右子节点做比较操作。
   * 这是堆排序比快速排序多做比较操作的根源 */
}
p=temp; /* 插入要插入的值 */
op++;
return op;
}

static int insertheap(int p[],
    int i, /* 要插入的元素的位置 */
    int n) /* 列表长度 */
{
int op=0;
int j,temp;
temp=p; /* 要插入的元素已经在根节点位置上,保存它的值 */
j=i*2+1; /* 要比较的节点位置是当前根节点的左子节点 */

/* 要比较的节点位置在列表范围内 */
while (j<n) {
  /* 要比较的左子节点有对应的子节点,并且
   * 当前根节点的左子节点小于右子节点 */
  if (j<n-1 && p[j]<p[j+1])
   j++; /* 要比较的节点位置是当前根节点的右子节点 */
  /* 要插入的值小于当前做比较的子节点 */
  if (temp<p[j]) {
   p=p[j];  /* 做比较的子节点的值上移到当前根节点 */
   i=j; /* 当前根节点下移到做比较的子节点的位置上 */
   j=i*2+1; /* 要比较的节点位置是当前根节点的的左子节点 */
  }
  /* 要插入的值小于当前做比较的子节点 */
        else
   break; /* 停止下移 */
  op+=2;
  /* 分别与左右子节点做比较操作。
   * 这是堆排序比快速排序多做比较操作的根源 */
}
p=temp; /* 插入要插入的值 */
op++;
return op;
}

/* 要比较的节点位置在列表范围内 */
while (j<n) {
  /* 要比较的左子节点有对应的子节点,并且
   * 当前根节点的左子节点小于右子节点 */
  if (j<n-1 && p[j]<p[j+1])
   j++; /* 要比较的节点位置是当前根节点的右子节点 */
  /* 要插入的值小于当前做比较的子节点 */
  if (temp<p[j]) {
   p=p[j];  /* 做比较的子节点的值上移到当前根节点 */
   i=j; /* 当前根节点下移到做比较的子节点的位置上 */
   j=i*2+1; /* 要比较的节点位置是当前根节点的的左子节点 */
  }
  /* 要插入的值小于当前做比较的子节点 */
        else
   break; /* 停止下移 */
  op+=2;
  /* 分别与左右子节点做比较操作。
   * 这是堆排序比快速排序多做比较操作的根源 */
}
p=temp; /* 插入要插入的值 */
op++;
return op;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值