归并排序,插入排序和堆排序A1089insert or merge和A1098insertion or heap sort

归并排序(merge sort):
归并排序是分治思想,类似完全二叉树,先用递归的方法,将其分解(divide)为小数组,递归边界是小数组中数据只为一个,然后用治(conquer)将小数组排序,整合成有序数列。
例 :
原数组: 14568973
分:
1: 1456 8973 拆分成完全二叉树序列
2: 14 56 89 73
3: 1 4 5 6 8 9 7 3
治:
1: 14 56 89 37 对每个小序列进行排序
2: 1456 3789
3: 13456789
在治(conquer)过程中,可以设置两个指针分别指向两个子序列,因为子序列必是有序数列,只需依次对两个指针指向的数比较大小放在temp数组中,再将temp数组放回原数组即可。
因为使用完全二叉树,数的深度是log2n,中间对数组进行遍历,所以归并排序(merge sort)的时间复杂度是O(nlogn).
插入排序(insert sort):
插入排序的思想是将数组按照顺序,将待排序数据插入到之前已排序数列。总共需要n-1趟排序,从第一个数据开始依次比较,与合适的位置元素交换。
例:
原数据: 2 1 5 9 0 6 8 7 3
第1趟 : 1 2 5 9 0 6 8 7 3
第2趟 : 1 2 5 9 0 6 8 7 3
第3趟 : 1 2 5 9 0 6 8 7 3
第4趟 : 1 2 5 9 0 6 8 7 3
第5趟 : 0 1 2 5 9 6 8 7 3
第6趟 : 0 1 2 5 6 9 8 7 3
第7趟 : 0 1 2 5 6 8 9 7 3
第8趟 : 0 1 2 5 6 7 8 9 3
第9趟 : 0 1 2 3 5 6 7 8 9
伪代码:
for(int i=1;i<a.size();i++)
{
for(int j=i;j>0&&a[j]<a[j-1];j–)
{
swap(a,j,j-1);
}
}
对于升序插入排序,最好情况是数组已是升序排列,只需要n-1次比较,如果数组是降序排列,组需要对数组进行n*(n-1)/2次交换,n-1次比较,时间复杂度为O(n^2)。
堆排序(heap sort):
利用二叉排序树(完全二叉树)对数据排序,实际是堆这种数据结构,分为大定堆和小顶堆,对于大顶堆来说,父元素大于子元素,所以大顶堆的根节点是最大的,堆排序是依次将根节点与堆的最后一个元素交换,利用堆这个数据结构将数据排序。可以用数组表示堆。如根节点为i,则2i表示左子树,2i+1表示右子树。
堆排序的步骤:
1:构造大顶堆(或小顶堆)
2:将大顶堆堆顶元素与最后一个元素交换
3:重复1、2步
实现伪代码:
1:构造大顶堆:
void adjustheap(int []arr , int i,int lenght())
{
int temp = arr[i];
for(k=2i+1;k<lenght;k=2k+1)
{
if(k+1<lenght&&arr[k]<arr[k+1]) k++;
if(arr[k]>temp)
{
arr[i]=arr[k];
i=k;
}
else break;
}
arr[i]=temp;
}
2:将大顶堆堆顶元素与最后一个元素交换
void sort(int []arr)
{
for(int i=arr.lenght/2-1;i>=0;i–)
{
adjustheap(arr,i,arr.lenght)
}
for(int i=arr.lenght;i>0;i–)
{
swap(arr,0,j);
adjustheap(arr,0,j);
}
}


A1089 insert or merge 插入排序和归并排序
原题描述:
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?
输入描述:
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.
输出描述:
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 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.
输入例子:
10
3 1 2 8 7 5 9 4 6 0
1 2 3 7 8 5 9 4 6 0
输出例子:
Insertion Sort
1 2 3 5 7 8 9 4 6 0

原题大意:
描述了插入排序和归并排序的操作步骤,给出一个数组及数组中数字个数,
再给出其中排序过程中产生的一次数列要求列出是插入排序还是归并排序,并给出下一趟排序的序列。
参考代码:

