一、概念
1.数据表
(1)顺序表
//DataList.h
#pragma once
#include<cstdio>
const int maxSize = 20;
typedef int DataType;
typedef struct {
DataType data[maxSize];
int n;
}DataList;
void Swap(DataList& L, int a, int b) {
DataType tmp = L.data[a];
L.data[a] = L.data[b];
L.data[b] = tmp;
}
void createList(DataList& L, DataType A[], int n) {
for (int i = 0; i < n; i++) L.data[i] = A[i];
L.n = n;
}
void printDataList(DataList& L) {
for (int i = 0; i < L.n; i++) {
printf("%d ", L.data[i]);
}
printf("\n");
}
(2)静态链表
//StaticLinkList.h
#pragma once
#include<climits>
#include<cstdio>
using namespace std;
#define maxSize 100
#define maxValue INT_MAX
typedef int DataType;
typedef struct {
DataType key;
int link;
}SLNode;
typedef struct {
SLNode elem[maxSize];
int n;
}StaticLinkList;
void createSList(StaticLinkList& SL, DataType A[], int n) {
for (int i = 0; i < n; i++) {
SL.elem[i + 1].key = A[i];
SL.elem[i + 1].link = i + 2;
}
SL.elem[0].key = maxValue;
SL.elem[0].link = 1;
SL.elem[n].link = 0;
SL.n = n;
}
void printSList(StaticLinkList& SL) {
for (int i = SL.elem[0].link; i != 0; i = SL.elem[i].link) {
printf("%d ", SL.elem[i].key);
}
printf("\n");
}
二、插入排序
1.顺序表插入排序
#include "DataList.h"
void InsertSort(DataList& L) {
DataType tmp;
int i, j;
for (i = 1; i < L.n; i++) {
if (L.data[i] < L.data[i - 1]) {
tmp = L.data[i];
for (j = i - 1; j >= 0 && tmp < L.data[j]; j--) {
L.data[j + 1] = L.data[j];
}
L.data[j + 1] = tmp;
}
}
}
2.静态链表插入排序
#include "StaticLinkList.h"
void SLinkInsertSort(StaticLinkList& L) {
int i, p, pre;
L.elem[0].key = maxValue;
for (i = 2; i <= L.n; i++) {
p = L.elem[0].link;
pre = 0;
while (L.elem[p].key <= L.elem[i].key) {
pre = p;
p = L.elem[i].link;
}
L.elem[pre].link = i;
L.elem[i].link = p;
}
}
3.折半插入排序
void BinaryInsertSort(DataList& L) {
DataType tmp;
for (int i = 1; i < L.n; i++) {
tmp = L.data[i];
int low = 0, high = i - 1;
while (low < high) {
int mid = (low + high) / 2;
if (tmp < L.data[mid]) high = mid;
else low = mid;
}
for (int j = i; j > low; j--) {
L.data[j] = L.data[j - 1];
}
L.data[low] = tmp;
}
}
4.希尔排序
void insertSort_gap(DataList& L, int start, int gap) {
DataType temp;
int i, j;
for (i = start + gap; i < L.n; i += gap) {
if (L.data[i - gap] > L.data[i]) {
temp = L.data[i]; j = i;
}
do {
L.data[j] = L.data[j - gap];
j -= gap;
} while (j - gap > 0 && L.data[j - gap] > temp);
L.data[j] = temp;
}
}
void ShellSort(DataList& L, int delta[], int m) {
int start, gap;
for (int i = m - 1; i >= 0; i--) {
gap = delta[i];
for (start = 0; start < gap; start++) insertSort_gap(L, start, gap);
}
}
三、交换排序
1.冒泡排序
void BubbleSort(DataList& L) {
DataType tmp;
for (int i = 0; i < L.n - 1; i++) {
int exchange = 0;
for (int j = L.n - 1; j > i; j--) {
if (L.data[j - 1] > L.data[j]) {
Swap(L, j - 1, j);
exchange = 1;
}
}
if (!exchange) return;
}
}
2.快速排序
(1)递归算法
int Partition(DataList& L, int low, int high) {
int i = low, j = high;
DataType pivot = L.data[low];
while (i < j) {
while (i < j && L.data[j] >= pivot) j--;
if (i < j) {
L.data[i] = L.data[j];
i++;
while (i < j && L.data[i] <= pivot) i++;
if (i < j) {
L.data[j] = L.data[i];
j--;
}
}
}
L.data[i] = pivot;
return i;
}
void QuickSort(DataList& L, int left, int right) {
if (left < right) {
int pivotpos = Partition(L, left, right);
QuickSort(L, left, pivotpos - 1);
QuickSort(L, pivotpos + 1, right);
}
}
(2)快速-直接插入混合法
void InsertSort(DataList& L, int left, int right) {
DataType temp;
int i, j;
for (i = left + 1; i <= right; i + ) {
if (L.data[i] < L.data[i - 1]) {
temp = L.data[i];
for (j = i - 1; j >= left && temp < L.data[j]; j--) {
L.data[j + 1] = L.data[j];
}
L.data[j + 1] = temp;
}
}
}
void QuickSort_insert(DataList& L, int left, int right, int M) {
if (right - left <= 0) return;
if (right - left + 1 < M) InsertSort(L, left, right);
else {
int pivotpos = Partition(L, left, right);
QuickSort_insert(L, left, pivotpos - 1, M);
QuickSort_insert(L, pivotpos + 1, right, M);
}
}
(3)在序列中三者取中并交换到左端的算法
void median3(DataList& L, int left, int right) {
int mid = (left + right) / 2;
int k1, k2;
if (L.data[left] <= L.data[mid]) {
k1 = left; k2 = mid;
}
else {
k1 = mid;
k2 = left;
}
if (L.data[right] < L.data[k1]) {
k2 = k1; k1 = right;
}
else if(L.data[right] < L.data[k2]) {
k2 = right;
}
if (k2 != left) Swap(L, k2, left);
}
(4)采用三者取中选择基准记录的快速排序算法
void QuickSort_mediancy(DataList& L, int left, int right) {
if (left < right) {
median3(L, left, right);
int pivotpos = Partition(L, left, right);
QuickSort_mediancy(L, left, pivotpos - 1);
QuickSort_mediancy(L, pivotpos + 1, right);
}
}
四、选择排序
1.简单选择排序
void SelectSort(DataList& L) {
int i, j, k;
for (i = 0; i < L.n - 1; i++) {
k = i;
for (j = i + 1; j <= L.n - 1; j++) {
if (L.data[j] < L.data[k]) k = j;
}
if (k != i) Swap(L, k, i);
}
}
2.堆排序
//maxHeap.h
#pragma once
#include<cstdio>
#define heapSize 128
typedef int DataType;
typedef struct {
DataType data[heapSize];
int n;
}maxHeap;
void siftDown(maxHeap& H, int start, int m) {
if (start == m) return;
int i = start; int j = 2 * i + 1;
DataType temp = H.data[i];
while (j <= m) {
if (j < m && H.data[j] < H.data[j + 1]) j++;
if (temp >= H.data[j]) break;
else { H.data[i] = H.data[j]; i = j; j = 2 * j + 1; }
}
H.data[i] = temp;
}
#include "maxHeap.h"
void createMaxHeap(maxHeap& H, DataType arr[], int n) {
for (int i = 0; i < n; i++) H.data[i] = arr[i];
H.n = n;
for (int i = (H.n - 2) / 2; i >= 0; i--) siftDown(H, i, H.n - 1);
}
void HeapSort(maxHeap& H) {
for (int i = H.n - 1; i > 0; i--) {
DataType temp = H.data[0];
H.data[0] = H.data[i];
H.data[i] = temp;
siftDown(H, 0, i - 1);
}
}
五、归并排序
1.二路归并
(1)二路归并的递归算法
void Merge(DataList& L, int left, int mid, int right) {
int i = left, j = mid + 1, k = 0, s = right - left + 1;
DataType* L2 = (DataType*)malloc(s * sizeof(DataType));
while (i <= mid && j <= right) {
if (L.data[i] <= L.data[j]) L2[k++] = L.data[i++];
else L2[k++] = L.data[j++];
}
while (i <= mid) L2[k++] = L.data[i++];
while (j <= right) L2[k++] = L.data[j++];
for (int i = 0; i < s; i++) L.data[left + i] = L2[i];
free(L2);
}
void MergeSort_recur(DataList& L, int left, int right) {
if (left < right) {
int mid = (left + right) / 2;
MergeSort_recur(L, left, mid);
MergeSort_recur(L, mid + 1, right);
Merge(L, left, mid, right);
}
}
(2)二路归并的迭代算法
void Merge_2(DataList& L, DataList& L2, int left, int mid, int right) {
int i = left, j = mid + 1, k = left;
while (i <= mid && j <= right) {
if (L.data[i] <= L.data[j]) L2.data[k++] = L.data[i++];
else L2.data[k++] = L.data[j++];
}
while (i <= mid) L2.data[k++] = L.data[i++];
while (j <= right) L2.data[k++] = L.data[j++];
}
void MergePass(DataList& L, DataList& L2, int len) {
int i = 0;
while (i + 2 * len < L.n) {
Merge_2(L, L2, i, i + len - 1, i + 2 * len - 1);
i += 2 * len;
}
if (i + len < L.n) Merge_2(L, L2, i, i + len - 1, L.n - 1);
else for (int j = i; j < L.n; j++) L2.data[j] = L.data[j];
}
void MergeSort_iter(DataList& L) {
DataList L2;
int i, len = 1;
while (len < L.n) {
MergePass(L, L2, len); len *= 2;
MergePass(L2, L, len); len *= 2;
}
}
六、基数排序
1.MSD基数排序算法
#include<cstdlib>
#include<cstdio>
using namespace std;
const int rd = 10, d = 3, maxSize = 20;
int getDigit(int x, int k) {
if (k < 1 || k > d) return -1;
for (int i = 1; i <= d - k; i++) x /= 10;
return x % 10;
}
void RadixSort(int A[], int left, int right, int k) {
if (left >= right || k > d) return;
int i, j, v, p1, p2, count[rd], posit[rd];
int* auxArray = (int*)malloc((right - left + 1) * sizeof(int));
for (j = 0; j < rd; j++) count[j] = 0;
for (i = left; i <= right; i++) {
v = getDigit(A[i], k);
count[v]++;
}
posit[0] = 0;
for (j = 1; j < rd; j++) posit[j] = count[j - 1] + posit[j - 1];
for (i = left; i <= right; i++) {
v = getDigit(A[i], k);
auxArray[posit[v]++] = A[i];
}
for (i = left, j = 0; i <= right; i++, j++) A[i] = auxArray[j];
free(auxArray);
p1 = left;
for (j = 0; j < rd; j++) {
p2 = p1 + count[j] - 1;
RadixSort(A, p1, p2, k + 1);
p1 = p2 + 1;
}
}
2.LSD链式基数排序的算法
#include "StaticLinkList.h"
const int rd = 10;
const int d = 3;
int getDigit(int x, int k) {
if (k < 1 || k > d) return -1;
for (int i = 1; i <= d - k; i++) x /= 10;
return x % 10;
}
void SLinkRadixSort(StaticLinkList& SL) {
int rear[rd], front[rd];
int i, j, k, last, s, t;
for (i = d; i >= 1; i--) {
for (j = 0; j < rd; j++) front[j] = 0;
for (s = SL.elem[0].link; s != 0; s = SL.elem[s].link) {
k = getDigit(SL.elem[s].key, i);
if (front[k] == 0) front[k] = s;
else SL.elem[rear[k]].link = s;
rear[k] = s;
}
for (j = 0; front[j] == 0; j++);
SL.elem[0].link = front[j];
last = rear[j];
for (t = j + 1; t < rd; t++) {
if (front[t] != 0) {
SL.elem[last].link = front[t];
last = rear[t];
}
}
SL.elem[last].link = 0;
for (t = SL.elem[0].link; t != 0; t = SL.elem[t].link) {
printf("%d ", SL.elem[t].key);
}
printf("\n");
}
}