PAT 1098 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?

输入描述:
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 "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.

输入例子:
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


一:题目意思

    给出俩组数,判断是什么排序,然后输出这种排序的下一个状态。

二:解题思路

1.简谈插入排序

   从这个数列的第二个数开始,把这个数插入这个数之前的数列的合适的位置。

 实现代码:

#include<iostream>

using namespace std;
int a[10] = { 9, 8, 7, 6, 5, 4, 3, 2, 1,0 };
void insertion_sort(int n)
{
	for (int i = 1; i < n; i++)
	{
		int now = a[i];
		int j = i - 1;
		//插入合适的位置,则前面的依次后移
		while (a[j]>now&&j>=0)
		{
			a[j + 1] = a[j];
			j--;
		}
		//while 循环里面j--了,所以这里需要+1再赋值
		a[j+1] = now;
	}
}
int main()
{
	insertion_sort(10);
	for (int i = 0; i < 10; i++)
	{
		cout << a[i] << endl;
	}
	return 0;
	
}
插入排序中,前面的是按顺序从小到大或者从大到小,而后面与原始数据是一样的,所以可以用来判断是不是插入排序。

2.简谈堆排序

    (1)一个数组,从最后一个叶节点的根节点开始,让其根节点都大于他们的子节点,这样一个数列的最大堆就组好了,然后最上面那个根节点就是这个数列中最大的那个数

    (2)将上述所说的最上面那个最大的根节点与最后一个叶节点交换,堆的大小减一,这样再次把这个堆维护成最大堆,再依次把最上面的也就是现在这个堆的最大值与最后那个叶节点交换,堆的大小继续减一,循环上述过程,大小就排好了。

    (3)上面所讲的,交换最上面那个根节点和最后那个叶节点,这个大小减一后的堆怎么维护成最大堆呢?因为这个时候根节点的左右俩个树都是最大堆的,这是个很好的性质,意味着我们从根节点往下看,依次与比根节点大的最大的叶节点交换就好了。

代码是借鉴http://blog.csdn.net/xiaoxiaoxuewen/article/details/7570621/的

#include <iostream>
#include<algorithm>
using namespace std;

void HeapAdjust(int *a,int i,int size)  //调整堆 
{
    int lchild=2*i;       //i的左孩子节点序号 
    int rchild=2*i+1;     //i的右孩子节点序号 
    int max=i;            //临时变量 
    if(i<=size/2)          //如果i不是叶节点就不用进行调整 
    {
        if(lchild<=size&&a[lchild]>a[max])
        {
            max=lchild;
        }    
        if(rchild<=size&&a[rchild]>a[max])
        {
            max=rchild;
        }
        if(max!=i)
        {
            swap(a[i],a[max]);
            HeapAdjust(a,max,size);    //避免调整之后以max为父节点的子树不是堆 
        }
    }        
}

void BuildHeap(int *a,int size)    //建立堆 
{
    int i;
    for(i=size/2;i>=1;i--)    //非叶节点最大序号值为size/2 
    {
        HeapAdjust(a,i,size);    
    }    
} 

void HeapSort(int *a,int size)    //堆排序 
{
    int i;
    BuildHeap(a,size);
    for(i=size;i>=1;i--)
    {
        //cout<<a[1]<<" ";
        swap(a[1],a[i]);           //交换堆顶和最后一个元素,即每次将剩余元素中的最大者放到最后面 
          //BuildHeap(a,i-1);        //将余下元素重新建立为大顶堆 
          HeapAdjust(a,1,i-1);      //重新调整堆顶节点成为大顶堆
    }
} 

int main(int argc, char *argv[])
{
     //int a[]={0,16,20,3,11,17,8};
    int a[100];
    int size;
    while(scanf("%d",&size)==1&&size>0)
    {
        int i;
        for(i=1;i<=size;i++)
            cin>>a[i];
        HeapSort(a,size);
        for(i=1;i<=size;i++)
            cout<<a[i]<<" ";
        cout<<endl;
    }
    return 0;
}
3.这道题的解题思路

 1. 根据1中所提的方法判断是否为插入排序
 2. 理解了堆排序和插入排序计算下一步就简单了

三:解题代码

#include<iostream>
#include<vector>
#include<algorithm>
using namespace std;
int N;
vector<int> firstState, temState;
bool isInsertion=true;
void MAX_HEAPIFY(int i,int n)
{
	//维护最大堆,也可以用于建立最大堆
	int largest;
	int l = 2 * i+1;
	int r = 2 * i + 2;
	if (temState[l]>temState[i]&&l<=n)
	{
		largest = l;
	}
	else
	{
		largest = i;
	}
	if (r<=n&&temState[r]>temState[largest])
	{
		largest = r;
	}
	//当最大值不在根节点的时候,将其与根节点交换,并继续检查此节点是否满足最大堆的性质
	if (largest!=i)
	{
		int c = temState[largest];
		temState[largest] = temState[i];
		temState[i] = c;
		MAX_HEAPIFY(largest, n);
	}

}
int main()
{
	cin >> N;
	firstState.resize(N);
	temState.resize(N);
//输入
	for (int i = 0; i < N; i++)
	{
		cin >> firstState[i];
	}
	for (int i = 0; i < N; i++)
	{
		cin >> temState[i];
	}
//检查是否为插入排序
	int k=N-1;
	for (int i = N-1; i >= 0; i--)
	{
		if (firstState[i] != temState[i])
		{
			k = i;
			break;
		}
	}
	//cout << "k:" << k << endl;
	for (int i = 0; i < k; i++)
	{
		if (temState[i]>temState[i + 1])
		{
			isInsertion = false;
			break;
		}
	}
//计算下一步
	if (isInsertion)
	{
		cout << "Insertion Sort" << endl;
		if (k!=N-1)
			sort(temState.begin(), temState.begin() + k + 2);
	}
	else
	{
		cout << "Heap Sort" << endl;
		int last = N - 1;
		while (temState[last]>=temState[0]&&last>=0)
		{
			last--;
		}
		int c = temState[last];
		temState[last] = temState[0];
		temState[0] = c;
		MAX_HEAPIFY(0, last - 1);
	}
//输出
	for (int i = 0; i < N; i++)
	{
		cout << temState[i];
		if (i != N - 1)
			cout << " ";
		else
			cout << endl;
	}
	
}


四:总结 

   这道题代码还有问题,暂时木有发现,尴尬。。


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值