PTA 09-排序1 排序(附全部算法实现及结果)

PTA 09-排序1 排序(25 分)

题目地址:09-排序1 排序(25 分)
题目描述:

给定N个(长整型范围内的)整数,要求输出从小到大排序后的结果。
本题旨在测试各种不同的排序算法在各种数据情况下的表现。各组测试数据特点如下:

  • 数据1:只有1个元素;

  • 数据2:11个不相同的整数,测试基本正确性;

  • 数据3:103个随机整数;

  • 数据4:104个随机整数;

  • 数据5:105个随机整数;

  • 数据6:105个顺序整数;

  • 数据7:105个逆序整数;

  • 数据8:105个基本有序的整数;

  • 数据9:105个随机正整数,每个数字不超过1000。

  • 输入格式:
    入第一行给出正整数N(≤10^​5)随后一行给出N个(长整型范围内的)整数,其间以空格分隔。

  • 输出格式:
    在一行中输出从小到大排序后的结果,数字间以1个空格分隔,行末不得有多余空格。


解题方法:
本博文将会给出以下几种排序算法的代码以及效果

  1. 冒泡排序
  2. 插入排序
  3. 原始的希尔排序
  4. Hibibbard增量序列的希尔排序
  5. Sedgewick增量序列的希尔排序
  6. 堆排序
  7. 递归版的归并排序
  8. 循环版的归并排序

程序:

#include <stdio.h>
#include <stdlib.h>
#include <algorithm>
#include <cmath>
using namespace std;

