一、排序中的思想方法
1.分治
快速排序
归并排序
基数排序
2.变无序为有序,使用某种数据结构对数据进行预处理(即将数据按一定规则组织起来,方便高效地排序)
二叉排序树
堆排序
Trie
3.将几种思想方法进行综合
希尔排序:先处理使其基本有序,在使用插入排序其效率就会提升很多
4.从简单处(初始处,特殊处,易确定处)着手,一步步由简单解构造出全局的复杂的解
选择排序:每次选取最小的
5.抓住数据的根本,利用有限研究无限
基数排序:利用组成数据的十个数据:(0~9),将所有的数据分成十类,数位DP也是利用这一思想
Trie:Trie将所有单词归结为26个单词的组合,利用这一特点来统一拆分和组织数据
二、排序算法实现(主要部分)
/******************************** 直接插入排序 **********************************/
// 注意:下标从1开始
void InsertSort(SqList &L)
{
int i, j;
for (i = 2; i <= L.length; i++) {
if (L.elem[i] < L.elem[i - 1]) {
L.elem[0] = L.elem[i];
for (j = i - 1; j >= 1 && L.elem[j] > L.elem[0]; j--) {
L.elem[j + 1] = L.elem[j]; //写成了L.elem[j + 1] = L.elem[0];
}
L.elem[j + 1] = L.elem[0];
}
}
}
/******************************** 希尔排序 ************************************/
// 注意:下标从1开始
void ShellInsert(SqList &L, int dk)
{
int i, j;
for (i = dk + 1; i <= L.length; i++) {
if (L.elem[i] < L.elem[i - dk]) {
L.elem[0] = L.elem[i];
for (j = i - dk; j >= 1 && L.elem[j] > L.elem[0]; j -= dk) { //j -= dk 写成j--
L.elem[j + dk] = L.elem[j];
}
L.elem[j + dk] = L.elem[0];
}
}
}
void ShellSort(SqList &L, int dlta[], int t)
{
int i;
for (i = 0; i < t; i++) {
ShellInsert(L, dlta[i]);
}
}
/******************************** 快速排序 **********************************/
// 注意:下标从0开始
void Swap(int &v1, int &v2)
{
int tmp = v1;
v1 = v2;
v2 = tmp;
}
void QuickSort(SqList &L, int i, int j)
{
if (j - i + 1 <= 1) return;
int p1 = i + 1, p2 = j;
while (p1 < p2) {
while (p1 < j && p1 < p2 && L.elem[p1] <= L.elem[i]) p1++;
while (p2 > i && p2 > p1 && L.elem[p2] > L.elem[i]) p2--;
Swap(L.elem[p1], L.elem[p2]);
}
if (L.elem[i] >= L.elem[p1]) {
Swap(L.elem[i], L.elem[p1]);
QuickSort(L, i, p1 - 1);
QuickSort(L, p2 + 1, j);
} else if (p1 - 1 > i) {
Swap(L.elem[i], L.elem[p1 - 1]);
QuickSort(L, i, p1 - 2);
QuickSort(L, p2, j);
} else {
QuickSort(L, i + 1, j);
}
}
/******************************** 归并排序 ************************************/
// 注意:下标从0开始
void Merge(SqList &L, int i, int j)
{
int p, q;
int k = i;
int m = (i + j) / 2;
int M[MAX] = {0};
for (p = i, q = m + 1; p <= m && q <= j;) { //写成p <= i && q <= j
if (L.elem[p] <= L.elem[q]) //写成L.elem[i++] <= L.elem[j++]
M[k++] = L.elem[p++];
else
M[k++] = L.elem[q++];
}
while (p <= m) M[k++] = L.elem[p++]; //忘了写
while (q <= j) M[k++] = L.elem[q++]; //忘了写
for (k = i; k <= j; k++) L.elem[k] = M[k];
}
void MergeSort(SqList &L, int i, int j)
{
if (j - i + 1 <= 1) return;
int m = (i + j) / 2;
MergeSort(L, i, m);
MergeSort(L, m + 1, j);
Merge(L, i, j);
}
void Distribute(int times, int n)
{
int i;
// 初始化静态邻接表
for (i = 0; i < SL.length; i++) {
SL.SLList[i].next = NULL;
endp[i] = &SL.SLList[i];
}
// 进行第times次分配
for (i = 0; i < n; i++) {
int tmp = data[i];
tmp = (int)(tmp / pow(10, times - 1)) % 10;
SLCell *p = (SLCell *)malloc(sizeof(SLCell));
if (!p) exit(1);
p->data = data[i];
p->next = &SL.SLList[tmp];
if (SL.SLList[tmp].next) { //细节
SL.SLList[tmp].next->next = p;
} else {
endp[tmp] = p;
}
SL.SLList[tmp].next = p;
}
}
void Collect()
{
int i;
int k = 0;
for (i = 0; i < SL.length; i++) {
if (endp[i] != &SL.SLList[i]) {
SLCell *p = endp[i];
while (p != &SL.SLList[i]) {
data[k++] = p->data;
p = p->next; //忘写这一句,循环里总是忘记移动指针
}
}
}
}
/******************************** 基数排序 **********************************/
// 注意:下标从0开始
void RadixSort(int n)
{
if (n <= 1) return;
int i;
int times = GetTimes(n);
for (i = 1; i <= times; i++) {
Distribute(i, n);
Collect();
}
}
/******************************** 堆排序 *************************************/
void AdjustHeap(SqList &L, int length, int i)
{
int l = 2 * i;
int r = 2 * i + 1;
if (l > length && r > length) {
return;
} else if (r > length) {
if (L.elem[i].data < L.elem[l].data) {
Swap(L.elem[i], L.elem[l]);
AdjustHeap(L, length, l);
}
} else {
if (L.elem[i].data >= L.elem[l].data && L.elem[i].data >= L.elem[r].data) {
;
} else if (L.elem[l].data >= L.elem[i].data && L.elem[l].data >= L.elem[r].data) {
Swap(L.elem[i], L.elem[l]);
AdjustHeap(L, length, l);
} else {
Swap(L.elem[i], L.elem[r]);
AdjustHeap(L, length, r);
}
}
}
void CreateHeap(SqList &L)
{
int i;
//建立父子关系
for (i = 1; i <= L.length / 2; i++) {
L.elem[i].l = 2 * i;
if (2 * i + 1 <= L.length)
L.elem[i].r = 2 * i + 1;
else
L.elem[i].r = 0;
}
for (i = L.length / 2 + 1; i <= L.length; i++) {
L.elem[i].l = 0;
L.elem[i].r = 0;
}
//调整
for (i = L.length / 2; i >= 1; i--) {
AdjustHeap(L, L.length, i);
}
}
void HeapSort(SqList &L)
{
CreateHeap(L);
for (int i = L.length; i >= 2; i--) {
Swap(L.elem[i], L.elem[1]);
AdjustHeap(L, i - 1, 1);
}
}
/******************************** 二叉排序树 **********************************/
void InsertBST(BSTree &T, int data)
{
if (!T) {
T = (BSTree)malloc(sizeof(Node));
if (!T) exit(1);
T->data = data;
T->num = 1;
T->l = T->r = NULL;
return;
}
if (data < T->data) {
InsertBST(T->l, data);
} else if (data > T->data) {
InsertBST(T->r, data);
} else {
T->num++; return;
}
}
void TraverseBST(BSTree T, void(*Visit)(BSTree))
{
if (!T) return;
TraverseBST(T->l, Visit);
Visit(T);
TraverseBST(T->r, Visit);
}
/******************************** Trie ****************************************/
//拆分数位,从高位到低位依次插入 Trie,可实现十位数及以内的整数排序
Trie Init(Trie p)
{
p = (Trie)malloc(sizeof(Node));
if (!p) exit(1);
p->data = INFINITE;
p->num = 0;
p->bits = 0;
for (int i = 0; i < BASE; i++)
p->next[i] = NULL;
return p;
}
void TrieInsert(Trie T, int data, int n)
{
if (n == 0) return;
Trie p = T;
int i = 0;
while (i < n) {
int pt = (data / base[n - 1 - i]) % 10;
if (!p->next[pt]) {
Trie q;
p->next[pt] = Init(q);
}
p = p->next[pt];
i++;
}
if (p->num != 0) {
p->num++;
} else {
p->data = data;
p->num = 1;
p->bits = n;
}
}
void TrieTraverse(Trie T)
{
if (!T) return;
if (T->data != INFINITE) {
for (int i = 0; i < T->num; i++) {
v[T->bits].push_back(T->data);
}
}
for (int i = 0; i < BASE - 1; i++) {
if (T->next[i]) TrieTraverse(T->next[i]);
}
}