排序算法汇总--冒泡,插入,归并,快速,堆,计数,基数,桶排序

sort.cpp

#include "stdafx.h"
#include <stdlib.h>

#define swap(x,y,t) t = x, x = y, y = t
/*****************************************************************************
 函 数 名  : BubbleSort
 功能描述  : 冒泡排序,每次将最小的数"冒"在最前面
 输入参数  : int *SortArray   
             int ArrayLength  
 输出参数  : 无
 返 回 值  : 
 调用函数  : 
 被调函数  : 
 
 修改历史      :
  1.日    期   : 2012年9月1日
    作    者   : 风痕
    修改内容   : 新生成函数

*****************************************************************************/
void BubbleSort(int *SortArray, int ArrayLength)
{
	int i, j;
	int temp;
	for(i = 0; i != ArrayLength; i++)
	{
		for(j = i+1; j != ArrayLength; j++)
		{
			if(SortArray[i] > SortArray[j])
			{
				swap(SortArray[i], SortArray[j], temp);	
			}
		}
	}
}

/*****************************************************************************
 函 数 名     : InsertSort
 功能描述  : 插入排序,从后往前依次插入元素
 输入参数  : int *SortArray   
             int ArrayLength  
 输出参数  : 无
 返 回 值  : 
 调用函数  : 
 被调函数  : 
 
 修改历史      :
  1.日    期   : 2012年9月1日
    作    者   : 风痕
    修改内容   : 新生成函数

*****************************************************************************/
void InsertSort(int SortArray[], int ArrayLength)
{
	int i, j;
	int key;

	for(j = 1; j  != ArrayLength; j++)
	{
		key = SortArray[j];
		i = j - 1;
		while(i != -1 && SortArray[i] > key)
		{
			SortArray[i+1]= SortArray[i];
			i--;
		}
		
		SortArray[i+1] = key;
	}
}

static void Merge(int SortArray[], int start, int middle, int end)
{
	int LeftLength = middle - start + 1;
	int RightLength = end - middle;

	// 创建临时数组保存已排序好的左右数组
	int *LeftArray = (int *)malloc(LeftLength * sizeof(int));
	for(int i = 0; i != LeftLength; ++i)
		LeftArray[i] = SortArray[start + i];
	int *RightArray = (int *)malloc(RightLength * sizeof(int));
	for(int i = 0; i != RightLength; ++i)
		RightArray[i] = SortArray[middle + i + 1];

	// 归并
	int i = 0;
	int j = 0;
	int k = start;
	while(i != LeftLength && j != RightLength)
	{
		if(LeftArray[i] <= RightArray[j])
			SortArray[k++] = LeftArray[i++];
		else
			SortArray[k++] = RightArray[j++];
	}

	while(i != LeftLength)
	{
		SortArray[k++] = LeftArray[i++];	
	}

	while(j != RightLength)
	{
		SortArray[k++] = RightArray[j++];
	}

	free(LeftArray);
	free(RightArray);
}

/*****************************************************************************
 函 数 名  : MergeSort
 功能描述  : 归并排序,分别对左右两边进行排序,然后合并,需要申请新的空间
 输入参数  : int SortArray[]  
             int start        
             int end          
 输出参数  : 无
 返 回 值  : 
 调用函数  : 
 被调函数  : 
 
 修改历史      :
  1.日    期   : 2012年9月1日
    作    者   : 风痕
    修改内容   : 新生成函数

*****************************************************************************/
void MergeSort(int SortArray[], int start, int end)
{
	if (start < end)
	{
		int middle = ( start + end ) / 2;
		MergeSort(SortArray, start, middle);
		MergeSort (SortArray, middle + 1, end);
		Merge(SortArray, start, middle, end);
	}
}

/*****************************************************************************
 函 数 名  : Partition
 功能描述  : 将数组划分为2组,左边的都比中间元素小,右边的都比中间元素大
 输入参数  : int SortArray[]  
             int start        
             int end          
 输出参数  : 无
 返 回 值  : static
 调用函数  : 
 被调函数  : 
 
 修改历史      :
  1.日    期   : 2012年9月1日
    作    者   : 风痕
    修改内容   : 新生成函数

*****************************************************************************/
static int Partition(int SortArray[], int start, int end)
{
	int middleValue = SortArray[end];
	int middleIndex = start - 1;
	int exchange;

	for(int j = start; j != end; ++j)
	{
		if (SortArray[j] <= middleValue)
		{
			middleIndex++;
			swap(SortArray[middleIndex], SortArray[j], exchange);
		}
		
	}
	swap(SortArray[middleIndex+1], SortArray[end], exchange);

	return middleIndex+1;
}

