直接插入排序
从第二个元素开始依次直接插入前面的有序增量序列。
5 7 9 4 3 8
j i
5| 7| 9 4 3 8
5| 7| 9| 4 3 8
4| 5| 7| 9| 3 8
3| 4| 5| 7| 9| 8
3| 4| 5| 7| 8| 9|
void InsertSort(int A[],int n){
int i, j, temp;
for(i=1;i<n;i++){//各元素插入到已排好序的队列中,i从1到n-1
if(A[i]<A[i-1]){//若A[i]小于前驱
temp=A[i];
for(j=i-1;j>=0&&A[j]>temp;j--)//A[i]插入到有序队列
A[j+1]=A[j];//所有大于temp的元素后移
A[j+1]=temp;
}
}
}
/************************************************************************/
/************************************************************************/
(优化)折半插入排序
从第二个元素开始直接插入前面的有序增量序列。寻找插入位置时折半查照。
0 | 1 | 2 | 3 | 4 | 5 | 6 |
---|---|---|---|---|---|---|
20 | 30 | 40 | 50 | 60 | 70 | 55 |
low | mid | high | i | |||
low | mid | high | i | |||
low mid high | i | |||||
high | low | i |
//每次将要插入的数跟增序队列中间的数比较,找出该数的位置插入
void Insert_Sort(int A[],int n){
int i,j,low,high,mid,temp;
for(i=1;i<n;i++){
if(A[i]<A[i-1]){
temp=A[i];
low=0;high=i-1; //折半查找范围
while(low<=high){
mid=(low+high)/2;
if(A[mid]<=temp) low=mid+1;
else high=mid-1;
}
for(j=i-1;j>high;j--)//此时A[i]要插在A[high]之后
A[j+1]=A[j];
A[high+1]=temp;
}
}
}
/************************************************************************/
/************************************************************************/
希尔排序
将序列分成相隔一定增量的子表,再进行直接插入排序
0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | |
---|---|---|---|---|---|---|---|---|
49* | 38 | 65 | 97 | 76 | 13 | 27 | 49 | |
j | d | i | ||||||
d=4 | 49* | 13 | 27 | 49 | 76 | 38 | 65 | 97 |
d=2 | 27 | 13 | 49* | 38 | 65 | 49 | 76 | 97 |
d=1 | 13 | 27 | 38 | 49 | 49* | 65 | 76 | 97 |
void ShellSort(int A[],int n){
int d,i,j,temp;
for(d=n/2;d>=1;d=d/2) //步长变化
for(i=d;i<n;i++)
if(A[i]<A[i-d]){ //把A[i]插入有序增量子表
temp=A[i];
for(j=i-d;j>0 && A[j]>temp;j=j-d)
A[j+d]=A[j]; //记录后移
A[j+d]=temp; //插入
}
}
/************************************************************************/
/************************************************************************/
冒泡排序
从末尾开始两两交换,使得最小的数换到最前面
0 | 1 | 2 | 3 | 4 | 5 |
---|---|---|---|---|---|
4 | 6* | 2 | 6 | 8 | 3 |
i | j | ||||
2 | 4 | 6* | 3 | 6 | 8 |
2 | 3 | 4 | 6* | 6 | 8 |
2 | 3 | 4 | 6* | 6 | 8 |
void swap(int &a,int &b){//不能直接传值调用
int temp=a;
a=b;
b=temp;
}
void BubbleSort(int A[],int n){
int i , j;
for(i=0;i<n-1;i++)
{
bool flag=false;
for(j=n-1;j>i;j--)
if(A[j]<A[j-1])
{
swap(A[j],A[j-1]);
flag=true;
}
if(flag==false) return;
}
}
/************************************************************************/
/************************************************************************/
快速排序
以第一个数为枢轴,将序列分成左右两部分。再将左右两部分分开。依次递归。
49 | 38 | 65 | 97 | 76 | 13 | 27 | 49 |
---|---|---|---|---|---|---|---|
pivot low | high | ||||||
{27 | 38 | 13} | 49 | {76 | 97 | 65 | 49} |
{13} | 27 | {38} | 49 | {49 | 65} | 76 | {97} |
13 | 27 | 38 | 49 | 49 | 65 | 76 | 97 |
//用第一个元素将序列分成左右两部分
int Partition(int A[],int low,int high){
int pivot=A[low];//第一个元素做枢轴
while(low<high)//用low、high搜索枢轴的最终位置
{
while(low<high && A[high]>=pivot) high--;
A[low]=A[high];//比枢轴小的移动到左边
while(low<high && A[low]<=pivot) low++;
A[high]=A[low];//比枢轴大的移动到右端
}
A[low]=pivot;
return low;
}
//快速排序
void QuickSort(int A[], int low, int high){
if(low<high){
int pivotpos=Partition(A,low,high);
QuickSort(A,low,pivotpos-1);
QuickSort(A,pivotpos+1,high);
}
}
/************************************************************************/
/************************************************************************/
简单选择排序
每次从序列中挑选最小的补在递增序列后
3 1 5 7 2
1 3 5 7 2
1 2 5 7 3
1 2 3 5 7
1 2 3 5 7
void SelectSort(int A[],int n){
for(int i=0;i<n-1;i++){//一共进行N-1趟
int min=i; //记录最小元素的位置
for(int j=i+1;j<n;j++)
if(A[j]<A[min]) min=j;
if(min!=i) swap(A[i],A[min]);
}
}