void Bubble_sort(long A[], int N)
{	/* 冒泡排序 */
	for (int P = N-1; P >=1; P--)
	{
		int flag = 0;
		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(long A[], int N)
{	/* 插入排序 */
	int P, i;
	for (P = 1; P < N; P++)
	{
		long temp = A[P];
		for (i = P; i >= 1 && temp < A[i-1]; i--)
			A[i] = A[i-1];
		A[i] = temp;
	}
}

void Shell_sort(long A[], int N)
{	/* 原始的希尔排序 */
	int P, i, D;
	for (D = N/2; D >= 1; D /= 2)
	{
		for (P = D; P < N; P++)
		{
			long temp = A[P];
			for (i = P; i >= D && temp < A[i-D]; i -= D)
				A[i] = A[i-D];
			A[i] = temp;
		}
	}
}

void ShellHib_sort(long A[], int N)
{	/* Hibbard增量序列的希尔排序 */
	int k = log2(N), P, i, D;
	for (D = pow(2, k)-1; D >= 1 && k >= 1; D = pow(2, --k)-1)
	{
		// printf("%d %d\n", k, D);
		for (P = D; P < N; P++)
		{
			long temp = A[P];
			for (i = P; i >= D && temp < A[i-D]; i -= D)
				A[i] = A[i-D];
			A[i] = temp;
		}
	}
}

void ShellSed_sort(long A[], int N)
{	/* Sedgewick增量序列的希尔排序 */
	int D, P, j, i = 0;
	int Sedgewick[] = {3905, 929, 505, 209, 109, 41, 19, 5, 1, 0};
	for (D = Sedgewick[i]; D >= N; D = Sedgewick[i++]);
	for (D = Sedgewick[i]; D > 0; D = Sedgewick[++i])
	{
		for (P = D; P < N; P++)
		{
			long temp = A[P];
			for (j = P; j >= D && temp < A[j-D]; j -= D)
				A[j] = A[j-D];
			A[j] = temp;
		}
	}
}

/***************** 堆排序 **************/
void PrecDown(long A[], int p, int N)
{
	int parent, child;
	long x = A[p];
	for (parent = p; (2*parent+1) < N ; parent = child)
	{
		child = 2*parent + 1;
		if (child != N-1 && A[child+1] > A[child])
			child++;	// 存在右儿子并且右儿子比做儿子大
		if (A[child] < x) 
			break;
		else
			A[parent] = A[child];
	}
	A[parent] = x;
}

void Heap_sort(long A[], int N)
{
	for (int i = N/2; i >= 0; i--)
		PrecDown(A, i, N);	/* 建立堆 */
	for (int i = N-1; i > 0; i--)
	{
		swap(A[0], A[i]);
		PrecDown(A, 0, i);
	}
}
/*************** 堆排序结束 ************/

/**************** 归并排序(递归版) *************/
void Merge(long A[], long temp[], int L, int R, int RightEnd)
{
	int LeftEnd = R - 1;
	int Num = RightEnd - L + 1;
	int temIdx = L, i;
	while (L <= LeftEnd && R <= RightEnd)
	{
		if (A[L] <= A[R])
			temp[temIdx++] = A[L++];
		else
			temp[temIdx++] = A[R++];
	}
	while (L <= LeftEnd)	/* 如果左边部分有多余 */
		temp[temIdx++] = A[L++];
	while (R <= RightEnd)   /* 如果右边部分有多余 */
		temp[temIdx++] = A[R++];
     for( i = 0; i < Num; i++, RightEnd-- )
         A[RightEnd] = temp[RightEnd]; /* 加temp中的元素返回给A */
}

void MSort(long A[], long temp[], int L, int RightEnd)
{
	int center;
	if (L < RightEnd)
	{
		center = (L + RightEnd) / 2;
		MSort(A, temp, L, center);
		MSort(A, temp, center+1, RightEnd);
		Merge(A, temp, L, center+1, RightEnd);
	}
}

void Merge_sort(long A[], int N)
{	/* 归并排序入口程序 */
	long *temp;
	temp = (long*)malloc(N * sizeof(long));
	MSort(A, temp, 0, N-1);
	free(temp);
}
/************** 归并排序结束(递归版) ***********/


/**************** 归并排序(循环版) *************/
void Merge1(long A[], long temp[], int L, int R, int RightEnd)
{
	int LeftEnd = R - 1;
	int temIdx = L;
	while (L <= LeftEnd && R <= RightEnd)
	{
		if (A[L] <= A[R])
			temp[temIdx++] = A[L++];
		else
			temp[temIdx++] = A[R++];
	}
	while (L <= LeftEnd)	/* 如果左边部分有多余 */
		temp[temIdx++] = A[L++];
	while (R <= RightEnd)   /* 如果右边部分有多余 */
		temp[temIdx++] = A[R++];
	/* 与Megre比少了最后一步 */
}

void Merge_pass(long A[], long temp[], int N, int length)
{
	int i, j;
	for (i = 0; i < N-2*length; i += 2*length)	
		Merge1(A, temp, i, i+length, i+2*length-1);
	if (i+length <= N-1)	/* 超过一个子序列 =号必须加*/
		Merge1(A, temp, i, i+length, N-1);
	else	/* 只剩一个子序列不到了 */
		for (j = i; j <= N-1; j++)
			temp[j] = A[j];
}

void Merge_sort1(long A[], int N)
{
	long* temp;
	int length = 1;
	temp = (long*)malloc(N * sizeof(long));
	while (length < N)
	{	/* 这么做A就是排好序的数组 */
		Merge_pass(A, temp, N, length);
		length *= 2;
		Merge_pass(temp, A, N, length);
		length *= 2;
	}
}
/*************** 归并排序结束(循环版) **********/


int main(int argc, char const *argv[])
{
	int N;
	scanf("%d", &N);
	long A[N];
	for (int i = 0; i < N; i++)
		scanf("%ld", &A[i]);
	ShellSed_sort(A, N);
	for (int i = 0; i < N; i++)
	{
		if (i != 0)
			printf(" ");
		printf("%ld", A[i]);
	}
	return 0;
}

运行效果:

  • 冒泡排序
    冒泡排序
  • 插入排序
    插入排序
  • 原始的希尔排序
    原始的希尔排序
  • Hibbard增量序列的希尔排序
    Hibbard增量序列的希尔排序
  • Sedgewick增量序列的希尔排序
    Sedgewick增量序列的希尔排序
  • 堆排序
    堆排序
  • 归并排序递归版
    归并排序递归版
  • 归并排序循环版
    归并排序循环版
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值