設待排序數組爲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);
}
}