/*****************************************************************************
 函 数 名  : QuickSort
 功能描述  : 快速排序算法,和归并排序相比,快速排序不需要额外的空间
 输入参数  : int SortArray[]  
             int start        
             int end          
 输出参数  : 无
 返 回 值  : 
 调用函数  : 
 被调函数  : 
 
 修改历史      :
  1.日    期   : 2012年9月1日
    作    者   : 风痕
    修改内容   : 新生成函数

*****************************************************************************/
void QuickSort(int SortArray[], int start, int end)
{
	if(start < end)
	{
		int middle = Partition(SortArray, start, end);
		QuickSort(SortArray, start, middle-1);
		QuickSort(SortArray, middle+1, end);
	}
}

/*****************************************************************************
 函 数 名  : CountingSort
 功能描述  : 计数排序
 				计数排序的基本思想是对每一个输入元素x,确定
 				出不小于x的元素个数。
				只适用于正整数
 输入参数  : int SortArray[]  :待排序的数组
 		int SortedArray[]: 排序好的数组(输出参数)
             int ArrayLength :数组长度 
             int maxValue: 数组中元素的最大值     
 输出参数  : 无
 返 回 值  : 
 调用函数  : 
 被调函数  : 
 
 修改历史      :
  1.日    期   : 2012年9月1日
    作    者   : 风痕
    修改内容   : 新生成函数

*****************************************************************************/
void CountingSort(int SortArray[], int SortedArray[], int ArrayLength,int maxValue)
{
	int *CountArray  = (int *)malloc((maxValue+1) * sizeof(int));

	// 初始化
	for(int i = 0; i != maxValue+1; ++i)
		CountArray[i] = 0;

	// 计数
	for(int i = 0; i != ArrayLength; ++i)
		CountArray[(SortArray[i])] += 1;	// 等于的元素个数

	for(int i = 1; i != maxValue+1; ++i)
		CountArray[i] += CountArray[i-1];	// 小于或等于的个数

	// 重排
	/*
	从大到小,可保持稳定性,即具有相同值的元素
	在输出数组中的相对次序与他们在输入数组中的次序相同
	*/
	for(int i = ArrayLength-1; i != -1; --i)
	{
		SortedArray[(CountArray[(SortArray[i])]) - 1] = SortArray[i]; // -1:下标从0开始
		CountArray[(SortArray[i])] -= 1;
		
	}

	free(CountArray);
}

static void CountingSortForRadixSort(int SortArray[], int CmpArray[], int ArrayLength, int maxValue)
{
	int *CountArray  = (int *)malloc((maxValue+1) * sizeof(int));
	int *SortedArray = (int *)malloc(ArrayLength * sizeof(int));

	for(int i = 0; i != maxValue+1; ++i)
		CountArray[i] = 0;
	
	for(int i = 0; i != ArrayLength; ++i)
		CountArray[(CmpArray[i])]++;
	for(int i = 1; i != maxValue+1; ++i)
		CountArray[i] += CountArray[i-1];

	for(int i = ArrayLength-1; i != -1; --i)
	{
		SortedArray[(CountArray[CmpArray[i]])-1]= SortArray[i];
		CountArray[CmpArray[i]] -= 1;
	}

	for(int i = 0; i != ArrayLength; ++i)
		SortArray[i] = SortedArray[i];

	free(CountArray);
	free(SortedArray);
	
}

/*****************************************************************************
 函 数 名  : RadixSort
 功能描述  : 基数排序
 				利用计数排序算法,对数组从低向高位排序
 输入参数  : int SortArray[]  
             int ArrayLength  
 输出参数  : 无
 返 回 值  : 
 调用函数  : 
 被调函数  : 
 
 修改历史      :
  1.日    期   : 2012年9月1日
    作    者   : 风痕
    修改内容   : 新生成函数

*****************************************************************************/
void RadixSort(int SortArray[], int ArrayLength)
{
	int *RadixArray = (int *)malloc(ArrayLength * sizeof(int));
	int BaseNumber = 1;
	bool rsIsOk = false;

	while(false ==rsIsOk)
	{
		rsIsOk = true;
		BaseNumber *= 10;

		for(int i = 0; i != ArrayLength; ++i)
		{
			RadixArray[i] = SortArray[i] % BaseNumber;
			RadixArray[i] = RadixArray[i] / (BaseNumber / 10);
			if(RadixArray[i] > 0)
				rsIsOk = false;
		}
		if(true == rsIsOk)
			break;
		CountingSortForRadixSort(SortArray, RadixArray, ArrayLength, 9 );
	}

	free(RadixArray);
}

