本文包含:
1.冒泡排序
2.及时终止的冒泡排序
3.计数排序
4.插入排序
5.选择排序
6.及时终止的选择排序
7.归并排序
8.快速排序
9.基数排序
1.冒泡排序
两重循环,遇到一个数比它后一个数大时就交换位置。
//冒泡排序
template<class T>
void bubbleSort(T a[], int n) {
for (int i = 0; i < n; ++i) {
for (int j = 0; j < n; ++j) {
if (a[j] > a[j + 1]) {
swap(a,j,j+1);
}
}
}
}
2.及时终止的冒泡排序
添加判断代码,避免做无用功
两重循环,遇到一个数比它后一个数大时就交换位置,直到每一个数的后一个数都比它本身大。
//及时终止的冒泡排序
template<class T>
void bubbleSort2(T a[], int n) {
bool swapped = true;//用于判断数组是否已经有序了
for (int i = n; i > 1 && swapped; --i) {
swapped = false;
for (int j = 0; j < i - 1; ++j) {
if (a[j] > a[j + 1]) {
swap(a,j,j+1);
swapped = true;
}
}
}
}
3.计数排序
先计算每个数应该排在第几名,再通过数字的名次把它交换到它应处的位置。
//计数排序
template<class T>
void countSort(T a[], int n) {
T *b = new T[n];
//先初始化数组b
for (int i = 0; i < n; ++i) {
b[i] = 0;
}
//计算名次
for (int j = 1; j < n; ++j) {
for (int i = 0; i < j; ++i) {
if (a[i] <= a[j]) {
b[j]++;
} else {
b[i]++;
}
}
}
//根据名次排序
for (int k = 0; k < n; ++k) {
while (b[k] != k) {
swap(a,k,b[k]);
swap(b,k,b[k]);
}
}
}
4.插入排序
将每个数都插入到当前顺序中它应在的位置,当完成所有数的插入后,便成了有序数组。
//插入排序
template<class T>
void insertSort(T a[], int n) {
for (int i = 0; i < n; ++i) {
T temp = a[i];
int j;
for (j = i - 1; j >= 0 && a[j] > temp; --j) {
a[j + 1] = a[j];
}
a[j + 1] = temp;
}
}
5.选择排序
选择最大的数放到最后面,再选择除了已选出来的数中最大的,放到这些数都后面。
//选择排序
template<class T>
void selectionSort(T a[], int n) {
for (int i = n; i > 1; --i) {
int indexOfMax = 0;
for (int j = 0; j < i; ++j) {
if (a[indexOfMax] <= a[j]) {
indexOfMax = j;
}
}
swap(a,indexOfMax,n-1);
}
}
6.及时终止的选择排序
添加判断代码,避免做无用功
后面的数都>前面的数了则停止。
//及时终止的选择排序
template<class T>
void selectionSort2(T a[], int n) {
bool sorted = false;//用于判断数组是否已经有序了
for (int i = n; !sorted && i > 1; --i) {
int indexOfMax = 0;
sorted = true;
for (int j = 0; j < i; ++j) {
if (a[indexOfMax] <= a[j]) {
indexOfMax = j;
} else {
sorted = false;
}
}
swap(a,indexOfMax,n-1);
}
}
7.归并排序
两个两个的排序,当有序后就合并为一个单位元看待,再进行两个两个的排序,直到都合并成一个。
驱动程序
//归并排序
template<class T>
void mergeSort(T a[], int n) {
T *b = new T[n];
int segmentSize = 1;
while (segmentSize < n) {
mergePass(a, b, n, segmentSize);
segmentSize += segmentSize;
mergePass(b, a, n, segmentSize);
segmentSize += segmentSize;
}
delete[] b;
}
确定需要归并的子序列的左右边界
template<class T>
void mergePass(T a[], T b[], int n, int segmentSize) {
int i = 0;
while (i <= n - 2 * segmentSize) {
merge(a, b, i, i + segmentSize - 1, i + 2 * segmentSize - 1);
i = i + 2 * segmentSize;
}
if (i + segmentSize < n) {
merge(a, b, i, i + segmentSize - 1, n - 1);
} else {
for (int j = i; j < n; ++j) {
b[j] = a[j];
}
}
}
实际完成基本的归并操作
template<class T>
void merge(T a[], T b[], int x, int y, int z) {
int first = x, second = y + 1, result = x;
while((first<=y)&&(second<=z)){
if(a[first]<=a[second]){
b[result++]=a[first++];
} else{
b[result++]=a[second++];
}
}
if(first>y){
for (int i = second; i <= z; ++i) {
b[result++]=a[i];
}
} else{
for (int i = first; i <= y; ++i) {
b[result++]=a[i];
}
}
}
8.快速排序
先找一个数(这里找的是第一个),将<它的数放到它左边,将>它的数放到它右边,再将它左边和右边的数分别进行快速排序。
驱动程序
//快速排序
template<class T>
void quickSort(T a[],int n){
if(n<=1)
return;
int indexOfMax = 0;
for (int j = 0; j < n; ++j) {
if (a[indexOfMax] <= a[j]) {
indexOfMax = j;
}
}
swap(a[n-1],a[indexOfMax]);//将最大元素移到最右边
quickSortStep(a,0,n-2);//进入递归程序
}
递归快速排序
template<class T>
void quickSortStep(T a[],int left,int right){
if(left>=right)
return;
int lTemp=left+1,rTemp=right;
T x=a[left];
//将比支点小的元素换到从右侧换到左侧
while (true){
while (a[lTemp]<a[left]){
lTemp++;
}
while (a[rTemp]>a[left]){
rTemp--;
}
if(lTemp>=rTemp)
break;
swap(a,lTemp,rTemp);
}
swap(a[left],a[rTemp]);//将支点换到中间
//在分别将左右侧元素进行快速排序
quickSortStep(a,left,rTemp-1);
quickSortStep(a,rTemp+1,right);
}
9.基数排序
先用最低位排序,再用下一位,一直排到最高位。
//基数排序
template<class T>
void radixSort(T a[], int n) {
//找出所有数中的最大位数
int m = 0;
for (int i = 0; i < n; ++i) {
int k = 1;
T temp = a[i];
while (temp / 10 != 0) {
temp /= 10;
k++;
}
if (k > m) {
m = k;
}
}
//排序
int num = 1;
for (int j = 0; j < m; ++j) {
//最大是几位就循环几次
int x[10][n];//第j位属于0-9的哪一个就存入对应的x[0-9]
int y[10];//存每个x[0-9]中有几个数
for (int j = 0; j < 10; j++) {
y[j] = 0;
}//初始化
int e, temp;
for (int i = 0; i < n; i++) {
temp = a[i] / num;
e = temp % 10;
x[e][y[e]] = a[i];
y[e]++;
}//存入
int f = 0;
for (int k = 0; k < 10; k++) {
if (y[k] > 0)
for (int i = 0; i < y[k]; i++) {
a[f] = x[k][i];
f++;
}
}//取出按顺序放回
num *= 10;//进入高一位排序
}
}
To be continue
接下来会更新分析各排序的程序性能