算法与数据结构——排序
前提
void X_Sort (ElementType A[], int N) //默认讨论从小到大的整数排序
-
冒泡排序
void Bubble_Sort(ElementType A[], int N)
{
for (int P = N - 1; P >= 0; P--)
{
int flag = 1;
for (int i = 0; i < P; i++)
{
if (A[i] > A[i + 1])
{
Swap(A[i], A[i + 1]); //交换两数
flag = 1;
}
}
if (flag == 0) break;//无交换则退出
}
}
- 优点:比较稳定,不仅适用于数组,而且适用于单向链表
-
插入排序
void Insert_Sort(ElementType A[], int N)
{
int i;
for (int p = 1; p < N; p++)
{
int Tmp = A[p];
for ( i = p; i > 0 && A[i - 1] > Tmp; i--)
{
A[i] = A[i - 1];
}
A[i] = Tmp;
}
}
优点:稳定
-
希尔排序
void Sheel_Sort(ElementType A[], int N)
{
int i;
for (int D = N / 2; D > 0; D /= 2) //D为增量序列(此为最原始的希尔排序)
{
for (int P = D; P < N; P++)
{
int Tmp = A[P];
for ( i = P; i >= D && A[i - D] > Tmp; i -= D)
{
A[i] = A[i - D];
}
A[i] = Tmp;
}
}
}
增量序列D因情况而异,特殊情况下互质的增量序列是没有效果的;
-
选择排序
void Select_Sort(ElementType A[], int N)
{
int minid;
for (int i = 0; i < N; i++)
{
minid = i;
for (int j = i + 1; j < N - 1; j++)
{
if (A[j] < A[minid])
{
minid = j;
}
}
int tmp = A[i];
A[i] = A[minid];
A[minid] = tmp;
}
}
-
堆排序
-
归并排序
-
递归实现
void merge(ElementType A[], ElementType tempArr[], int left, int mid, int right)
{
int L_pos = left;
int R_pos = mid + 1;
int pos = left;
while (L_pos <= mid && R_pos <= right)
{
if (A[L_pos] < A[R_pos])
{
tempArr[pos++] = A[L_pos++];
}
else
{
tempArr[pos++] = A[R_pos++];
}
}
while (L_pos <= mid)
{
tempArr[pos++] = A[L_pos++];
}
while (R_pos <= right)
{
tempArr[pos++] = A[R_pos++];
}
while (left <= right)
{
A[left] = tempArr[left];
left++;
}
}
void msort(ElementType A[], ElementType tempArr[], int left, int right)
{
if (left < right)
{
int mid = (left + right) / 2;
msort(A, tempArr, left, mid);
msort(A, tempArr, mid + 1, right);
merge(A, tempArr, left, mid, right);
}
}
void Merge_sort(ElementType A[], int N)
{
//分配一个辅助数组
int* tempArr = (int*)malloc(N * sizeof(ElementType));
if (tempArr)
{
msort(A, tempArr, 0, N - 1);
free(tempArr);
}
else
{
printf("error: failed to allocate memory");
}
}
- 非递归算法(循环实现)
/* 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 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 ) {
//循环使用A[]和TmpA[],节省了Merge()函数中每次都要将TmpA中有序数组复制回A的过程
Merge_pass( A, TmpA, N, length );
length *= 2;
Merge_pass( TmpA, A, N, length );
length *= 2;
}
free( TmpA );
}
else printf( "空间不足" );
}
未完待续。。。。。