文章目录
测试点
插入排序
/* 插入排序 */
void InsertionSort(int A[], int N) {
int P, i;
int Tmp;
// 第一个元素可视为有序 从第二个元素(p = 1)开始
for (P = 1; P < N; P++) {
Tmp = A[P]; /* 取出未排序序列中的第一个元素*/
for (i = P; i > 0 && A[i - 1] > Tmp; i--) // i == 0 或者 前一个元素小于或等于未排序的第一个元素(Tmp)
A[i] = A[i - 1]; /*依次与已排序序列中元素比较并右移*/
A[i] = Tmp; /* 放进合适的位置 */
}
}
冒泡排序
1. 原始:
2. 冒泡排序中加入判断每趟是否进行排序语句:
/*冒泡排序*/
void Bubble_Sort(int A[], int N) {
int Tem;
int is_Sort;
for (int i = 0; i < N - 1; i++) {
// 一共N-1趟 每趟选一个最大值放在后面
is_Sort = 1;
for (int j = 0; j < N - i - 1; j++) {
if (A[j] > A[j + 1]) {
Tem = A[j];
A[j] = A[j + 1];
A[j + 1] = Tem;
is_Sort = 0;
}
}
if (is_Sort) // 若在这一趟中没有交换 说明已经有序
break;
}
}
双向冒泡排序
/*双向冒泡排序*/
void Double_Bubble_Sort(int A[], int N) {
int Tem;
int is_Sort;
for (int i = 0; i < N - 1; i++) {
// 一共N-1趟 每趟选一个最大值放在后面
is_Sort = 1;
if (i % 2 == 0) {
//printf("%d %d %d\n", i, i / 2, N - i / 2 - 1);
for (int j = i / 2; j < N - i / 2 - 1; j++) {
if (A[j] > A[j + 1]) {
Tem = A[j];
A[j] = A[j + 1];
A[j + 1] = Tem;
is_Sort = 0;
}
}
}
else {
//printf("%d %d %d\n", i, N - (i / 2 + 1) - 1, i / 2);
for (int j = N - (i / 2 + 1) - 1; j > i / 2; j--) {
if (A[j] < A[j - 1]) {
Tem = A[j];
A[j] = A[j - 1];
A[j - 1] = Tem;
is_Sort = 0;
}
}
}
//printf("%d", A[0]);
//for (int i = 1; i < N; i++) {
// printf(" %d", A[i]);
//}
//printf("\n");
if (is_Sort) // 若在这一趟中没有交换 说明已经有序
break;
}
}
希尔排序
1. 使用Sedgewick增量序列:
int Sedgewick[] = {
929, 505, 209, 109, 41, 19, 5, 1, 0 };
只使用了部分的Sedgewick增量序列
/* 希尔排序 - 用Sedgewick增量序列 */
void ShellSort_Sedgewick(int A[], int N){
int Si, D, P, i;
int Tmp;
/* 这里只列出一小部分增量 */
int Sedgewick[] = {
929, 505, 209, 109, 41, 19, 5, 1, 0 };
/* 初始的增量Sedgewick[Si]不能超过待排序列长度 */
for (Si = 0; Sedgewick[Si] >= N; Si++); // 让Si指向增量数组适当位置
for (D = Sedgewick[Si]; D > 0; D = Sedgewick[++Si]) {
// 按这个序列不断改变D --- 即不断改变间距
/* 插入排序*/
for (P = D; P < N; P++) {
// 从D往后开始
Tmp = A[P];
for (i = P; i >= D && A[i - D] > Tmp; i -= D) // 对前面每隔D个进行比较 第一个元素可视为有序 从第二个元素(i = P)开始(对每隔D个数进行排序)
A[i] = A[i - D];
A[i] = Tmp;
}
}
}
2. 使用Hibbard增量序列:
int Hibbard[] = {
1023, 511, 255, 127, 63, 31, 15, 7, 3, 1, 0 };
使用了部分的Hibbard序列
/* 希尔排序 - 用Hibbard增量序列 */
void ShellSort_Hibbard(int A[], int N) {
int Si, D, P, i;
int Tmp;
/* 这里只列出一小部分增量 */
int Hibbard[] = {
1023, 511, 255, 127, 63, 31, 15, 7, 3, 1, 0 };
/* 初始的增量Sedgewick[Si]不能超过待排序列长度 */
for (Si = 0; Hibbard[Si] >= N; Si++); // 让Si指向增量数组适当位置
for (D = Hibbard[Si]; D > 0; D = Hibbard[++Si]) {
// 按这个序列不断改变D --- 即不断改变间距
/* 插入排序*/
for (P = D; P < N; P++) {
// 从D往后开始
Tmp = A[P];
for (i = P; i >= D && A[i - D] > Tmp; i -= D) // 对前面每隔D个进行比较 第一个元素可视为有序 从第二个元素(i = P)开始(对每隔D个数进行排序)
A[i] = A[i - D];
A[i] = Tmp;
}
}
}
3. 使用原始的增量序列:
/* 希尔排序 - 用原始的增量序列 */
void ShellSort(int A[], int N) {
int Si, D, P, i;
int Tmp;
for (D = N / 2; D > 0; D = D / 2) {
// 按这个序列不断改变D --- 即不断改变间距
/* 插入排序*/
for (P = D; P < N; P++) {
// 从D往后开始
Tmp = A[P];
for (i = P; i >= D && A[i - D] > Tmp; i -= D) // 对前面每隔D个进行比较 第一个元素可视为有序 从第二个元素(i = P)开始(对每隔D个数进行排序)
A[i] = A[i - D];
A[i] = Tmp;
}
}
}
堆排序
/*堆排序*/
void Swap(int* A, int* B) {
int t = *A;
*A = *B;
*B = t;
}
void PercDown(int A[], int p, int N) {
// 对p调整 建立最大堆
int Parent, Child;
int X;
X = A[p];
for (Parent = p; (Parent * 2 + 1) < N; Parent = Child) {
Child = Parent * 2 + 1;
if ((Child != N - 1) && (A[Child] < A[Child + 1])) {
Child++;
}
if (X >= A[Child])
break;
else
A[Parent] = A[Child];
}
A[Parent] = X;
}
void HeapSort(int A[], int N) {
// 有效元素下标从0开始
for (int i = N / 2 - 1; i >= 0; i--) {
// 从第一个非终端结点开始
PercDown(A, i, N);
}
for (int i = N - 1; i > 0; i--) {
Swap(&A[0], &A[i]);
PercDown(A, 0, i);
}
}