1089 Insert or Merge (25分) && 1098 Insertion or Heap Sort

1.推荐使用vector 传引用数组不用给定大小范围....我用的int数组,麻烦还有限制,但是目前懒得改

2.引用这个还挺好用的

3.插入排序的话 前面有序,后面和原数组内容一致 我只是模拟了下插入第i个元素的最终排序  没有实现从头到尾排序的

4.归并排序注意是二路归并  直接二分往下模拟会有问题代码注释中有说明 直接sort  2的i次方的跨度往后排序  但是我没写这个

5.堆排序 最终求从小到大排序需要建立大根堆  然后逐步调整

6.由于这两个个一样  所以两个题合并了  merge直接用归并模拟有问题,注意这个问题

#include 

#include 

using namespace std;

int n, a[100], b[100], i, j, ans[100], len=1;

bool flag=false;//merge结束条件
void InsertSort(int (&a)[100], int n) {
	int tmp = a[n], j;
	for(j=n-1; j>=0; j--) {
		if(a[j] > tmp) {
			a[j+1] = a[j];

		} else break;
	}
	a[j+1] = tmp;
}
//下标从0开始存  一般建议从1存 A[0]用来放置标兵,左右子节点计算也方便(*/2即左 不用+1 -1之类的)..但是我现在懒得改
void AdjustHeap(int (&a)[100], int l, int r) {
	int tmp = a[l];//类似于快排中的pivot 插入排序等标兵角色

	for(int i=2*l+1; i tmp) { //二者最大的子节点大于父节点
			a[l] = a[i];//父节点有子节点赋值
			l = i;//继续向下
		} else break;
	}
	a[l] = tmp;
}
void HeapSort(int (&a)[100], int l, int r) {
	//构建大根堆
	for(int i=r/2-1; i>=0; i++) {
		AdjustHeap(a, i, r);
	}
	//排序   大的逐步交换到最后  相当于小-》大排序
	for(int i=r-1; i>0; i--) {
		swap(a[0], a[i]);
		AdjustHeap(a, 0, i); //i之后的都排好了
	}
}
void Merge(int (&a)[100], int l, int r, int m) {
	int i=l, temp[100];
	int j=m+1;
	int k=l;
	int sum;//求逆序对数
	while(i<=m&&j<=r) {
		if(a[i]>a[j]) {
			sum+=m-i+1;
			temp[k++]=a[j++];
		} else {
			temp[k++]=a[i++];
		}
	}

	while(i<=m) {
		temp[k++]=a[i++];
	}
	while(j<=r) {
		temp[k++]=a[j++];
	}
	for(i=l; i<=r; i++) {
		a[i]=temp[i];
		//	cout << a[i] << " ";
	}
	//cout << endl;

}
void MergeSort(int (&a)[100], int l, int r) {
	int i;
	cout << l << " " << r << endl;
	if(l < r) {
		int mid = (l+r)/2;

		MergeSort(a, l, mid);
		MergeSort(a, mid+1, r);
		Merge(a, l, r, mid);

		for(i=0; i> n;

	for (int i = 0; i < n; i++)

		cin >> a[i];

	for (int i = 0; i < n; i++)

		cin >> b[i];

	i=0;

	while(i0 && b[idx] >= b[0]) idx--;
		swap(b[0], b[idx]);
		//	downAdjust(b, 0, idx);
		AdjustHeap(b, 0, idx);
	}

	for (j = 0; j < n; j++) {
		if (j != 0) printf(" ");
		printf("%d", b[j]);
	}

	return 0;

}

 

你可能感兴趣的:(PAT,堆排序,排序)