1.经典排序算法 – 插入排序Insertion sort
插入排序就是每一步都将一个待排数据按其大小插入到已经排序的数据中的适当位置,直到全部插入完毕。
插入排序方法分直接插入排序和折半插入排序两种,这里只介绍直接插入排序,折半插入排序留到“查找”内容中进行。
图1演示了对4个元素进行直接插入排序的过程,共需要(a),(b),(c)三次插入。
#include "stdafx.h"
#include<iostream>
using namespace std;
void insertion_sort(int a[],int n)
{
int i,j;
int key;
for(i=1;i<n;i++)
{
key = a[i];
for(j=i-1;j>=0&&key<a[j];j--)
a[j+1] = a[j];
a[j+1] = key;
}
}
void print(int *a,int n)
{
for(int i = 0;i<n;i++)
std::cout<< *(a+i)<<" ";
std::cout<<endl;
}
int _tmain(int argc, _TCHAR* argv[])
{
int a[] = {4,3,1,2};
print(a,4);
insertion_sort(a,4);
print(a,4);
return 0;
}
</pre><p>插入排序的递归算法</p><pre name="code" class="cpp">void insert(int *a,int n) //把数组a的第n个数插入前n-1个数中,注意前n-1个数已经是排好序的了
{
int i= 0,key = *(a+n-1);
for( i = n-2;i>=0&&*(a+i)>key;i--)
*(a+i+1) = *(a+i);
*(a+i+1) = key;
}
void recoursion_insert_sort(int a[],int n) //递归插入,跟求阶乘的思想一样,前n-1个排好序的数组,是建立在前n-2个排好序的数组的基础上插出来的
{
if(n>0)
{
recoursion_insert_sort(a,n-1);
insert(a,n);
}
}
归并排序
// merge_sort.cpp : 定义控制台应用程序的入口点。
//
#include "stdafx.h"
#include<malloc.h>
#include<iostream>
using namespace std;
// 将大化小,将复杂归为简单。
// 归并排序:
// 1.将整个集合一分为二
// 2.左侧进行排序。
// 3.右侧进行排序。
// 4.左侧和右侧统一进行排序调整。
/********************************************************
*函数名称:Merge
*参数说明:pDataArray 无序数组;
* int *pTempArray 临时存储合并后的序列
* bIndex 需要合并的序列1的起始位置
* mIndex 需要合并的序列1的结束位置
并且作为序列2的起始位置
* eIndex 需要合并的序列2的结束位置
*说明: 将数组中连续的两个子序列合并为一个有序序列
*********************************************************/
// 方法一
void merge(int* pDataArray, int bIndex, int mIndex, int eIndex) //[bIndex,mIndex] , (mIndex,eIndex]
{
int mLength = eIndex - bIndex + 1; //合并后的序列长度
int *pTempArray = (int *)malloc(sizeof(int)*mLength);
int i = 0; //记录合并后序列插入数据的偏移
int j = bIndex; //记录子序列1插入数据的偏移
int k = mIndex+1; //记录子序列2掺入数据的偏移
while (j <= mIndex && k <= eIndex)
{
if (pDataArray[j] <= pDataArray[k])
{
pTempArray[i++] = pDataArray[j];
j++;
}
else
{
pTempArray[i++] = pDataArray[k];
k++;
}
}
if (j > mIndex) //说明序列1已经插入完毕
while (k <= eIndex)
pTempArray[i++] = pDataArray[k++];
else //说明序列2已经插入完毕
while (j <= mIndex)
pTempArray[i++] = pDataArray[j++];
for (i = 0; i < mLength; i++) //将合并后序列重新放入pDataArray
pDataArray[bIndex + i] = pTempArray[i];
free(pTempArray);
}
/********************************************************
* 归并排序pDataArray 中 p到r中的元素
*********************************************************/
void merge_sort(int* pDataArray, int p,int r)
{
if(p<r)
{
int q = (p+r)/2;
merge_sort(pDataArray,p,q);
merge_sort(pDataArray,q+1,r);
merge(pDataArray,p,q,r);
}
}
void print(int *a,int n)
{
for(int i = 0;i<n;i++)
std::cout<< *(a+i)<<" ";
std::cout<<endl;
}
int _tmain(int argc, _TCHAR* argv[])
{
void Merge(int* pDataArray, int *pTempArray, int bIndex, int mIndex, int eIndex) ;
void BottomUpMergeSort(int* pDataArray, int iDataNum) ;
int a[] = { 63,95,84,46,18,24,27,31,46};
print(a,9);
merge_sort(a,0,8);
print(a,9);
return 0;
}
// 方法二
void Merge(int* pDataArray, int *pTempArray, int bIndex, int mIndex, int eIndex)
{
int mLength = eIndex - bIndex; //合并后的序列长度
int i = 0; //记录合并后序列插入数据的偏移
int j = bIndex; //记录子序列1插入数据的偏移
int k = mIndex; //记录子序列2掺入数据的偏移
while (j < mIndex && k < eIndex)
{
if (pDataArray[j] <= pDataArray[k])
{
pTempArray[i++] = pDataArray[j];
j++;
}
else
{
pTempArray[i++] = pDataArray[k];
k++;
}
}
if (j == mIndex) //说明序列1已经插入完毕
while (k < eIndex)
pTempArray[i++] = pDataArray[k++];
else //说明序列2已经插入完毕
while (j < mIndex)
pTempArray[i++] = pDataArray[j++];
for (i = 0; i < mLength; i++) //将合并后序列重新放入pDataArray
pDataArray[bIndex + i] = pTempArray[i];
}
void BottomUpMergeSort(int* pDataArray, int iDataNum)
{
int *pTempArray = (int *)malloc(sizeof(int) * iDataNum); //临时存放合并后的序列
int length = 1; //初始有序子序列长度为1
while (length < iDataNum)
{
int i = 0;
for (; i + 2*length < iDataNum; i += 2*length)
Merge(pDataArray, pTempArray, i, i + length, i + 2*length);
if (i + length < iDataNum)
Merge(pDataArray, pTempArray, i, i + length, iDataNum);
length *= 2; //有序子序列长度*2
}
free(pTempArray);
}