您的位置:首页 > 其它

算法补习-第三天-排序(下)

2016-03-03 08:39 260 查看
插入排序:直接插入排序,希尔排序,归并排序

直接插入排序:

将一个新的数据插入到一个有序数组中,并继续保持有序。例如有一个长度为N的无序数组,进行N-1次的插入即能完成排序;第一次,数组第1个数认为是有序的数组,将数组第二个元素插入仅有1个有序的数组中;第二次,数组前两个元素组成有序的数组,将数组第三个元素插入由两个元素构成的有序数组中......第N-1次,数组前N-1个元素组成有序的数组,将数组的第N个元素插入由N-1个元素构成的有序数组中,则完成了整个插入排序。

方法:将数据插入有序数组时,如a[5]={3,5,6,7}中插入4,需将a[1]=4,后边的元素后移,为节省内存,从最后一位开始后移,即先将a[3]的4移到a[4]上,再依次往前后移,即为a[4]=a[3],扩大为a[j]=a[j-1],从最后一位到第二位需要一次后移,移完后再将数据插入第二位a[1].

代码:

#include<iostream>
using namespace std;
void insert_sort(int*array,unsigned int n)
{
int i,j;
int temp;
for(i=1;i<n;i++)
{
temp=*(array+i);
for(j=i;j>0&&*(array+j-1)>temp;j--)
{
*(array+j)=*(array+j-1);
}
*(array+j)=temp;
}
}
int main()
{
int a[5] = {5,6,4,3,8};
insert_sort(a,5);
for(int i=0;i<5;i++)
{
cout<<a[i]<<" ";
}
cout<<endl;
return 0;
}
希尔排序:

将数组按dk间距分成dk个小的数组

例数组a[5]={5,6,4,3,8},其索引值对应为0,1,2,3,4,按间距dk分为dk=5/2个数组,即a[0],a[2],a[4]与a[1],a[3],分别将其进行直接插入排序。再将dk--,进入同上循环,此时间距dk为1,即将a[0],a[1],a[2],a[3],a[4]进行直接插入排序。再进行dk--,dk>=1为假,跳出循环。

注意:基准元素为i=dk前的元素,即a
4000
[0],a[1],其在循环过程中分别被当前值temp比较,

#include<iostream>
using namespace std;

void ShellSort(int a[],int n)
{
int dk = (n-1)/2;
int i,j,temp;
while(dk>=1)
{
//一趟shell排序,对dk个序列分别进行直接插入排序
for(i=dk;i<=n;i++)//需要插入的元素为dk及其以后的数
{
temp = a[i];//将需插入元素放入缓冲区
for(j=i-dk;j>=0&&a[j]>temp;j=j-dk)//建立以dk为间距的小数组,进行比较
{
a[j+dk] = a[j];
}
a[j+dk] = temp;
}
dk--;
}

}
int main()
{
int a[5] = {5,6,4,3,8};
ShellSort(a,5);
for(int i=0;i<5;i++)
{
cout<<a[i]<<" ";
}
cout<<endl;
return 0;
}

归并排序:

思路:

归并排序是建立在归并操作上的一种有效的排序算法。该算法是采用分治法(Divide and Conquer)的一个非常典型的应用。

首先考虑下如何将将二个有序数列合并。这个非常简单,只要从比较二个数列的第一个数,谁小就先取谁,取了后就在对应数列中删除这个数。然后再进行比较,如果有数列为空,那直接将另一个数列的数据依次取出即可。

解决了上面的合并有序数列问题,再来看归并排序,其的基本思路就是将数组分成二组A,B,如果这二组组内的数据都是有序的,那么就可以很方便的将这二组数据进行排序。如何让这二组组内数据有序了?

可以将A,B组各自再分成二组。依次类推,当分出来的小组只有一个数据时,可以认为这个小组组内已经达到了有序,然后再合并相邻的二个小组就可以了。这样通过先递归的分解数列,再合并数列就完成了归并排序。

函数功能:

merge():将一个左右两部分 分别 已排好序的 数组二分成两个子数组,将子数组每一项挨个比较,得到排序后的数组,用于归并。

mergeSort():用于分治,将数组不停二分,直至二分后的结果为两个子数。
代码:
#include<iostream>
using namespace std;

void merge(int a[],int L,int M,int R)
{
int LEFT_SIZE = M - L;
int RIGHT_SIZE = R - M + 1;
int left[LEFT_SIZE];
int right[RIGHT_SIZE];
int i,j,k;

for(i=L;i<M;i++)
{
left[i-L] = a[i];
}
for(i=M;i<=R;i++)
{
right[i-M] = a[i];
}

i=0;j=0;k=L;

while(i<LEFT_SIZE && j<RIGHT_SIZE)
{
if(left[i]<right[j])
{
a[k] = left[i];
i++;
k++;
}
else
{
a[k] = right[j];
j++;
k++;
}
}
while(i<LEFT_SIZE)
{
a[k] = left[i];
i++;
k++;
}
while(j<RIGHT_SIZE)
{
a[k] = right[j];
j++;
k++;
}
}

void mergeSort(int a[],int L,int R)
{
if(L == R)
{
return;
}
else{
int M = (L + R) / 2;
mergeSort(a,L,M);
mergeSort(a,M+1,R);
merge(a,L,M+1,R);
}
}

int main()
{
int a[6] = {5,6,4,3,8,9};
int i;
mergeSort(a,0,5);
for(i=0;i<6;i++)
{
cout<<a[i]<<" ";
}
cout<<endl;
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: