C++实现经典排序算法

本文展示了C++实现的冒泡排序、选择排序、插入排序、希尔排序、快速排序、归并排序和堆排序,并通过测试案例对10000个随机数进行排序,记录了每种排序算法的运行时间。实验结果揭示了不同排序算法在效率上的差异。
摘要由CSDN通过智能技术生成

C++实现经典排序算法

/**---------------------------------------
* 文件名称: CSorter.h
* 功能描述: 排序算法的实现
* 创建标识: xad 2022/2/9
*
* 修改标识:
* 修改描述:
------------------------------------------**/

#ifndef		CSORTER_SORTER_H
#define		CSORTER_SORTER_H

class CSorter
{
public:
	/**
	*  @brief    冒泡排序
	*
	*  @param    int arr[]
	*  @param    int length
	*  @return   void
	*/
	static void bubbleSort(int arr[], int length);

	/**
	*  @brief    选择排序
	*
	*  @param    int arr[]
	*  @param    int length
	*  @return   void
	*/
	static void selectSort(int arr[], int length);

	/**
	*  @brief    插入排序
	*
	*  @param    int arr[]
	*  @param    int length
	*  @return   void
	*/
	static void insertSort(int arr[], int length);

	/**
	*  @brief    希尔排序
	*
	*  @param    int arr[]
	*  @param    int length
	*  @return   void
	*/
	static void shellSort(int arr[], int length);

	/**
	*  @brief    快速排序
	*
	*  @param    int arr[]
	*  @param    int start
	*  @param    int end
	*  @return   void
	*/
	static void quickSort(int arr[], int start, int end);

	/**
	*  @brief    归并排序
	*
	*  @param    int arr[]
	*  @param    int start
	*  @param    int end
	*  @param    int temp[]
	*  @return   void
	*/
	static void mergeSort(int arr[], int start, int end, int temp[]);

	/**
	*  @brief    堆排序
	*
	*  @param    int arr[]
	*  @param    int length
	*  @return   void
	*/
	static void heapSort(int arr[], int length);
protected:
private:
	static void _swap(int* a, int* b);

	// 快速排序使用
	static int _partition(int arr[], int start, int end);

	// 归并排序使用
	static void _merge(int arr[], int start, int end, int mid, int temp[]);

	// 堆排序使用
	static void _adjust(int arr[], int index, int length);
};

#endif
#include "CSorter.h"

void CSorter::bubbleSort(int arr[], int length)
{
	for (int i = 0; i < length;i++)
	{
		bool bFlag = false;
		for (int j = length - 1; j > i;j--)
		{
			if (arr[j] < arr[j -1])
			{
				bFlag = true;
				_swap(&arr[j], &arr[j - 1]);
			}
		}

		if (!bFlag)
		{
			break;
		}

	}
}

void CSorter::selectSort(int arr[], int length)
{
	//从小到大排序
	// 选择排序通过减少交换次数来提升效率
	for (int i = 0; i < length; ++i)
	{
		int nMinIndex = i;
		for (int j = i; j < length; ++j)
		{
			if (arr[j] < arr[nMinIndex])
			{
				nMinIndex = j;
			}
		}

		_swap(&arr[i], &arr[nMinIndex]);
	}

}

// 插入排序
// 最好情况:原始序列正序,需要比较(n-1)次,移动2(n-1)次,时间复杂度O(n)
// 最坏情况:原始序列倒序,需要比较(n-1)(n+2)/2次(2~n求和值),移动(n-1)(n+4)/2次 ((2+1)~(n+1)求和值)
void CSorter::insertSort(int arr[], int length)
{
	for (int i = 1; i < length; ++i)
	{
		if (arr[i] < arr[i - 1])
		{
			//找到合适的插入位置
			int temp = arr[i]; 
			int j;

			for (j = i - 1; j >= 0 && arr[j] > temp; --j)
			{
				arr[j + 1] = arr[j];
			}
			arr[j + 1] = temp;
		}

	}
}

