3. 整数排序(排序-基本题)

本文详细介绍了在C++中实现的五种排序算法:选择排序、冒泡排序、堆排序、归并排序以及快速排序,并提供了每种算法的代码实现以及比较次数的计算。
摘要由CSDN通过智能技术生成

 武汉理工数据结构第二次实验第三题

五种排序

#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
//10 1
//38 356 98 -102 126 46 65 -9 100 0 21 2 90 8 18 12 78 16 189 23
void swap(int* p1, int* p2) {
	int temp = *p1;
	*p1 = *p2;
	*p2 = temp;
}
//打印函数
void print(int* arr, int length) {
	for (int i = 0; i < length; i++) {
		if (i == length - 1)printf("%d\n", arr[i]);
		else printf("%d ", arr[i]);
	}
}
int select_sort(int *arr,int length) {
	int count = 0;
	for (int i = 0; i < length; i++) {
		for (int j = i + 1; j < length; j++) {
			int mindex = i;
			count++;
			if (arr[mindex] >= arr[j]) {
				mindex = j;
			}
			int temp = arr[i];
			arr[i] = arr[mindex];
			arr[mindex] = temp;
		}
	}
	return count;
}
int bubble_sort(int* arr, int length) {
	int count = 0;
	int flag = 0;
	for (int i = 0; i < length; i++) {
		for (int j =1; j <length-i; j++) {
			count++;
			if (arr[j-1] >= arr[j]) {
				flag = 1;
			int temp = arr[j-1];
			arr[j-1] = arr[j];
			arr[j] = temp;
			}
		}
		if (flag) {
			flag = 0;
		}
		else break;
	}
	return count;

}
int heap_sort(int* arr, int length) {
	int count = 0;
	int child = length - 1;
	//建立大根堆,自下而上,向下调整
	for (int parent = (child - 1) / 2; parent >= 0; parent--) {
		//左孩子节点
		child = (parent + 1) * 2 - 1;
	//	//向下调整
	//	adjust(arr, parent, length, count);
	//}
		
	//向下调整临时的p
		int p = parent;
		while (child < length) {
		//如果右孩子存在且较大
			if (child + 1 < length && arr[child + 1] > arr[child]) child += 1;
			/*交换会破坏另一个的堆
			{
			swap(&arr[child + 1], &arr[child]);
		}*/
		//比较进行交换
			count++;
			if (arr[p] < arr[child])swap(&arr[p], &arr[child]);
			else break;
		p = child;
		child = (p + 1) * 2 - 1;
		}
	}
	//向下调整进行堆排序
	//n表示未排序的个数
	int n = length;
	while (n != 1) {
		//最大数放后面
		swap(&arr[0], &arr[n - 1]);
		//调整前n-1个数
		int parent = 0;
		int child = 1;
		while (child < n - 1) {
			count++;
			if (child + 1 < n - 1 && arr[child + 1] > arr[child]) child += 1;
			if (arr[parent] < arr[child])swap(&arr[parent], &arr[child]);
			else break;
			parent = child;
			child = (parent + 1) * 2 - 1;
		}
	n -= 1;
	}
	return count;
}
//merge二路归并
void merge(int arr[], int leftStar, int leftEnd, int rightStar, int rightEnd, int* pcount) {
	int temp[100];
	int star = leftStar;
	int end = rightEnd;
	//二分排序
	if(leftStar < leftEnd)merge(arr,leftStar, (leftStar + leftEnd) / 2, (leftStar+leftEnd)/ 2 + 1, leftEnd, pcount);
	if(rightStar < rightEnd)merge(arr,rightStar,( rightEnd+rightStar)/ 2, (rightEnd + rightStar) /2 + 1, rightEnd, pcount);
	int k = 0;//记录temp
	while (leftStar <= leftEnd && rightStar <= rightEnd) {
		(*pcount)++;
		if (arr[leftStar] < arr[rightStar]) {
			temp[k++] = arr[leftStar++];
		}
		else {
			temp[k++] = arr[rightStar++];
		}
	}
	while (leftStar <= leftEnd)temp[k++] = arr[leftStar++];
	while (rightStar <= rightEnd)temp[k++] = arr[rightStar++];
	k = 0;
	for (int i = star; i <=end; i++) {
		arr[i] = temp[k++];
	}
}
int merge_sort(int* arr, int length) {
	int count = 0;
	//左右数组,真的不想用malloc所以浪费一点空间无伤大雅
	merge(arr,0,length/2,length/2+1,length-1,&count);
	return count+1;
}
//quick,以第一个为基准
void quick(int* k, int left, int right, int* pNum) {
	int i, last;
	if (left < right) {

		last = left;

		for (i = left + 1; i <= right; i++) {
			(*pNum)++;
			if (k[i] < k[left]) {
			swap(&k[++last], &k[i]);
			}
		}


		swap(&k[left], &k[last]);
		quick(k, left, last - 1,pNum);
		quick(k, last + 1, right,pNum);

	}
}
int quick_sort(int* arr, int length) {
	int count = 0;
	quick(arr, 0, length - 1,&count);
	return count;
}

int main() {
	//长度,选择的排序算法
	int length, input;
	//记录比较次数
	int count = 0;
	scanf("%d%d", &length, &input);
	//输入初始数组
	int arr[100];
	for (int i = 0; i < length; i++) {
		scanf("%d", &arr[i]);
	}
	switch (input) {
	case 1:count=select_sort(arr, length); break;
	case 2:count=bubble_sort(arr, length); break;
	case 3:count=  heap_sort(arr, length); break;
	case 4:count= merge_sort(arr, length); break;
	case 5:count= quick_sort(arr, length); break;
	}
	print(arr, length);
	printf("%d", count);
	return 0;
}

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值