课程给出代码
C语言:插入排序
void InsertionSort( ElementType A[], int N )
{ /* 插入排序 */
int P, i;
ElementType Tmp;
for ( P=1; P<N; P++ ) {
Tmp = A[P]; /* 取出未排序序列中的第一个元素*/
for ( i=P; i>0 && A[i-1]>Tmp; i-- )
A[i] = A[i-1]; /*依次与已排序序列中元素比较并右移*/
A[i] = Tmp; /* 放进合适的位置 */
}
}
C语言: 希尔排序 - 用Sedgewick增量序列
void ShellSort( ElementType A[], int N )
{ /* 希尔排序 - 用Sedgewick增量序列 */
int Si, D, P, i;
ElementType Tmp;
/* 这里只列出一小部分增量 */
int Sedgewick[] = {929, 505, 209, 109, 41, 19, 5, 1, 0};
for ( Si=0; Sedgewick[Si]>=N; Si++ )
; /* 初始的增量Sedgewick[Si]不能超过待排序列长度 */
for ( D=Sedgewick[Si]; D>0; D=Sedgewick[++Si] )
for ( P=D; P<N; P++ ) { /* 插入排序*/
Tmp = A[P];
for ( i=P; i>=D && A[i-D]>Tmp; i-=D )
A[i] = A[i-D];
A[i] = Tmp;
}
}
C语言:堆排序
void Swap( ElementType *a, ElementType *b )
{
ElementType t = *a; *a = *b; *b = t;
}
void PercDown( ElementType A[], int p, int N )
{ /* 改编代码4.24的PercDown( MaxHeap H, int p ) */
/* 将N个元素的数组中以A[p]为根的子堆调整为最大堆 */
int Parent, Child;
ElementType 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++; /* Child指向左右子结点的较大者 */
if( X >= A[Child] ) break; /* 找到了合适位置 */
else /* 下滤X */
A[Parent] = A[Child];
}
A[Parent] = X;
}
void HeapSort( ElementType A[], int N )
{ /* 堆排序 */
int i;
for ( i=N/2-1; i>=0; i-- )/* 建立最大堆 */
PercDown( A, i, N );
for ( i=N-1; i>0; i-- ) {
/* 删除最大堆顶 */
Swap( &A[0], &A[i] ); /* 见代码7.1 */
PercDown( A, 0, i );
}
}
C语言:归并排序 - 递归实现
/* 归并排序 - 递归实现 */
/* L = 左边起始位置, R = 右边起始位置, RightEnd = 右边终点位置*/
void Merge( ElementType A[], ElementType TmpA[], int L, int R, int RightEnd )
{ /* 将有序的A[L]~A[R-1]和A[R]~A[RightEnd]归并成一个有序序列 */
int LeftEnd, NumElements, Tmp;
int i;
LeftEnd = R - 1; /* 左边终点位置 */
Tmp = L; /* 有序序列的起始位置 */
NumElements = RightEnd - L + 1;
while( L <= LeftEnd && R <= RightEnd ) {
if ( A[L] <= A[R] )
TmpA[Tmp++] = A[L++]; /* 将左边元素复制到TmpA */
else
TmpA[Tmp++] = A[R++]; /* 将右边元素复制到TmpA */
}
while( L <= LeftEnd )
TmpA[Tmp++] = A[L++]; /* 直接复制左边剩下的 */
while( R <= RightEnd )
TmpA[Tmp++] = A[R++]; /* 直接复制右边剩下的 */
for( i = 0; i < NumElements; i++, RightEnd -- )
A[RightEnd] = TmpA[RightEnd]; /* 将有序的TmpA[]复制回A[] */
}
void Msort( ElementType A[], ElementType TmpA[], int L, int RightEnd )
{ /* 核心递归排序函数 */
int Center;
if ( L < RightEnd ) {
Center = (L+RightEnd) / 2;
Msort( A, TmpA, L, Center ); /* 递归解决左边 */
Msort( A, TmpA, Center+1, RightEnd ); /* 递归解决右边 */
Merge( A, TmpA, L, Center+1, RightEnd ); /* 合并两段有序序列 */
}
}
void MergeSort( ElementType A[], int N )
{ /* 归并排序 */
ElementType *TmpA;
TmpA = (ElementType *)malloc(N*sizeof(ElementType));
if ( TmpA != NULL ) {
Msort( A, TmpA, 0, N-1 );
free( TmpA );
}
else printf( "空间不足" );
}
C语言:归并排序 - 循环实现
/* 归并排序 - 循环实现 */
/* 这里Merge函数在递归版本中给出 */
/* length = 当前有序子列的长度*/
void Merge_pass( ElementType A[], ElementType TmpA[], int N, int length )
{ /* 两两归并相邻有序子列 */
int i, j;
for ( i=0; i <= N-2*length; i += 2*length )
Merge( A, TmpA, i, i+length, i+2*length-1 );
if ( i+length < N ) /* 归并最后2个子列*/
Merge( A, TmpA, i, i+length, N-1);
else /* 最后只剩1个子列*/
for ( j = i; j < N; j++ ) TmpA[j] = A[j];
}
void Merge_Sort( ElementType A[], int N )
{
int length;
ElementType *TmpA;
length = 1; /* 初始化子序列长度*/
TmpA = malloc( N * sizeof( ElementType ) );
if ( TmpA != NULL ) {
while( length < N ) {
Merge_pass( A, TmpA, N, length );
length *= 2;
Merge_pass( TmpA, A, N, length );
length *= 2;
}
free( TmpA );
}
else printf( "空间不足" );
}
09-排序1 排序 (25 分)
给定N个(长整型范围内的)整数,要求输出从小到大排序后的结果。
本题旨在测试各种不同的排序算法在各种数据情况下的表现。各组测试数据特点如下:
数据1:只有1个元素;
数据2:11个不相同的整数,测试基本正确性;
数据3:103个随机整数;
数据4:104个随机整数;
数据5:105个随机整数;
数据6:105个顺序整数;
数据7:105个逆序整数;
数据8:105个基本有序的整数;
数据9:105个随机正整数,每个数字不超过1000。
输入格式:
输入第一行给出正整数N(≤E5),随后一行给出N个(长整型范围内的)整数,其间以空格分隔。
输出格式:
在一行中输出从小到大排序后的结果,数字间以1个空格分隔,行末不得有多余空格。
强推代码来源: https://blog.csdn.net/xijujie/article/details/53103012
#include <stdio.h>
#include <stdlib.h>
#define N 100000
#define Cutoff 10
#define Radix 10
void percdown(long *a, int n, int i);
void merge(long *a, long *tmp, int start, int end, int middle);
void msort(long *a, long *tmp, int start, int end);
void merge_pass(long *a, long *tmp, int n, int length);
void q_sort(long *a, int left, int right);
void bubble_sort(long *a, int n);
void insertion_sort(long *a, int n);
void selection_sort(long *a, int n);
void shell_sort(long *a, int n);
void shellsedgewick_sort(long *a, int n);
void heap_sort(long *a, int n);
void merge1_sort(long *a, int n);
void merge2_sort(long *a, int n);
void quick_sort(long *a, int n);
void radix_sort(long *a, int n);
int main() {
int i, n;
long a[N];
scanf("%d", &n);
for (i = 0;i < n;i++)
scanf("%ld", &a[i]);
radix_sort(a, n);
printf("%ld", a[0]);
for (i = 1;i < n;i++)
printf(" %ld", a[i]);
return 0;
}
//冒泡排序
void bubble_sort(long *a, int n) {
int i, j, flag;
long temp;
for (i = n - 1;i > 0;i--) {
flag = 0;
for (j = 0;j < i;j++) {
if (a[j] > a[j + 1]) {
temp = a[j];
a[j] = a[j + 1];
a[j + 1] = temp;
flag = 1;
}
}
if (!flag) break;
}
}
//插入排序
void insertion_sort(long *a, int n) {
int i, j;
long temp;
for (i = 1;i < n;i++) {
temp = a[i];
for (j = i; j > 0 && a[j - 1] > temp; j--)
a[j] = a[j - 1];
a[j] = temp;
}
}
//选择排序
void selection_sort(long *a, int n) {
int i, j, t;
long temp;
for (i = 0;i < n - 1;i++) {
temp = a[i];
t = i;
for (j = i + 1;j < n;j++) {
if (a[j] < temp) {
temp = a[j];
t = j;
}
}
a[t] = a[i];
a[i] = temp;
}
}
//希尔排序-希尔增量
void shell_sort(long *a, int n) {
int i, j, d;
long temp;
for (d = n / 2;d > 0;d /= 2) {
for (i = d;i < n;i++) {
temp = a[i];
for (j = i;j >= d && a[j - d] > temp;j -= d)
a[j] = a[j - d];
a[j] = temp;
}
}
}
//希尔排序-sedgewick增量
void shellsedgewick_sort(long *a, int n) {
int i, j, d, si;
int Sedgewick[] = { 929, 505, 209, 109, 41, 19, 5, 1, 0 };
long temp;
for (si = 0;Sedgewick[si] >= n;si++)
;
for (;Sedgewick[si] > 0;si++) {
d = Sedgewick[si];
for (i = d;i < n;i++) {
temp = a[i];
for (j = i;j >= d && a[j - d] > temp;j -= d)
a[j] = a[j - d];
a[j] = temp;
}
}
}
//堆排序
void heap_sort(long *a, int n) {
int i;
long temp;
for (i = (n - 2) / 2; i >= 0; i--)
percdown(a, n, i);
for (i = n - 1;i > 0;i--) {
temp = a[i];
a[i] = a[0];
a[0] = temp;
percdown(a, i, 0);
}
}
void percdown(long *a, int n, int i) {
int child;
long x = a[i];
for (;i * 2 + 1 <= n - 1;i = child) {
child = i * 2 + 1;
if (child < n - 1 && a[child + 1] > a[child])
child++;
if (x >= a[child]) break;
else a[i] = a[child];
}
a[i] = x;
}
//归并排序-递归实现
void merge1_sort(long *a, int n) {
long *tmp = (long*)malloc(n*sizeof(long));
msort(a, tmp, 0, n - 1);
free(tmp);
}
void msort(long *a, long *tmp, int start, int end) {
int middle;
if (start < end) {
middle = (start + end) / 2;
msort(a, tmp, start, middle);
msort(a, tmp, middle + 1, end);
merge(a, tmp, start, end, middle);
}
}
void merge(long *a, long *tmp, int start, int end, int middle) {
int l, r, s;
s = start;
l = start;
r = middle + 1;
while (l <= middle && r <= end) {
if (a[l] <= a[r]) tmp[s++] = a[l++];
else tmp[s++] = a[r++];
}
while (l <= middle) tmp[s++] = a[l++];
while (r <= end) tmp[s++] = a[r++];
for (;start <= end;start++)
a[start] = tmp[start];
}
//归并排序-循环实现
void merge2_sort(long *a, int n) {
int length = 1;
long *tmp = (long*)malloc(n*sizeof(long));
while (length < n) {
merge_pass(a, tmp, n, length);
length *= 2;
merge_pass(tmp, a, n, length);
length *= 2;
}
free(tmp);
}
void merge_pass(long *a, long *tmp, int n, int length) {
int i, j;
for (i = 0;i + 2 * length <= n;i += 2*length)
merge(a, tmp, i, i + 2 * length - 1, i + length - 1);
if (i + length <= n)
merge(a, tmp, i, n - 1, i + length - 1);
else
for (j = i;j < n;j++)
tmp[j] = a[j];
}
//快速排序
void quick_sort(long *a, int n) {
q_sort(a, 0, n - 1);
}
void q_sort(long *a, int left, int right) {
long pivot, temp;
int i, j, center;
if (right - left + 1 > Cutoff) {
center = (left + right) / 2;
if (a[center] < a[left]) {
temp = a[center];a[center] = a[left];a[left] = temp;
}
if (a[right] < a[left]) {
temp = a[right];a[right] = a[left];a[left] = temp;
}
if (a[right] < a[center]) {
temp = a[right];a[right] = a[center];a[center] = temp;
}
temp = a[right - 1];a[right - 1] = a[center];a[center] = temp;
pivot = a[right - 1];
i = left;
j = right - 1;
for (;;) {
while (a[++i] < pivot);
while (a[--j] > pivot);
if (i < j) {
temp = a[i];a[i] = a[j];a[j] = temp;
}
else break;
}
temp = a[i];a[i] = a[right - 1];a[right - 1] = temp;
q_sort(a, left, i - 1);
q_sort(a, i + 1, right);
}
else
insertion_sort(a + left, right - left + 1);
}
//基数排序-次位优先
struct Node {
int data;
Node* next;
};
struct Bucket {
Node *head, *tail;
};
void radix_sort(long *a, int n) {
int d, di, i, flag;
long t;
Bucket b[Radix*2 - 1];//19个桶 -9--1,0,1-9;
Node *tmp, *p, *list = NULL;
for (i = 0;i <= (Radix-1) * 2;i++)
b[i].head = b[i].tail = NULL;
for (i = n - 1;i >= 0;i--) {
tmp = (Node*)malloc(sizeof(Node));
tmp->data = a[i];
tmp->next = list;
list = tmp;
}
for (d = 1;;d++) {
p = list;
flag = 0;
while (p) {
t = p->data;
for (i = 1;i <= d;i++) {
di = t % Radix;t /= Radix;
}
if (di != 0) flag = 1;
di += Radix-1;
tmp = p;
p = p->next;
tmp->next = NULL;
if (!b[di].head)
b[di].head = b[di].tail = tmp;
else {
b[di].tail->next = tmp;
b[di].tail = tmp;
}
}
if (!flag) break;
else {
list = NULL;
for (i = (Radix - 1) * 2;i >= 0;i--) {
if (b[i].head) {
b[i].tail->next = list;
list = b[i].head;
b[i].head = b[i].tail = NULL;
}
}
}
}
for (i = 0;i < n;i++) {
a[i] = b[Radix - 1].head->data;
b[Radix - 1].head = b[Radix - 1].head->next;
}
}
09-排序2 Insert or Merge (25 分)
According to Wikipedia:
Insertion sort iterates, consuming one input element each repetition, and growing a sorted output list. Each iteration, insertion sort removes one element from the input data, finds the location it belongs within the sorted list, and inserts it there. It repeats until no input elements remain.
Merge sort works as follows: Divide the unsorted list into N sublists, each containing 1 element (a list of 1 element is considered sorted). Then repeatedly merge two adjacent sublists to produce new sorted sublists until there is only 1 sublist remaining.
Now given the initial sequence of integers, together with a sequence which is a result of several iterations of some sorting method, can you tell which sorting method we are using?
Input Specification:
Each input file contains one test case. For each case, the first line gives a positive integer N (≤100). Then in the next line, N integers are given as the initial sequence. The last line contains the partially sorted sequence of the N numbers. It is assumed that the target sequence is always ascending. All the numbers in a line are separated by a space.
Output Specification:
For each test case, print in the first line either “Insertion Sort” or “Merge Sort” to indicate the method used to obtain the partial result. Then run this method for one more iteration and output in the second line the resuling sequence. It is guaranteed that the answer is unique for each test case. All the numbers in a line must be separated by a space, and there must be no extra space at the end of the line.
代码来源: https://blog.csdn.net/xijujie/article/details/53155723
#include <iostream>
#include <algorithm>
int main() {
int n, i, count, length, a[100], b[100];
int flag = 1;
scanf("%d", &n);
for (i = 0;i < n;i++)
scanf("%d", &a[i]);
for (i = 0;i < n;i++)
scanf("%d", &b[i]);
//i从0到n-1遍历,当b[i+1]<b[i],继续遍历判断a[i] == b[i]
//不相等,则为归并,否则为插入
for (i = 1; b[i] >= b[i - 1]; i++);
count = i;
for (;i < n && a[i] == b[i];i++);
if (i == n) {
printf("Insertion Sort\n");
std::sort(b, b + count + 1);
printf("%d", b[0]);
for (i = 1;i < n;i++)
printf(" %d", b[i]);
}
else {
printf("Merge Sort\n");
for (length = 2;flag;length *= 2) {
//在长度为length片段满足顺序排列的基础上判断length*2
for (i = length; i < n; i += length * 2) {
if (b[i - 1] > b[i]) {
flag = 0;break;
}
}
}
for (i = 0;i + length <= n;i += length)
std::sort(b + i, b + i + length);
std::sort(b + i, b + n);
printf("%d", b[0]);
for (i = 1;i < n;i++)
printf(" %d", b[i]);
//另一种比较直接的做法是模拟merge过程,每一步都判断是否与b相等
}
return 0;
}
09-排序3 Insertion or Heap Sort (25 分)
According to Wikipedia:
Insertion sort iterates, consuming one input element each repetition, and growing a sorted output list. Each iteration, insertion sort removes one element from the input data, finds the location it belongs within the sorted list, and inserts it there. It repeats until no input elements remain.
Heap sort divides its input into a sorted and an unsorted region, and it iteratively shrinks the unsorted region by extracting the largest element and moving that to the sorted region. it involves the use of a heap data structure rather than a linear-time search to find the maximum.
Now given the initial sequence of integers, together with a sequence which is a result of several iterations of some sorting method, can you tell which sorting method we are using?
Input Specification:
Each input file contains one test case. For each case, the first line gives a positive integer N (≤100). Then in the next line, N integers are given as the initial sequence. The last line contains the partially sorted sequence of the N numbers. It is assumed that the target sequence is always ascending. All the numbers in a line are separated by a space.
Output Specification:
For each test case, print in the first line either “Insertion Sort” or “Heap Sort” to indicate the method used to obtain the partial result. Then run this method for one more iteration and output in the second line the resulting sequence. It is guaranteed that the answer is unique for each test case. All the numbers in a line must be separated by a space, and there must be no extra space at the end of the line.
代码来源:https://blog.csdn.net/xijujie/article/details/53155865
#include <iostream>
#include <algorithm>
int main() {
int n, i, count, length, a[100], b[100];
int flag = 1;
scanf("%d", &n);
for (i = 0;i < n;i++)
scanf("%d", &a[i]);
for (i = 0;i < n;i++)
scanf("%d", &b[i]);
for (i = 1; b[i] >= b[i - 1]; i++);
count = i;
for (;i < n && a[i] == b[i];i++);
if (i == n) {
printf("Insertion Sort\n");
std::sort(b, b + count + 1);
printf("%d", b[0]);
for (i = 1;i < n;i++)
printf(" %d", b[i]);
}
else {
printf("Heap Sort\n");
for (i = n - 1;i > 0 && b[i] > b[i - 1];i--);
std::pop_heap(b, b + i + 1);
printf("%d", b[0]);
for (i = 1;i < n;i++)
printf(" %d", b[i]);
}
return 0;
}