首先是算法实现文件Sort.h。代码例如以下:

<pre name="code" class="java">/*
* 实现了八个经常使用的排序算法:插入排序、冒泡排序、选择排序、希尔排序
* 以及高速排序、归并排序、堆排序和LST基数排序
* @author gkh178
*/
#include <iostream> template<class T>
void swap_value(T &a, T &b)
{
T temp = a;
a = b;
b = temp;
} //插入排序:时间复杂度o(n^2)
template<class T>
void insert_sort(T a[], int n)
{
for (int i = 1; i < n; ++i)
{
T temp = a[i];
int j = i - 1;
while (j >= 0 && a[j] > temp)
{
a[j + 1] = a[j];
--j;
}
a[j + 1] = temp;
}
} //冒泡排序:时间复杂度o(n^2)
template<class T>
void bubble_sort(T a[], int n)
{
for (int i = n - 1; i > 0; --i)
{
for (int j = 0; j < i; ++j)
{
if (a[j] > a[j + 1])
{
swap_value(a[j], a[j + 1]);
}
}
}
} //选择排序:时间复杂度o(n^2)
template<class T>
void select_sort(T a[], int n)
{
for (int i = 0; i < n - 1; ++i)
{
T min = a[i];
int index = i;
for (int j = i + 1; j < n; ++j)
{
if (a[j] < min)
{
min = a[j];
index = j;
}
}
a[index] = a[i];
a[i] = min;
}
} //希尔排序:时间复杂度介于o(n^2)和o(nlgn)之间
template<class T>
void shell_sort(T a[], int n)
{
for (int gap = n / 2; gap >= 1; gap /= 2)
{
for (int i = gap; i < n; ++i)
{
T temp = a[i];
int j = i - gap;
while (j >= 0 && a[j] > temp)
{
a[j + gap] = a[j];
j -= gap;
}
a[j + gap] = temp;
}
}
} //高速排序:时间复杂度o(nlgn)
template<class T>
void quick_sort(T a[], int n)
{
_quick_sort(a, 0, n - 1);
}
template<class T>
void _quick_sort(T a[], int left, int right)
{
if (left < right)
{
int q = _partition(a, left, right);//一次划分得到的中位数的位置
_quick_sort(a, left, q - 1);//对左边进行递归快排
_quick_sort(a, q + 1, right);//对右边进行递归快排
}
}
template<class T>
int _partition(T a[], int left, int right)
{
T pivot = a[left];//设置第一个数为中位数
while (left < right)
{
while (left < right && a[right] >= pivot)
{
--right;
}
a[left] = a[right];//从右到左寻找一个比中位数小的数。将其填入中位数的所在位置
while (left < right && a[left] <= pivot)
{
++left;
}
a[right] = a[left];//从左到右寻找一个比中位数大的数,将其填入刚才空缺的位置
}
a[left] = pivot;//将中位数填入空缺位置
return left;
} //归并排序:时间复杂度o(nlgn)
template<class T>
void merge_sort(T a[], int n)
{
_merge_sort(a, 0, n - 1);
}
template<class T>
void _merge_sort(T a[], int left, int right)
{
if (left < right)
{
int mid = left + (right - left) / 2;
_merge_sort(a, left, mid);//对左边递归归并排序
_merge_sort(a, mid + 1, right);//对右边递归归并排序
_merge(a, left, mid, right);//将左右归并起来
}
}
template<class T>
void _merge(T a[], int left, int mid, int right)
{
int length = right - left + 1;
T *newA = new T[length];//用来暂存原始数组
for (int i = 0, j = left; i <= length - 1; ++i, ++j)
{
*(newA + i) = a[j];
}
int i = 0;
int j = mid - left + 1;
int k = left;
for (; i <= mid - left && j <= length - 1; ++k)
{
if (*(newA + i) < *(newA + j))
{
a[k] = *(newA + i);
++i;
}
else
{
a[k] = *(newA + j);
++j;
}
}
//将左边或者右边多余的数填入数组
while (i <= mid - left)
{
a[k++] = *(newA + i);
++i;
}
while (j <= right - left)
{
a[k++] = *(newA + j);
++j;
}
delete[] newA;
} //堆排序:时间复杂度o(nlgn)
template<class T>
void heap_sort(T a[], int n)
{
built_max_heap(a, n);//建立初始大根堆
//交换首尾元素。并对交换后排除尾元素的数组进行一次上调整
for (int i = n - 1; i >= 1; --i)
{
swap_value(a[0], a[i]);
up_adjust(a, i);
}
}
//建立一个长度为n的大根堆
template<class T>
void built_max_heap(T a[], int n)
{
up_adjust(a, n);
}
//对长度为n的数组进行一次上调整
template<class T>
void up_adjust(T a[], int n)
{
//对每一个带有子女节点的元素遍历处理,从后到根节点位置
for (int i = n / 2; i >= 1; --i)
{
adjust_node(a, n, i);
}
}
//调整序号为i的节点的值
template<class T>
void adjust_node(T a[], int n, int i)
{
//节点有左右孩子
if (2 * i + 1 <= n)
{
//右孩子的值大于节点的值,交换它们
if (a[2 * i] > a[i - 1])
{
swap_value(a[2 * i], a[i - 1]);
}
//左孩子的值大于节点的值。交换它们
if (a[2 * i - 1] > a[i - 1])
{
swap_value(a[2 * i - 1], a[i - 1]);
}
//对节点的左右孩子的根节点进行调整
adjust_node(a, n, 2 * i);
adjust_node(a, n, 2 * i + 1);
}
//节点仅仅有左孩子,为最后一个有左右孩子的节点
else if (2 * i == n)
{
//左孩子的值大于节点的值,交换它们
if (a[2 * i - 1] > a[i - 1])
{
swap_value(a[2 * i - 1], a[i - 1]);
}
}
} //基数排序的时间复杂度为o(distance(n+radix)),distance为位数。n为数组个数,radix为基数
//本方法是用LST方法进行基数排序。MST方法不包括在内
//当中參数radix为基数,一般为10。distance表示待排序的数组的数字最长的位数。n为数组的长度
template<class T>
void lst_radix_sort(T a[], int n, int radix, int distance)
{
T* newA = new T[n];//用于暂存数组
int* count = new int[radix];//用于计数排序。保存的是当前位的值为0 到 radix-1的元素出现的的个数
int divide = 1;
//从倒数第一位处理到第一位
for (int i = 0; i < distance; ++i)
{
//待排数组复制到newA数组中
for (int j = 0; j < n; ++j)
{
*(newA + j) = a[j];
}
//将计数数组置0
for (int j = 0; j < radix; ++j)
{
*(count + j) = 0;
}
for (int j = 0; j < n; ++j)
{
int radixKey = (*(newA + j) / divide) % radix; //得到数组元素的当前处理位的值
(*(count + radixKey))++;
}
//此时count[]中每一个元素保存的是radixKey位出现的次数
//计算每一个radixKey在数组中的结束位置。位置序号范围为1-n
for (int j = 1; j < radix; ++j)
{
*(count + j) = *(count + j) + *(count + j - 1);
}
//运用计数排序的原理实现一次排序,排序后的数组输出到a[]
for (int j = n - 1; j >= 0; --j)
{
int radixKey = (*(newA + j) / divide) % radix;
a[*(count + radixKey) - 1] = newA[j];
--(*(count + radixKey));
}
divide = divide * radix;
}
delete[] newA;
delete[] count;
}

