设待排序数组为a[n]
(1)直接插入排序
思想:将数组a[n]分为一个有序区a[1]...a[i] 和一个无序区a[i+1]....a[n-1],每一次将a[i+1]插入有序区,形成一个新的有序区,如此反复。
代码如下:
#include "stdafx.h"
#include <iostream>
using namespace std;
typedef int type;
//直接插入排序
void InsertSort(type a[],int n)
{
int i,j;
type temp;
for(i=1;i<n;i++)
{
temp=a[i];
for(j=i;j>0 && a[j-1]>temp;j--)
{
a[j]=a[j-1];
}
a[j]=temp;
}
}
(2)直接选择排序
思想: 将数组a[n]分为一个有序区a[1]...a[i] 和一个无序区a[i+1]....a[n-1],每次将无序区最大或最小的值找出,并置于有序区尾部。
代码如下:
//直接选择排序
void ChooseSort(type a[],int n)
{
int i,j;
type temp;
for(i=0;i<n;i++)
{
temp=a[i];
for(j=i+1;j<n;j++)
{
if(a[j]<temp)
{
a[i]=a[j];
a[j]=temp;
}
}
}
}
(3)冒泡排序
思想:数组a[0]...a[n-1]垂直排列,从数组尾部开始向数组首部开始扫描,a[i]与a[i-1]相比较, 满足条件(大或小),两两交换。
代码如下:
//冒泡排序
void BubbleSort(type a[],int n)
{
int i,j;
type temp;
for(i=1;i<n;i++)
{
for(j=n-1;j>=i;j--)
{
if(a[j-1]<a[j])
{
temp=a[j];
a[j]=a[j-1];
a[j-1]=temp;
}
}
}
(4)快速排序
思想: 在a[0]...a[n-1]中选取一个记录(例如a[i])将无序区分为左右两个子区间,使得左区间a[0]...a[i-1]的值都小于等于a[i],右区间a[i+1]...a[n-1]的值都大于等于a[i]的值,而a[i]则位于正确的位置,不需要参加后续排序。通过递归调用分别对左右两个子区间进行快速排序。
代码如下:
//快速排序
void QuickSort(type a[],int left, int right)
{
int i,j;
if(left>right)
return;
i=left;
j=right;
type temp=a[i];
while(i!=j)
{
while((a[j]>temp)&&(j>i))
j--;
if(j>i)
{
a[i++]=a[j];
}
while((a[i]<temp)&&(i<j))
i++;
if(i<j)
{
a[j--]=a[i];
}
}
a[i]=temp;
QuickSort(a,left,i-1);
QuickSort(a,i+1,right);
}
(5)堆排序
思想: 首先建造一个初始大堆;其次,每一趟排序都是将当前无序区的堆顶记录a[0]和区间最后一个记录交换,将新的无序区调整为堆。
//堆排序
//生成大根堆
//调整以spoint为根结点的二叉树为大堆 n为数组大小
void Swap(type *a,type *b)
{
type temp;
temp=*a;
*a=*b;
*b=temp;
}
void CreateHeep(type a[],int spoint, int n)
{
while((2*spoint+1)<n) //左子树根结点值还在数组中
{
int mpoint=2*spoint+1;
if((mpoint+1)<n) //右子树根结点值处于数组中
{
if(a[mpoint]<a[mpoint+1]) //判断左右子树的最大值
{
mpoint=mpoint+1;
}
}
if(a[spoint]<a[mpoint])//如果根结点值小于左右子树中的最大值 则交换
{
Swap(&a[spoint],&a[mpoint]); //交换值
spoint=mpoint; //交换后,继续查看以新的spoint为根结点的子树是否满足大堆要求
}
else
{
break;
}
}
}
void HeepSort(type a[],int n)
{
int i;
for(i=(n/2-1);i>=0;i--) //根据数组创建大堆
{
CreateHeep(a,i,n);
}
for(i=(n-1);i>=1;i--) //堆排序
{
Swap(&a[i],&a[0]);//堆顶元素和最后一个元素交换
CreateHeep(a,0,i);
}
}
(6)归并排序
思想: 分治法,先讲一个待排序数组递归分区,直至分为2个有序数组为止(数组中只有一个元素时,则肯定有序); 而后将2个排好序的数组进行合并.
代码如下:
//归并排序
void MergeSort(type *a,int left,int mid,int right)
{
int i=left;
int j=mid+1;
int k=0;
type *temp=new type[right-left+1];
while((i<=mid)&&(j<=right))
{
if(a[i]<a[j])
{
temp[k++]=a[i++];
}
else
{
temp[k++]=a[j++];
}
}
while(i<=mid)
{
temp[k++]=a[i++];
}
while(j<=right)
{
temp[k++]=a[j++];
}
for(int r=0;r<(right-left+1);r++)
{
a[r+left]=temp[r];
}
delete []temp;
}
void MergeSortFunction(type *a, int left, int right)
{
if(left<right)
{
int mid=(left+right)/2;
MergeSortFunction(a,left,mid);
MergeSortFunction(a,mid+1,right);
MergeSort(a,left,mid,right);
}
}