void CSorter::shellSort(int arr[], int length)
{
	int increase = length;
	do {
		increase = increase / 3 + 1;
		for (int i = 0; i < increase; ++i)
		{
			for (int j = i + increase; j < length; j += increase)
			{
				if (arr[j] < arr[j - increase]) 
				{
					int temp = arr[j];
					int k;
					for (k = j - increase; k >= 0 && arr[k] > temp; k -= increase)
					{
						arr[k + increase] = arr[k];
					}
					arr[k + increase] = temp;
				}
			}
		}
	} while (increase > 1);
}

void CSorter::quickSort(int arr[], int start, int end)
{
	if (start >= end) {
		return;
	}

	int pivotPos = _partition(arr, start, end); //将大的数值排在pivotPos右边,将小的数值排在左边
	quickSort(arr, start, pivotPos - 1);
	quickSort(arr, pivotPos + 1, end);
}

void CSorter::mergeSort(int arr[], int start, int end, int temp[])
{
	if (start >= end) {
		return;
	}
	int mid = start + (end - start) / 2;
	mergeSort(arr, start, mid, temp);
	mergeSort(arr, mid + 1, end, temp);
	_merge(arr, start, end, mid, temp);

}

void CSorter::heapSort(int arr[], int length)
{
	// 初始化堆,大顶堆
	for (int i = length / 2 - 1; i >= 0; --i) {
		_adjust(arr, i, length);
	}
	// 交换堆顶元素和最后一个元素
	for (int i = length - 1; i >= 0; --i) {
		_swap(&arr[0], &arr[i]);
		_adjust(arr, 0, i);
	}

}

void CSorter::_swap(int * a, int * b)
{
	int tmp = *a;
	*a = *b;
	*b = tmp;
}

int CSorter::_partition(int arr[], int start, int end)
{
	int nPosValue = arr[start];
	int nPosIndex = start;
	int ni = start, nj = end;

	while (ni < nj)
	{
		while (arr[nj] > nPosValue)
		{
			nj--;
		}
		while (arr[ni] <= nPosValue)
		{
			ni++;
		}
		if (ni >= nj)
		{
			break;
		}
		_swap(&arr[ni], &arr[nj]);
	}

	arr[nPosIndex] = arr[nj];
	arr[nj] = nPosValue;
	return nj;

}

void CSorter::_merge(int arr[], int start, int end, int mid, int temp[])
{
	int i_start = start;
	int j_start = mid + 1;
	int i_end = mid;
	int j_end = end;
	int pos = start;
	while (i_start <= i_end && j_start <= j_end) {
		if (arr[i_start] < arr[j_start]) {
			temp[pos] = arr[i_start];
			i_start++;
			pos++;
		}
		else {
			temp[pos] = arr[j_start];
			j_start++;
			pos++;
		}
	}
	while (i_start <= i_end) {
		temp[pos] = arr[i_start];
		i_start++;
		pos++;
	}
	while (j_start <= j_end) {
		temp[pos] = arr[j_start];
		j_start++;
		pos++;
	}
	for (int i = start; i <= end; ++i) {
		arr[i] = temp[i];
	}

}

void CSorter::_adjust(int arr[], int index, int length)
{
	while ((2 * index + 1) < length) {
		int lchild = 2 * index + 1;
		int rchild = lchild + 1;
		int maxChild = (rchild < length && arr[rchild] > arr[lchild]) ? rchild : lchild;
		if (arr[index] >= arr[maxChild]) break;
		_swap(&arr[index], &arr[maxChild]);
		index = maxChild;
	}

}

/**---------------------------------------
* 文件名称: TestCSorter.cpp
* 功能描述: 测试排序算法
* 创建标识: xad 2022/2/9
*
* 修改标识:
* 修改描述:
------------------------------------------**/

#include<iostream>
#include <string>
#include "CSorter.h"
#include <sys/timeb.h>
#include <time.h>

const int MAX_SIZE = 10000;

void printArray(int arr[], int length);
long getSystemTime(void);
void test_07(void);

int main()
{
	test_07();
	system("pause");
	return 0;
}

