堆排序(非递归)

来源:互联网 发布:程序编程培训班 编辑:程序博客网 时间:2024/04/25 17:08

概述

在上一篇文章中提到了堆排序的递归算法,递归算法相对于非递归算来来说主要有以下优点:

  1. 将原问题划分为一个规模更小的子问题(分治法)。
  2. 代码结构清晰,代码量少,可读性强。

但同时递归也存在以下缺点:

  1. 递归调用函数,时间开销大。
  2. 递归太深容易导致堆栈溢出。

为了能解决上述两个缺点,本文采用了非递归实现了非递归版本的堆排序算法。但需要注意的是,非递归版的堆排序算法,减少了函数的调用次数,避免了堆栈溢出的可能,但是其代码相对较为复杂,且不容易理解。

堆排序实现(非递归版)

#include <stdio.h>#define LEFT(i)     (((i) << 1) + 1)#define RIGHT(i)    (((i) << 1) + 2)#define PARENT(i)   (((i) - 1) >> 1)void heap_sort(int *A, int len){  int l, r, largest;  int i, j, tmp;  i = PARENT(len - 1); /* Get the last non-leaf node */  while (i >= 0) { /* Build the heap */    l = LEFT(i);    r = RIGHT(i);    largest = i;    if (l < len && A[l] > A[largest]) {      largest = l;    }    if (r < len && A[r] > A[largest]) {      largest = r;    }    if (largest != i) {      tmp = A[i];      A[i] = A[largest];      A[largest] = tmp;      i = largest;    } else {      i--;    }  }  len--;  while (len > 0) {    tmp = A[0];          /* Sort */    A[0] = A[len];    A[len] = tmp;    len--;    i = 0;    while (1) {         /* Heapify */      l = LEFT(i);      r = RIGHT(i);      if (l < len && A[l] > A[largest]) {        largest = l;      }      if (r < len && A[r] > A[largest]) {        largest = r;      }      if (largest != i) {        tmp = A[i];        A[i] = A[largest];        A[largest] = tmp;        i = largest;      } else {        break;      }    }  }}void display(int *A, int len){  int i;  for (i = 0; i < len; i++) {    printf("%d ", A[i]);  }  printf("\n");}int main(){  int A[] = {10, 32, 43, 31, 2, 45, 12, 9, 71, 41, 10, -19, 32, 4, 8, 6};  int len = sizeof(A) / sizeof(A[0]);  display(A, len);  heap_sort(A, len);  display(A, len);  return 0;}

堆排序实现(非递归通用版)

为了满足通用性,本文同样实现了类似于库函数qsort排序算法的通用版。

#include <stdio.h>#define LEFT(i)            (((i) << 1) + 1)#define RIGHT(i)           (((i) << 1) + 2)#define PARENT(i)          (((i) - 1) >> 1)#define SWAP(a, b, size)                      \  do {                                        \  size_t __size = (size);                     \  unsigned char *__a = (a), *__b = (b);       \  do {                                        \    unsigned char __tmp = *__a;               \    *__a++ = *__b;                            \    *__b++ = __tmp;                           \  } while (--__size > 0);                     \  } while(0)void display(int *A, int len){  int i;  for (i = 0; i < len; i++) {    printf("%d ", A[i]);  }  printf("\n");}/* @brief The hsort() function sorts an array with nmemb *        elements of size size. * @param base [in] The start of the array. * @param nmemb [in] The number of elements in array. * @param size [in] The size of the element. * @param compare [in] The comparison function. */void hsort(void *base, size_t nmemb, size_t size,           int (*compare)(const void *, const void *)){  int l, r, i, largest;  i = PARENT(nmemb - 1);  /* Get the last non-leaf node */  /* First build heap */  while (i >= 0) {    l = LEFT(i);    r = RIGHT(i);    largest = i;    if (l < nmemb && compare(base + l * size, base + largest * size) > 0) {      largest = l;    }    if (r < nmemb && compare(base + r * size, base + largest * size) > 0) {      largest = r;    }    if (largest == i) {      i--;    } else {      SWAP(base + i * size, base + largest * size, size);      i = largest;    }  }  while (--nmemb > 0) {    SWAP(base, base + nmemb * size, size);  /* Sort: get the max element */    i = 0;              /* Heapify */    while (1) {      l = LEFT(i);      r = RIGHT(i);      largest = i;      if (l < nmemb && compare(base + l * size, base + largest * size) > 0) {        largest = l;      }      if (r < nmemb && compare(base + r * size, base + largest * size) > 0) {        largest = r;      }      if (largest == i) {        break;      }      SWAP(base + i * size, base + largest * size, size);      i = largest;    }  }}int compare(const void *a, const void *b){  return *(int *)a - *(int *)b;}int main(){  int A[] = {10, 32, 43, 31, 2, 45, 12, 9, 71, 41, 10, -19, 32, 4, 8, 6};  int len = sizeof(A) / sizeof(A[0]);  display(A, len);  hsort(A, len, sizeof(int), compare);  display(A, len);  return 0;}
0 0
原创粉丝点击