/*****************************************************************************
堆: 可以视为一棵完全二叉树,树的每一层都是填满的,除了最后一层

*****************************************************************************/
#define PARENT(x)	((x) >> 1)			// 节点x的父节点下标号
#define LEFT(x)		((x) << 1)			// 节点x的左子节点下标号
#define RIGHT(x)	(((x) << 1) + 1)	// 节点x的右子节点下标号

static void MaxHeapify(int SortArray[], int heap_size, int parent)
{
	int temp;
	int left, right, largest;

	left = LEFT(parent+1) - 1;
	right = RIGHT(parent+1) -1;

	if(left < heap_size && SortArray[left] > SortArray[parent])
		largest = left;
	else
		largest = parent;

	if(right < heap_size && SortArray[right] > SortArray[largest])
		largest = right;

	if(largest != parent)
	{
		swap(SortArray[largest], SortArray[parent], temp);

		MaxHeapify(SortArray, heap_size, largest);
	}
}

static void BuildMaxHeap(int SortArray[], int ArrayLength)
{
	int HeapSize = ArrayLength;

	for(int i = ArrayLength/2; i != -1; --i)
		MaxHeapify(SortArray,HeapSize,i);
}

/*****************************************************************************
 函 数 名  : HeapSort
 功能描述  : 堆排序算法
 				堆排序算法主要用于优先级队列
 输入参数  : int SortArray[]  
             int ArrayLength  
 输出参数  : 无
 返 回 值  : 
 调用函数  : 
 被调函数  : 
 
 修改历史      :
  1.日    期   : 2012年9月2日
    作    者   : 风痕
    修改内容   : 新生成函数

*****************************************************************************/
void HeapSort(int SortArray[], int ArrayLength)
{
	int temp;
	int HeapSize = ArrayLength;

	BuildMaxHeap(SortArray, ArrayLength);
	for(int i = ArrayLength-1; i !=0; --i)
	{
		swap(SortArray[0], SortArray[i], temp);
		HeapSize--;
		MaxHeapify(SortArray, HeapSize, 0);
	}
}

/*****************************************************************************
 函 数 名  : GetHeapMaximum
 功能描述  : 获取最大堆中的最大值
 输入参数  : int *MaxHeapArray  
 输出参数  : 无
 返 回 值  : 
 调用函数  : 
 被调函数  : 
 
 修改历史      :
  1.日    期   : 2012年9月2日
    作    者   : 风痕
    修改内容   : 新生成函数

*****************************************************************************/
int GetHeapMaximum(int *MaxHeapArray)
{
	return MaxHeapArray[0];	
}

/*****************************************************************************
 函 数 名  : ExtractHeapMaximum
 功能描述  : 去掉并返回队列中最大关键字元素
 输入参数  : int *MaxHeapArray  
             int HeapSize       
 输出参数  : 无
 返 回 值  : 
 调用函数  : 
 被调函数  : 
 
 修改历史      :
  1.日    期   : 2012年9月2日
    作    者   : 风痕
    修改内容   : 新生成函数

*****************************************************************************/
int ExtractHeapMaximum(int *MaxHeapArray, int HeapSize)
{
	if(0 == HeapSize)	// 空堆返回0
		return 0;	

	int maxValue = MaxHeapArray[0];
	
	// 重建堆
	MaxHeapArray[0] = MaxHeapArray[HeapSize-1];
	HeapSize--;
	MaxHeapify(MaxHeapArray, HeapSize, 0);

	return maxValue;
}

/*****************************************************************************
 函 数 名  : IncreaseHeapKey
 功能描述  : 将KeyIndex的值增加到Key
 输入参数  : int *MaxHeapArray  
             int KeyIndex       
             int Key            
 输出参数  : 无
 返 回 值  : 
 调用函数  : 
 被调函数  : 
 
 修改历史      :
  1.日    期   : 2012年9月2日
    作    者   : 风痕
    修改内容   : 新生成函数

*****************************************************************************/
bool IncreaseHeapKey(int *MaxHeapArray, int KeyIndex, int Key)
{
	int temp;
	
	if(Key < MaxHeapArray[KeyIndex])
		return false;

	while(KeyIndex != 0 && MaxHeapArray[PARENT(KeyIndex+1)]<<MaxHeapArray[KeyIndex])
	{
		swap(MaxHeapArray[PARENT(KeyIndex+1)],MaxHeapArray[KeyIndex], temp);
		KeyIndex = PARENT(KeyIndex+1);
	}

	if(0 == KeyIndex)
	{
		swap(MaxHeapArray[0], MaxHeapArray[1], temp);
	}

	return false;
}