然后是測试文件main.cpp。代码例如以下:

#include "Sort.h"
using namespace std; template<class T>
void printArray(T a[], int n)
{
for (int i = 0; i < n; ++i)
{
cout << a[i] << " ";
}
cout << endl;
} int main()
{
for (int i = 1; i <= 8; ++i)
{
int arr[] = { 45, 38, 26, 77, 128, 38, 25, 444, 61, 153, 9999, 1012, 43, 128 };
switch (i)
{
case 1:
insert_sort(arr, sizeof(arr) / sizeof(arr[0]));
break;
case 2:
bubble_sort(arr, sizeof(arr) / sizeof(arr[0]));
break;
case 3:
select_sort(arr, sizeof(arr) / sizeof(arr[0]));
break;
case 4:
shell_sort(arr, sizeof(arr) / sizeof(arr[0]));
break;
case 5:
quick_sort(arr, sizeof(arr) / sizeof(arr[0]));
break;
case 6:
merge_sort(arr, sizeof(arr) / sizeof(arr[0]));
break;
case 7:
heap_sort(arr, sizeof(arr) / sizeof(arr[0]));
break;
case 8:
lst_radix_sort(arr, sizeof(arr) / sizeof(arr[0]), 10, 4);
break;
default:
break;
}
printArray(arr, sizeof(arr) / sizeof(arr[0]));
}
return 0;
}

最后是执行结果图,例如以下:

watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast" alt="">

