几种常见的排序算法实现

#include "stdafx.h"
#include <cmath>
#include <ctime>
#include <assert.h>
#include <iostream>
using namespace std;

// 交换值
template<typename T>
inline void swap_value(T *pLeft, T *pRight)
{
	T temp  = *pLeft;
	*pLeft  = *pRight;
	*pRight = temp;
}

// 比较函数
template<typename T>
inline int compare_value(T left, T right)
{
	if (left == right)
		return 0;
	else if (left < right)
		return -1;
	else
		return 1;
}

// 反转
template<typename T>
inline void revert_value(T arry[], int nCount)
{
	int i = 0;
	int nMid = nCount / 2;

	for (i = 0; i < nMid; i++)
	{
		swap_value(&arry[i], &arry[nCount - i - 1]);
	}
}

// 制造数据
void create_int_value(int *pArray, int nCount, int nRand)
{
	int i = 0;

	assert(NULL != pArray);

	if (NULL == pArray)
		return ;

	srand(nRand);

	for (i = 0; i < nCount; i++)
	{
		pArray[i] = rand() % 100 + 1;
	}
}

// 输出
template<typename T>
void output_value(T arry[], int nCount)
{
	int i = 0;
	cout << "----------开始输出-----------" << endl;
	for (i = 0; i < nCount; i++)
	{
		cout << arry[i] << " ";
	}
	cout << endl;
	cout << "----------输出结束-----------" << endl;
}

// 二叉树输出
template<typename T>
void output_tree(T arry[], int nCount)
{
	int i = 0, j = 0;

	// 层数
	int nLayer = 0;
	while ((pow(2.0, nLayer) - 1) < nCount)
	{
		nLayer++;
	}

	cout << "----------开始输出-----------" << endl;
	for (i = 0; i < nLayer; i++)
	{
		int nSpace = nLayer - i;
		while (nSpace-- >= 0)
		{
			cout << "   ";
		}

		int nBegin = (int)pow(2.0, i) - 1;
		int nEnd   = nBegin + (int)pow(2.0, i);

		for (j = nBegin; j < nEnd; j++)
		{
			if (j >= nCount)
				break;

			cout << arry[j] << "   ";
		}

		cout << endl;		
	}
	cout << "----------输出结束-----------" << endl;
}

// 冒泡排序
template <typename T>
void sort_bubble(T arry[], int nCount)
{
	bool isOk = true;
	for (int i = nCount - 1; i > 0; --i)
	{
		isOk = true;
		for (int j = 0; j < i; ++j)
		{
			if (compare_value(arry[j], arry[j + 1]) > 0)
			{
				swap_value(&arry[j], &arry[j + 1]);
				isOk = false;
			}
		}

		if (isOk)
			break;
	}
}

// 选择排序
template<typename T>
void sort_select(T arry[], int nCount)
{
	int nMinIdx = 0;
	for (int i = 0; i < nCount - 1; ++i)
	{
		nMinIdx = i;
		for (int j = i + 1; j < nCount; ++j)
		{
			if (compare_value(arry[j], arry[nMinIdx]) < 0)
			{
				nMinIdx = j;
			}
		}

		if (nMinIdx != i)
		{
			swap_value(&arry[nMinIdx], &arry[i]);
		}
	}
}

// 插入排序
template<typename T>
void sort_insert(T arry[], int nCount)
{
	T temp;
	int j = 0;
	for (int i = 1; i < nCount; ++i)
	{
		temp = arry[i];
		for (j = i - 1; j >= 0; --j)
		{
			if (compare_value(arry[j], temp) > 0)
				arry[j + 1] = arry[j];
			else
				break;
		}

		if (j != i - 1)
			arry[j + 1] = temp;
	}
}

// 快速排序
template<typename T>
int quickPartition(T arry[], int nBegin, int nEnd)
{
	int nLeftNum = 0;
	for (int i = nBegin + 1; i < nEnd; ++i)
	{
		if (compare_value(arry[i], arry[nBegin]) < 0)
		{
			++nLeftNum;
			swap_value(&arry[nBegin + nLeftNum], &arry[i]);
		}
	}

	if (nLeftNum > 0)
		swap_value(&arry[nBegin], &arry[nBegin + nLeftNum]);
	return (nBegin + nLeftNum);
}

template<typename T>
void sort_qksort(T arry[], int nBegin, int nEnd)
{
	if (nBegin < nEnd)
	{
		int nPartIdx = quickPartition(arry, nBegin, nEnd);
		sort_qksort(arry, nBegin, nPartIdx);
		sort_qksort(arry, nPartIdx + 1, nEnd);
	}
}

// 堆排序
template<typename T>
void build_heap(T arry[], int nCount)
{
	for (int i = (nCount - 1) / 2; i >= 0; --i)
	{
		adjust_heap(arry, i, nCount - 1);
	}
}

template<typename T>
void adjust_heap(T arry[], int nCurRoot, int nMaxIndex)
{
	// 叶节点不用调整
	if (nCurRoot > (nMaxIndex - 1) / 2)
		return;

	int nLChild = nCurRoot * 2 + 1;
	int nRChild = nLChild + 1;
	int nMax = nCurRoot;
	if (nLChild <= nMaxIndex && compare_value(arry[nLChild], arry[nMax]) > 0)
		nMax = nLChild;
	if (nRChild <= nMaxIndex && compare_value(arry[nRChild], arry[nMax]) > 0)
		nMax = nRChild;

	if (nMax != nCurRoot)
	{
		swap_value(&arry[nMax], &arry[nCurRoot]);
		adjust_heap(arry, nMax, nMaxIndex);
	}
}

template<typename T>
void sort_heap(T arry[], int nCount)
{
	build_heap(arry, nCount);

	for (int i = nCount - 1; i >= 1; --i)
	{
		swap_value(&arry[0], &arry[i]);
		adjust_heap(arry, 0, i - 1);
	}
}

int _tmain(int argc, _TCHAR* argv[])
{
	int nCount  = 15;

	// 分配空间
	int *pArray = new int [nCount];
	memset(pArray, 0, sizeof(int) * nCount);

	// 制造数据
	create_int_value(pArray, nCount, (int)time(NULL));

	 冒泡排序
	//output_value(pArray, nCount);
	//sort_bubble(pArray, nCount);
	//output_value(pArray, nCount);

	 选择排序
	//output_value(pArray, nCount);
	//sort_select(pArray, nCount);
	//output_value(pArray, nCount);

	 插入排序
	//output_value(pArray, nCount);
	//sort_insert(pArray, nCount);
	//revert_value(pArray, nCount);
	//output_value(pArray, nCount);

	 快速排序
	//output_value(pArray, nCount);
	//sort_qksort(pArray, 0, nCount);
	//output_value(pArray, nCount);

	// 堆排序
	output_value(pArray, nCount);
	sort_heap(pArray, nCount);
	output_value(pArray, nCount);

	// 释放
	delete []pArray;
	pArray = NULL;

	system("pause");

	return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值