排序算法——插入排序&希尔排序&堆排

例:给定数组A[] = { 3, 7, 4, 6, 2, 1, 5, 8},对数组进行升序排序

插入排序
思想:
(1)按照给定数组 A 的顺序将数据依次进行插入,每插入一个数据 Ai 时,将该数据 Ai 与 A(i-1) 进行比较;
(2)如果比 A(i-1) 大,则直接放到 A(i-1)后面;
(3)如果比A(i-1)小,则继续和A(i-2)进行比较,直至找到 Ai 应插入的正确位置;
(4)然后将插入位置之后的数据向后挪动,至此一次插入排序完成。

时间复杂度:O(N^2)

每次排序结果:
插入排序
代码:

void insert_sort(int* a, int n)
{
      for (int i = 0; i < n-1; i++)
      {
            int tmp = a[i+1];
            int end = i;
            while (end >= 0)
            {
                  if (tmp < a[end])
                  {
                        a[end + 1] = a[end];
                        --end;
                  }
                  else
                        break;
            }
            a[end+1] = tmp;
      }
}

希尔排序(指定间隔gap为:3)
思想:
与插入排序思想类似,只不过插入排序的间隔gap为1,希尔排序的间隔gap较大,一次排序之后将gap–变小,继续进行。

时间复杂度:O(N) ~ O(N^2)

每次排序结果:
希尔排序
代码:
每次以gap为间隔的组进行插入排序,相当于我们按照数组顺序进行间隔为gap的插入排序,截止条件为gap < 1;
gap = 1时相当于进行的是插入排序。

void shell_sort(int* a, int n)
{
      int gap = n;
      while (gap > 1)
      {
            gap = gap / 3 + 1;
            for (size_t i = 0; i < n-gap; i++)
            {
                  int tmp = a[i + gap];
                  int end = i;
                  while (end >= 0 && tmp < a[end])
                  {
                        a[end + gap] = a[end];
                        end -= gap;
                  }
                  a[end + gap] = tmp;
            }
      }
}

堆排序
思想:
(1)对数组建大堆,使得每一个父亲节点的值都比孩子的大,大堆建好后可以知道:根节点一定是数值最大的;
(2)将跟节点与最后一个结点的值交换,此时最大数一定在最终排序结束的位置上;
(3)忽略已调整好的最后一个数,对堆顶进行向下调整算法,使此时的堆仍为一个大堆;
(4)再次进行上述过程…

时间复杂度:O(N*logN)

对原始数组建大堆过程:
建大堆
每次排序结果:
堆排
代码:

//建大堆,升序
void adjust_down(int* heap, int n,size_t root)
{
      size_t parent = root;
      size_t child = parent * 2 + 1;

      while (child < n)
      {
            if ((child + 1 < n) && (heap[child] < heap[child + 1]))
                  child++;
            if (heap[child] > heap[parent])
            {
                  swap(heap[child], heap[parent]);
                  parent = child;
                  child = parent * 2 + 1;
            }
            else
                  break;
      }
}
void heap_sort(int* a, int n)
{
      //建大堆
      for (int i = (n-2)/2; i >= 0;i--)
      {
            adjust_down(a, n, i);
      }
      int end = n - 1;
      while (end != 0)
      {
            swap(a[end], a[0]);
            adjust_down(a, end, 0);
            end--;
      }
}

猜你喜欢

转载自blog.csdn.net/weixin_39294633/article/details/81674241
今日推荐