void test_07(void)
{
	int* arr = new int[MAX_SIZE];
	std::srand((unsigned int)time(nullptr));
	for (int i = 0; i < MAX_SIZE; ++i) {
		arr[i] = std::rand() % MAX_SIZE;
	}
	std::cout << "排序前:" << std::endl;
	//    printArray(arr, MAX_SIZE);
	long t_start = getSystemTime();
	CSorter::bubbleSort(arr, MAX_SIZE);
	long t_end = getSystemTime();
	std::cout << "冒泡排序" << MAX_SIZE << "个元素,所需时间:" << (t_end - t_start) << std::endl;
	std::cout << "排序后:" << std::endl;
	//    printArray(arr, MAX_SIZE);


	for (int i = 0; i < MAX_SIZE; ++i) {
		arr[i] = std::rand() % MAX_SIZE;
	}

	std::cout << "排序前:" << std::endl;
	//    printArray(arr, MAX_SIZE);
	t_start = getSystemTime();
	CSorter::selectSort(arr, MAX_SIZE);
	t_end = getSystemTime();
	std::cout << "选择排序" << MAX_SIZE << "个元素,所需时间:" << (t_end - t_start) << std::endl;
	std::cout << "排序后:" << std::endl;
	//    printArray(arr, MAX_SIZE);

	for (int i = 0; i < MAX_SIZE; ++i) {
		arr[i] = std::rand() % MAX_SIZE;
	}
	std::cout << "排序前:" << std::endl;
	//    printArray(arr, MAX_SIZE);
	t_start = getSystemTime();
	CSorter::insertSort(arr, MAX_SIZE);
	t_end = getSystemTime();
	std::cout << "插入排序" << MAX_SIZE << "个元素,所需时间:" << (t_end - t_start) << std::endl;
	std::cout << "排序后:" << std::endl;
	//    printArray(arr, MAX_SIZE);

	for (int i = 0; i < MAX_SIZE; ++i) {
		arr[i] = std::rand() % MAX_SIZE;
	}
	std::cout << "排序前:" << std::endl;
	//    printArray(arr, MAX_SIZE);
	t_start = getSystemTime();
	CSorter::shellSort(arr, MAX_SIZE);
	t_end = getSystemTime();
	std::cout << "希尔排序" << MAX_SIZE << "个元素,所需时间:" << (t_end - t_start) << std::endl;
	std::cout << "排序后:" << std::endl;
	//    printArray(arr, MAX_SIZE);

	for (int i = 0; i < MAX_SIZE; ++i) {
		arr[i] = std::rand() % MAX_SIZE;
	}
	std::cout << "排序前:" << std::endl;
	//    printArray(arr, MAX_SIZE);
	t_start = getSystemTime();
	CSorter::quickSort(arr, 0, MAX_SIZE - 1);
	t_end = getSystemTime();
	std::cout << "快速排序" << MAX_SIZE << "个元素,所需时间:" << (t_end - t_start) << std::endl;
	std::cout << "排序后:" << std::endl;
	//    printArray(arr, MAX_SIZE);

	for (int i = 0; i < MAX_SIZE; ++i) {
		arr[i] = std::rand() % MAX_SIZE;
	}
	int* temp = new int[MAX_SIZE];
	std::cout << "排序前:" << std::endl;
	//    printArray(arr, MAX_SIZE);
	t_start = getSystemTime();
	CSorter::mergeSort(arr, 0, MAX_SIZE - 1, temp);
	t_end = getSystemTime();
	std::cout << "归并排序" << MAX_SIZE << "个元素,所需时间:" << (t_end - t_start) << std::endl;
	std::cout << "排序后:" << std::endl;
	//    printArray(arr, MAX_SIZE);

	for (int i = 0; i < MAX_SIZE; ++i) {
		arr[i] = std::rand() % MAX_SIZE;
	}
	std::cout << "排序前:" << std::endl;
	//    printArray(arr, MAX_SIZE);
	t_start = getSystemTime();
	CSorter::heapSort(arr, MAX_SIZE);
	t_end = getSystemTime();
	std::cout << "堆排序" << MAX_SIZE << "个元素,所需时间:" << (t_end - t_start) << std::endl;
	std::cout << "排序后:" << std::endl;
	//    printArray(arr, MAX_SIZE);

	delete[] temp;
	delete[] arr;
}

long getSystemTime()
{
	struct timeb tb {};
	ftime(&tb);
	return tb.time * 1000 + tb.millitm;
}

void printArray(int arr[], int length) 
{
	for (int i = 0; i < length; ++i) {
		std::cout << arr[i] << " ";
	}
	std::cout << std::endl;
}

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值