#include <cstdio>
#include <algorithm>
#include <vector>
using namespace std;
//const int maxn=100;
//int a[maxn],b[maxn];//输入序列,比对序列
vector <int> arr,brr,arrori;
int n;
void swap (int a ,int b)
{
	int temp;
	temp=arr[b];
	arr[b]=arr[a];
	arr[a]=temp;
}
bool issame(vector<int>a,vector <int>b )
 {
	for(int i=0;i<n;i++)
	{
		if(a[i]!=b[i]) return false;
	}
	return true;
}
bool insertsort ()
{
	bool flag=false;
	for(int i=1;i<n&&flag==false;i++)
	{
		if(issame(arr,brr)&&i!=1) flag= true;
		for(int j=i;j>0&&arr[j]<arr[j-1];j--)
		{
			 swap(j,j-1);
		}  
	}
	return flag;

}
// 递归方法  
void merge(int l1 ,int r1,int l2,int r2)
{
	int i=l1,j=l2,index=0;
	vector <int> temp;
	while(i<=r1&&j<=r2)
	{
		if(arrori[i]<=arrori[j]) {temp.push_back(arrori[i++]);index++;}
		if(arrori[i]>arrori[j])  {temp.push_back(arrori[j++]);index++;}
	}
	while(i<=r1){temp.push_back(arrori[i++]);index++;}
	while(j<=r2){temp.push_back(arrori[j++]);index++;}
	for(int i=0;i<index;i++)
	{
		arrori[l1+i]=temp[i];
	}
}
//bool mergesort (int left,int right)
//{
//	if(right<left)
//	{
//		int mid=(left+right)/2;
//		mergesort(left,mid);
//		mergesort(mid+1,right);
//		merge(arr,left,mid,mid+1,right);
//	}
//
//}
//归并非递归
void mergesort()
{
	bool flag=false;
	for(int step=2;step/2<=n;step*=2)
	{
		if(step!=2&&issame(arrori,brr))
		{
			flag=true;
		}
		for(int i=0;i<n;i+=step)
		{
			int mid = i+step/2-1;
			if(mid+1<n)
			{
				merge(i,mid,mid+1,min(i+step-1,n-1));
			}
		}
		if(flag==true)
		{
			for(int k=0;k<arrori.size();k++)
		    {
				printf("%d",arrori[k]);
			    if(k<arrori.size()-1)printf(" ");
		    }	
			return;
		}
	}
}
int main()
{
	int temp;
	scanf("%d",&n);
	for(int i=0;i<n;i++)
	{
		scanf("%d",&temp);
		arr.push_back(temp);// insert sort
		arrori.push_back(temp);
	}
	for(int i=0;i<n;i++)
	{
		scanf("%d",&temp);
		brr.push_back(temp);
	}
	if(insertsort())
	{	
		printf("insert sort\n");
		for(int k=0;k<arr.size();k++)
		{
			printf("%d",arr[k]);
			if(k<arr.size()-1)printf(" ");
		}		
	}
	else
	{
		printf("merge sort\n");
		mergesort(); 
	}
}

A1098 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 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.
Sample Input 1:
10
3 1 2 8 7 5 9 4 6 0
1 2 3 7 8 5 9 4 6 0
Sample Output 1:
Insertion Sort
1 2 3 5 7 8 9 4 6 0
Sample Input 2:
10
3 1 2 8 7 5 9 4 6 0
6 4 5 1 0 3 2 7 8 9
Sample Output 2:
Heap Sort
5 4 3 1 0 2 6 7 8 9
原题大意:
与A0189类似,描述了插入排序和堆排序,给出一个数列和数列个数及进行到某步的排序序列,需要判断是插入排序还是堆排序,并输出下一步排序序列。
参考代码:

#include<cstdio>
#include<vector>
#include<algorithm>
using namespace std;
int n;
vector <int> heap,insert,result;//堆排序原输入队列、插入排序原输入队列、比较队列
void swap (vector <int> &arr,int a,int b)
{
	int temp=arr[b];
	arr[b]=arr[a];
	arr[a]=temp;
}
bool insertsort ()
{
	bool flag=false;
	for(int i=2;i<=n&&flag==false;i++)
	{
		if(i!=2&&insert==result)
		{
			flag=true;
		}
		for(int j=i;j>1&&insert[j]<insert[j-1];j--)
		{
			swap(insert,j,j-1);
		}
	}
	return flag;
}

void downadjust(int low,int high)
{
	int i=low,j=2*i;//i为欲调整结点,j 为i左孩子
	while(j<=high)
	{
		if(j+1<high&&heap[j+1]>heap[j])
		{
			j=j+1;//j始终表示i的孩子结点的最大值
		}
		if(heap[j]>heap[i])
		{
			swap(heap,i,j);
			i=j;
			j=2*i;
		}
		else 
			break; 
	}
}
void heapsort()
{
	bool flag=false;
	for(int i=n/2;i>=1;i--)
	{
		downadjust(i,n);//建堆
	}
    for(int i=n;i>1;i--)
	{
		if(i!=n&&heap==result)
		{
			flag=true;
		}
		swap(heap,i,1);
		downadjust(1,i-1);
		if(flag==true)
		{
			for(int j=1;j<=n;j++)
		   {
			    printf("%d",heap[j]);
			    if(j<n)printf(" ");
		   }
			return;
		}
	}
}
int main ()
{
	int temp;
	scanf("%d",&n);
	insert.push_back(n);
	heap.push_back(n);
	result.push_back(n);
	for(int i=1;i<=n;i++)
	{
		scanf("%d",&temp);
		insert.push_back(temp);
		heap.push_back(temp);
	}
	for(int i=1;i<=n;i++)
	{
		scanf("%d",&temp);
		result.push_back(temp);
	}
    if(insertsort())
	{
		printf("insert sort\n");
		for(int i=1;i<=n;i++)
		{
		
			printf("%d",insert[i]);
			if(i<n)printf(" ");
		}
	}
	else
	{
		printf("heap sort\n");
		heapsort();
	}
	return 0;
}

批量增加注释 快捷键 Ctrl+k Ctrl + c
批量取消注释 快捷键 Ctrl+k Ctrl + u

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值