5-12 排序 (25分)

5-12 排序   (25分)

給定NN個(長整型範圍內的)整數,要求輸出從小到大排序後的結果。

本題旨在測試各種不同的排序算法在各種數據情況下的表現。各組測試數據特點如下:

數據1:只有1個元素;

數據2:11個不相同的整數,測試基本正確性;

數據3:103個隨機整數;

數據4:104個隨機整數;

數據5:105個隨機整數;

數據6:105個順序整數;

數據7:105個逆序整數;

數據8:105個基本有序的整數;

數據9:105個隨機正整數,每個數字不超過1000。

輸入格式:

輸入第一行給出正整數NN\le 10^5105),隨後一行給出NN個(長整型範圍內的)整數,其間以空格分隔。

輸出格式:

在一行中輸出從小到大排序後的結果,數字間以1個空格分隔,行末不得有多餘空格。

輸入樣例:

11
4 981 10 -17 0 -20 29 50 8 43 -5

輸出樣例:

-20 -17 -5 0 4 8 10 29 43 50 981




#include<stdio.h>  
#include<stdlib.h>  
#include<algorithm>
#define MAX 100000
using namespace std;  

void Swap(int *a,int *b)
{
	int t;
	t = *a;
	*a = *b;
	*b = t;
}

void print(int A[],int N)
{
	for(int i = 0; i < N; i++)
	{
		printf("%d",A[i]);
		if(i < N - 1)
		{
			printf(" ");
		}
	}
	printf("\n");
}

/*冒泡排序*/
void maopao_sort(int A[],int N)
{
	int p,flag;
	for(p = N - 1; p >= 0; p--)
	{
		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;
	}
	print(A,N);
}

/*插入排序*/
void Insert_sort(int A[],int N)
{
	int p,Tmp;
	for(int i = 1; i < N; i++)
	{
		Tmp = A[i];
		for(p = i; p > 0 && A[p - 1] > Tmp; p--)
		{
			A[p] = A[p - 1];/*將大的一個一個向後推*/ 
		}
		A[p] = Tmp;/*最後放到合適的位置*/
	}
	print(A,N);
}

/*希爾排序*/
void shell_sort(int A[],int N)
{
	int p,Tmp,d,si,i;
	int Sedgewick[] = {929, 505, 209, 109, 41, 19, 5, 1, 0};
	
	for(int si = 0; Sedgewick[si] >= N; si++);/*初始增量Sedgewick[si]不能超過序列長度(N)*/
	
	for(d = Sedgewick[si]; d > 0; d = Sedgewick[++si])
	{
		for(i = d; i < N; i++)/*在數組A中,從下標爲d開始往後掃描*/
		{
			Tmp = A[i];
			for(p = i; p >= d && A[p - d] > Tmp; p -= d)/*每次判斷A[p - d] 與 A[p]的大小關係,當p < d時說明A[p]前沒有d那麼多個數了*/
			{
				A[p] = A[p - d];
			}
			A[p] = Tmp;
		}	
	}
	print(A,N);
}

/*堆排序*/ 
void percDown(int A[],int p,int N)/*構建最大堆,因爲再後面要將數組第一個元素與最後一個互換,所以再輸出的時候就是從小到大輸出的*/
{
	int child,parent;
	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 Heap_sort(int A[],int N)
{
	for(int i = (N - 1)/2 ; i >= 0; i--)
	{
		percDown(A,i,N);
	}
	
	for(int i = N - 1; i > 0; i--)
	{
		Swap(&A[0],&A[i]);/*交換後數組A的最後一位就是最大值,並且下次循環的時候不會將最後一位進入percDown函數*/
		
		percDown(A,0,i);
	}
	print(A,N);
}

/*歸併排序*/

void Merge(int A[],int TmpA[],int L,int R,int Rightend)/* L = 左邊起始位置, R = 右邊起始位置, RightEnd = 右邊終點位置*/
{
	int num,Leftend;
	Leftend = R - 1;
	int Tmp = L;
	num = Rightend - L + 1;
	
	while(L <= Leftend && R <= Rightend)
	{
		if(A[L] >= A[R])
		{
			TmpA[Tmp++] = A[R++];	
		} 
		else
		{
			TmpA[Tmp++] = A[L++];
		}
	}
	
	while(L <= Leftend) TmpA[Tmp++] = A[L++];
	while(R <= Rightend) TmpA[Tmp++] = A[R++];
	
	for(int i = 0; i < num; i++, Rightend--)
	{
		A[Rightend] = TmpA[Rightend];/*從後往前賦給A數組*/ 
	}
}

void Msort(int A[],int TmpA[],int L,int Rightend)
{
	int mid;
	if(L < Rightend)
	{
		mid = (L + Rightend)/2;
		Msort(A,TmpA,L,mid);
		Msort(A,TmpA,mid + 1,Rightend);
		Merge(A,TmpA,L,mid + 1,Rightend);
	}
}

void MergeSort(int A[],int N)/*遞歸方法*/
{
	int *TmpA = (int *)malloc(N * sizeof(int));
	if(TmpA != NULL)
	{
		Msort(A,TmpA,0,N - 1);
		free(TmpA);
	}
	else
	{
		printf("空間不足");	
	} 
	print(A,N);
}

void Merge_pass(int A[],int TmpA[],int length,int N)/*循環實現*/
{
	int i,j;
	for(i = 0 ; i <= N - length*2; i += length*2)
	{
		Merge(A, TmpA, i, i + length, i + length*2 - 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(int A[],int N)
{
	int length = 1;
	int *TmpA = (int *)malloc(N * sizeof(int));
	if(TmpA != NULL)
	{
		while(length < N)
		{
			Merge_pass(A,TmpA,length,N);
			length *= 2;
			Merge_pass(TmpA,A,length,N);
			length *= 2;
		}
		free(TmpA);
	}
	else
	{
		printf("空間不足");
	}
	print(A,N);
}

int main(void)
{
	int N;
	int A[MAX];
	scanf("%d",&N);
	for(int i = 0; i < N; i++)
	{
		scanf("%d",&A[i]);
	}
	
//	maopao_sort(A,N);/*冒泡排序*/
	
//	Insert_sort(A,N);/*插入排序*/
	
//	shell_sort(A,N);/*希爾排序*/

//	Heap_sort(A,N);/*堆排序*/

//	MergeSort(A,N);/*歸併排序 - 遞歸方法*/
	
	Merge_Sort(A,N);/*歸併排序 - 循環實現*/
	
	return 0;
}





發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章