排序算法C++实现—八大排序算法

前言

把排序算法忘光了,回顾《数据结构》严蔚敏版,并看了网上的几篇文章后,随再做一次总结。本文不会具体介绍每一个算法,我觉得要具体看,可以看《数据结构》这本书,写得很好,不懂的再百度补充知识,主要是每一种方式的实现展示出来。

在这里插入图片描述
他们的性能比较:
在这里插入图片描述

排序算法C++实现

1.插入排序

1.1.直接插入排序
/*
* 直接插入排序
* int a[]为需要排序的数组
* start为起始位置,要求start>=1,因为a[0]要作为“哨兵”使用
* end为结束位置
*/
void InsertSort(int a[], int start, int end)
{
  int i, j;
  for(i = start + 1; i <= end; i++) {
    if(a[i] < a[i-1]) {
      a[0] = a[i];
      a[i] = a[i-1];
      for(j = i - 2; a[0] < a[j]; --j) {
        a[j+1] = a[j];
      }
      a[j+1] = a[0];
    }
  }
}
1.2.希尔排序
/*
* 希尔排序
* int a[]为需要排序的数组
* start为起始位置,要求start>=1,因为a[0]是暂存单元,不是哨兵
* end为结束位置
*/
void ShellInsert(int a[], int start, int end, int dk)
{
  int i, j;
  for(i = dk + 1; i <= end; ++i) {
    if(a[i] < a[i-dk]) {
      a[0] = a[i];
      for(j = i - dk; j > 0 && a[0] < a[j]; j-=dk) {
        a[j+dk] = a[j];
      }
      a[j+dk] = a[0];
    }
  }
}
void ShellSort(int a[], int start, int end)
{
  int dt[3] = {5, 3, 1}, t = 3;
  for(int k = 0; k < t; ++k) {
    ShellInsert(a, start, end, k);
  }
}

2.交换排序

2.1.冒泡排序
/*
* 冒泡排序
* int a[]为需要排序的数组
* start为起始位置,要求start>=1
* end为结束位置
*/
void BubbleSort(int a[], int start, int end)
{
  int m = end - 1;
  bool flag = true;
  for (int i = start; i <= end - 1 && flag; ++i) {
    flag = false;
    for(int j = 1; j <= end - i; ++j) {
      if(a[j] > a[j+1]) {
        flag = true;
        int t = a[j]; a[j] = a[j+1]; a[j+1] = t;
      }
    }
  }
}
2.2.快速排序
/*
* 快速排序
* int a[]为需要排序的数组
* start为起始位置,要求start>=1,因为a[0]是暂存单元,不是哨兵
* end为结束位置
*/
int Partition(int a[], int low, int high)
{
  int pivotkey = a[low];
  while (low < high) {
    while (low < high && a[high] >= pivotkey) --high;
    a[low] = a[high];
    while (low<high && a[low] <= pivotkey) ++low;
    a[high] = a[low];
  }
  a[low] = pivotkey;
  return low;
}
void QSort(int a[], int low, int high)
{
  if(low < high) {
    int pivotloc = Partition(a, low, high);
    QSort(a, low, pivotloc - 1);
    QSort(a, pivotloc + 1, high);
  }
}

3.选择排序

3.1.简单选择排序
/*
* 简单选择排序排序
* int a[]为需要排序的数组
* start为起始位置,要求start>=1
* end为结束位置
*/
void SelectSort(int a[], int start, int end)
{
  for (int i = start; i <= end; i++) {
    int k = i;
    for (int j = i + 1; j <= end; j++) {
      if (a[k] > a[j]) {  k = j;  }
    }
    if (k!=i) {
      int t = a[i]; a[i] = a[k]; a[k] = t;
    } 
  }
}
3.1.堆排序

/*

  • 堆排序
  • int a[]为需要排序的数组
  • start为起始位置,要求start>=1
  • end为结束位置
  • 最坏O(nlog2n),而快排最坏O(n^2),当记录较多时较为高效
    */
void BuildMaxHeap(int heap[], int len) {
    for (int i = len/2-1; i >= 0; i--) {
        if ((2*i+1) < len && heap[i] < heap[2*i+1]) {
            // 根结点大于左子树
            int temp = heap[i];
            heap[i] = heap[2*i+1];
            heap[2*i+1] = temp;
            if (2*(2*i+1)+1 < len && heap[2*i+1] < heap[2*(2*i+1)+1]
                || 2*(2*i+1)+2 < len && heap[2*i+1] < heap[2*(2*i+1)+2]) {
                //检查交换后的左子树是否满足大顶堆性质,如不满足,则重新调整子树结构
                BuildMaxHeap(heap, len);
            }
        }
        if ((2*i+2) < len && heap[i] < heap[2*i+2]) {
            int temp = heap[i];
            heap[i] = heap[2*i+2];
            heap[2*i+2] = temp;
            if (2*(2*i+2)+1 < len && heap[2*i+2] < heap[2*(2*i+2)+1]
                    || 2*(2*i+2)+2 < len && heap[2*i+1] < heap[2*(2*i+2)+2]) {
                BuildMaxHeap(heap, len);
            }
        }
    }
}
void HeapSort(int a[], int len) {
   for (int i = len; i > 0; i--) {
        BuildMaxHeap(a, i);
        //交换根结点和数组末尾元素的值
        int temp = a[0];
        a[0] = a[i-1];
        a[i-1] = temp;
    }
}

4.归并排序

/*
* 归并排序
* int array[]为需要排序的数组
* low为起始位置,要求start>=1
* high为结束位置
* cnt为求逆序对数目,是归并排序的拓展
*/
// 合并数组,排好序,然后在拷贝到原来的数组array
int cnt = 0;
void Merge(int array[], int low,int mid, int high, int temp[]) {
    int i = low;
    int j = mid + 1;
    int k = 0;
    while (i <= mid && j <= high ) {
        if (array[i] <= array[j]) temp[k++] = array[i++];
        else {
          temp[k++] = array[j++];
          cnt += mid - i + 1;//求逆序对数目
        }
    }
    while (i <= mid) temp[k++] = array[i++];
    while (j <= high) temp[k++] = array[j++];
    for (int p = 0; p < k; p++) array[low + p] = temp[p];
}
// 归并排序,将数组前半部分后半部分分成最小单元,然后在合并
void MSort(int array[], int low,  int high, int temp[]) {
    if (low == high) temp[low] = array[low];
    else {
        int mid = (low + high) / 2;
        MSort(array, low, mid, temp);
        MSort(array, mid + 1, high, temp);
        Merge(array, low, mid, high, temp);
    }
}
// 在这里创建临时数组,节省内存开销,因为以后的temp都是在递归里使用的。
void MergeSort(int array[], int low, int high) {
    int *temp = new int[high+1];
    MSort(array, low, high, temp);
}

5.基数排序

参考

《数据结构》严蔚敏版
轻松学习排序算法
面试准备之六大排序算法篇
数据结构常见的八大排序算法(详细整理)
八大排序算法总结与java实现

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值