插入排序、冒泡排序、选择排序、希尔排序、高速排序、归并排序、堆排序和LST基数排序——C++实现的更多相关文章

  1. C# 插入排序 冒泡排序 选择排序 高速排序 堆排序 归并排序 基数排序 希尔排序

    C# 插入排序 冒泡排序 选择排序 高速排序 堆排序 归并排序 基数排序 希尔排序 以下列出了数据结构与算法的八种基本排序:插入排序 冒泡排序 选择排序 高速排序 堆排序 归并排序 基数排序 希尔排序 ...

  2. 排序算法之高速排序(Java)

    //高速排序 public class Quick_Sort { // 排序的主要算法 private int Partition(int[] data, int start, int end) { ...

  3. 七内部排序算法汇总(插入排序、Shell排序、冒泡排序、请选择类别、、高速分拣合并排序、堆排序)

    写在前面: 排序是计算机程序设计中的一种重要操作,它的功能是将一个数据元素的随意序列,又一次排列成一个按keyword有序的序列.因此排序掌握各种排序算法很重要. 对以下介绍的各个排序,我们假定全部排 ...

  4. 《算法导论》 — Chapter 7 高速排序

    序 高速排序(QuickSort)也是一种排序算法,对包括n个数组的输入数组.最坏情况执行时间为O(n^2). 尽管这个最坏情况执行时间比較差.可是高速排序一般是用于排序的最佳有用选择.这是由于其平均 ...

  5. 冒泡排序 & 选择排序 & 插入排序 & 希尔排序 JavaScript 实现

    之前用 JavaScript 写过 快速排序 和 归并排序,本文聊聊四个基础排序算法.(本文默认排序结果都是从小到大) 冒泡排序 冒泡排序每次循环结束会将最大的元素 "冒泡" 到最 ...

  6. 数组排序-冒泡排序-选择排序-插入排序-希尔排序-快速排序-Java实现

    这五种排序算法难度依次增加. 冒泡排序: 第一次将数组相邻两个元素依次比较,然后将大的元素往后移,像冒泡一样,最终最大的元素被移到数组的最末尾. 第二次将数组的前n-1个元素取出,然后相邻两个元素依次 ...

  7. 学习C#之旅 冒泡排序,选择排序,插入排序,希尔排序[资料收集]

    关于冒泡排序,选择排序,插入排序,希尔排序[资料收集]  以下资料来源与网络 冒泡排序:从后到前(或者从前到后)相邻的两个两两进行比较,不满足要求就位置进行交换,一轮下来选择出一个最小(或最大)的放到 ...

  8. 算法 排序lowB三人组 冒泡排序 选择排序 插入排序

    参考博客:基于python的七种经典排序算法   [经典排序算法][集锦]     经典排序算法及python实现 首先明确,算法的实质 是 列表排序.具体就是操作的列表,将无序列表变成有序列表! 一 ...

  9. JavaScript 数据结构与算法之美 - 冒泡排序、插入排序、选择排序

    1. 前言 算法为王. 想学好前端,先练好内功,只有内功深厚者,前端之路才会走得更远. 笔者写的 JavaScript 数据结构与算法之美 系列用的语言是 JavaScript ,旨在入门数据结构与算 ...

随机推荐

  1. MySQL创建表时加入的约束以及外键约束的的意义

    1,创建表时加入的约束 a) 非空约束,not null b) 唯一约束,unique c) 主键约束,primary key d) 外键约束,foreign key 1,非空约束,针对某个字段设置其 ...

  2. UVA 436 - Arbitrage (II)(floyd)

    UVA 436 - Arbitrage (II) 题目链接 题意:给定一些国家货币的汇率.问是否能通过不断换货币使钱得到增长 思路:floyd,完事后推断一下有没有连到自己能大于1的情况 代码: #i ...

  3. cocos2dx-3.0创建Android项目时遇到的错误。

    cocos run -p android出现 文件名称.文件夹名或卷标语法不对 Updated project.properties Updated local.properties Updated ...

  4. pat(A) 1066. Root of AVL Tree

    代码: #include<iostream> #include<cstdio> #include<cmath> #include<stdlib.h> # ...

  5. activity生命周期的onPause和onStop

    搞了这么长时间的android开发,却对一些基础的东西一直模棱两可...就比方这个onPause和onStop. 假设从一个界面,跳到还有一个界面,那么是调用哪个呢? 经过我的实验.搞清楚了.onPa ...

  6. Android开发之AudioManager(音频管理器)具体解释

    AudioManager简单介绍: AudioManager类提供了訪问音量和振铃器mode控制. 使用Context.getSystemService(Context.AUDIO_SERVICE)来 ...

  7. android 退出系统

    /** * */ package com.szkingdom.android.phone.utils; import java.io.BufferedReader; import java.io.IO ...

  8. JS数组去重 包含去除多个 NaN

    Array.prototype.uniq = function () { var arr = []; var flag = true; this.forEach(function(item) {   ...

  9. HttpWebRequest 表单提交

    /// <summary> /// http请求 /// </summary> public static class ZkWebRequestHelp { /// <s ...

  10. HDU 1950 Bridging signals【最长上升序列】

    解题思路:题目给出的描述就是一种求最长上升子序列的方法 将该列数an与其按升序排好序后的an'求出最长公共子序列就是最长上升子序列 但是这道题用这种方法是会超时的,用滚动数组优化也超时, 下面是网上找 ...