/*****************************************************************************
 函 数 名  : MaxHeapInsert
 功能描述  : 向堆中插入元素KeyValue
 				注意,插入元素后堆长度增加,需在调用该函数后增加
 输入参数  : int HeapArray[]  
             int HeapSize     
             int KeyValue     
 输出参数  : 无
 返 回 值  : 
 调用函数  : 
 被调函数  : 
 
 修改历史      :
  1.日    期   : 2012年9月2日
    作    者   : 风痕
    修改内容   : 新生成函数

*****************************************************************************/
int MaxHeapInsert(int HeapArray[], int HeapSize, int KeyValue)
{
	HeapArray[HeapSize] = 0;

	return IncreaseHeapKey(HeapArray, HeapSize, KeyValue);
	
}
/*****************************************************************************
 函 数 名  : BucketSort
 功能描述  : 桶排序
 				将数组中的元素划分到n个大小相同的区间(桶)内,
 				然后对区间内的数使用插入排序,然后再将数组合并
 输入参数  : 无
 输出参数  : 无
 返 回 值  : 
 调用函数  : 
 被调函数  : 
 
 修改历史      :
  1.日    期   : 2012年9月1日
    作    者   : 风痕
    修改内容   : 新生成函数

*****************************************************************************/
void BucketSort()
{

}


sort.h

#ifndef _SORT_H
#define _SORT_H
void InsertSort(int *SortArray, int ArrayLength);
void BubbleSort(int *SortArray, int ArrayLength);
void MergeSort(int SortArray[], int start, int end);
void QuickSort(int SortArray[], int start, int end);
void CountingSort(int SortArray[], int SortedArray[], int ArrayLength,int maxValue);
void RadixSort(int SortArray[], int ArrayLength);
void HeapSort(int SortArray[], int ArrayLength);

int GetHeapMaximum(int *MaxHeapArray);
int ExtractHeapMaximum(int *MaxHeapArray, int HeapSize);
bool IncreaseHeapKey(int *MaxHeapArray, int KeyIndex, int Key);
int MaxHeapInsert(int HeapArray[], int HeapSize, int KeyValue);

#endif

sortTest.cpp

// SortTest.cpp : 定义控制台应用程序的入口点。
//

#include "stdafx.h"
#include <stdlib.h>
#include "sort.h"

int _tmain(int argc, _TCHAR* argv[])
{
	int SortArray1[] = {0,0,9,8,7,6,5,4,3,1,2};
	int SortArray2[] = {8,9,3,4,5,0,0,6,7,9,8}; 
	//MergeSort(SortArray1, 0, sizeof(SortArray1)/sizeof(int)-1);
	//MergeSort(SortArray2, 0, sizeof(SortArray2)/sizeof(int)-1);
	//QuickSort(SortArray1, 0, sizeof(SortArray1)/sizeof(int)-1);
	//QuickSort(SortArray2, 0, sizeof(SortArray2)/sizeof(int)-1);
	//int *SortedArray1 = (int *)malloc(sizeof(SortArray1)*sizeof(int));
	//int *SortedArray2 = (int *)malloc(sizeof(SortArray2)*sizeof(int));
	//CountingSort(SortArray1, SortedArray1, sizeof(SortArray1)/sizeof(int), 9);
	//CountingSort(SortArray2, SortedArray2, sizeof(SortArray2)/sizeof(int), 9);
	//RadixSort(SortArray1,sizeof(SortArray1)/sizeof(int));
	//RadixSort(SortArray2,sizeof(SortArray2)/sizeof(int));
	int SortArray3[] = {110,120,129,138,317,6,15,54,33,441,902};
	int SortArray4[] = {118,129,123,134,325,0,10,56,37,409,8}; 
	//RadixSort(SortArray3,sizeof(SortArray3)/sizeof(int));
	//RadixSort(SortArray4,sizeof(SortArray4)/sizeof(int));
	HeapSort(SortArray1,sizeof(SortArray1)/sizeof(int));
	HeapSort(SortArray2,sizeof(SortArray2)/sizeof(int));
	HeapSort(SortArray3,sizeof(SortArray3)/sizeof(int));
	HeapSort(SortArray4,sizeof(SortArray4)/sizeof(int));
	return 0;
}


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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值