(1)插入排序
假设位置0到P-1上的元素是已经排好序的,对于P上的元素,其与0到p-1位置元素比较,找到小于P位置元素j把j+1到p-1元素往后移动一个位置,把p位置元素插入,这样就完成0到p位置元素的排序,依次类推,最终完成排序。
(2)希尔排序
使用一个增量序列h,每次排序都使得A[i]<A[i+h],h的选择是:h(k)=N/2,h(k+1)=h(k)/2。当h(k)=1时,完成排序。
(3)堆排序
先把数组元素按堆的顺序存储(采用堆的思想,与堆不同的是结点元素大于或等于儿子结点元素),然后删除最大的(即把最大的依次保存起来,依次放在堆序的最后位置)最后完成排序
(4)归并排序
思想是合并两个已经排序好的 数据序列,比如:要排序24,13,26,1,2,27,38,25. 将该数组分为2部分:24,13,26,1 2,27,38,25,递归的把前4个后4个采用归并排序进行排序。1,13,24,26 2,25,27,38.将这两个部分合并 1,2,13,15,24,26,27,38最后完成排序。
(5)快速排序法
1.三数中值法获取枢纽元素V:把left、center、right位置上的元素进行比较,最小的放在left、最大放在right
2.将枢纽元素与最后一个元素交换
3.将前面的N-1个元素:小元素移到数组的左边,大元素移到数组的右边,其中大小是相对枢纽元素V而言的
4.在数组中枢纽前面的元素(s1)都小于枢纽,后面的元素(s2)都大于枢纽
5.递归的对s1和s2使用同样的方法
例如:8,1,4,9,6,3,5,2,7,0 —>比较left,center,right上元素并交换,找出枢纽元素:0 1 4 9 6 3 5 2 7 8—>枢纽元素为6,把大于6的放在6 后面,小于6的放在其前面,可得 0 1 4 2 5 3 6 9 7 8,6的前部分采用快速排序,后部分采用递归排序。递归结束条件:left+3<=right时,直接采用中值法获取枢纽元素就可以完成排序。
// Algorithm-sorting.cpp : 定义控制台应用程序的入口点。
#include "stdafx.h"
#include<iostream>
using namespace std;
//1.
//插入排序:O(N^2)位置0到位置p的元素是已排过序
void InsertSort(int *&a,int N)
{
int tem,j;
for(int i=1;i<N;i++)
{
tem=a[i];
for(j=i;j>0&&tem<a[j-1];j--)
a[j]=a[j-1];
a[j]=tem;
}
}
//2.
//希尔排序:O(N^6/7)选取增量序列,对于每个i我们有A[i]<A[i+h],h的选择是:h(k)=N/2,h(k+1)=h(k)/2,其排序思想用到插入排序
void shellsort(int *&a,int N)
{
int i,j,h;
int tem;
h=1;
for(h=N/2;h>0;h /=2)
{
for(i=h;i<N;i++)
{
tem=a[i];
for(j=i;j>=h;j-=h)
if(tem<a[j-h])
a[j]=a[j-h];
else
break;
a[j]=tem;
}
}
}
//3.
//*********堆排序:(N*logN)先把数组元素按堆的顺序存储,然后删除最大的
void buildheap(int *&a,int N)//建立堆
{
int *max=new int[N+1];
int hole;
for(int i=0;i<N;i++)
{
hole=i+1;
for(;hole>1&&a[i]>max[hole/2];hole/=2)
{
max[hole]=max[hole/2];
}
max[hole]=a[i];
}
for(int i=0;i<N;i++)
{
a[i]=max[i+1];
}
}
void deletemax(int *&a,int N)//删除最大
{
int tem;
for(int i=N-1;i>0;i--)
{
tem=a[i];
a[i]=a[0];
a[0]=tem;
buildheap(a,i);
}
}
void Heapsort(int *&a,int N)
{
buildheap(a,N);
deletemax(a,N);
}
//4.
/**********归并排序:O(N*logN)合并两个已排序的表,是经典的分治策略
1.将数组打中间(left+right)/2分成2部分
2.
*/
void sort(int *&a,int *&tem,int left,int center,int right)
{
int leftend=center-1;
int t=left;
int num=right-left+1;
while(left<=leftend&¢er<=right)
if(a[left]<a[center])
tem[t++]=a[left++];
else
tem[t++]=a[center++];
while(left<=leftend)
tem[t++]=a[left++];
while(center<=right)
tem[t++]=a[center++];
for(int i=0;i<num;i++,right--)//此步骤是至关重要的,其保证了a中的子数组调换
a[right]=tem[right];
}
void Mergesor(int *&a,int *&tem,int left,int right)
{
int center;
if(left<right)
{
center=(left+right)/2;
Mergesor(a,tem,left,center);
Mergesor(a,tem,center+1,right);
sort(a,tem,left,center+1,right);
}
}
//5.
/*******快速排序法:O(N*logN)
1.三数中值法获取枢纽元素V:把left、center、right位置上的元素进行比较,最小的放在left、最大放在right
2.将枢纽元素与最后一个元素交换
3.将前面的N-1个元素:小元素移到数组的左边,大元素移到数组的右边,其中大小是相对枢纽元素V而言的
4.在数组中枢纽前面的元素(s1)都小于枢纽,后面的元素(s2)都大于枢纽
5.递归的对s1和s2使用同样的方法
*/
void sw(int &a,int &b)
{
int tem;
tem=a;
a=b;
b=tem;
}
int media(int *&a,int left,int right)
{
int center=(left+right)/2;
if(a[center]<a[left])
sw(a[left],a[center]);
if(a[right]<a[left])
sw(a[left],a[right]);
if(a[right]<a[center])
sw(a[center],a[right]);
sw(a[center],a[right-1]);
return a[right-1];
}
void Quicksort(int *&a,int left,int right)
{
if(left<right)
{
int m=media(a,left,right);
if(left+3<=right) //当子数组长度为3时,sw交换就可以完成排序
{
int i=left,j=right-1;
for(;;)
{
while(a[++i]<m){ }
while(a[--j]>m){ }
if(i<j)
sw(a[i],a[j]);
else
break;
}
sw(a[i],a[right-1]);
Quicksort(a,left,i-1);
Quicksort(a,i+1,right);
}
}
}
int _tmain(int argc, _TCHAR* argv[])
{
int N;
cout<<"input N:"<<endl;
cin>>N;
int* a=new int[N];
cout<<"input a:"<<endl;
for(int i=0;i<N;i++)
{
cin>>a[i];
}
//插入排序
//InsertSort(a,N);
//希尔排序
//shellsort(a, N);
//堆排序
//Heapsort(a,N);
//归并排序
//int *tem=new int[N];
//Mergesor(a,tem,0,N-1);
//快速排序法
Quicksort(a,0,N-1);
for(int i=0;i<N;i++)
{
cout<<a[i]<<" ";
}
return 0;
}