重新写了一遍代码,算是学习了下,有空还得再看一遍才行。
代码很简单应该都是正确的,有什么改进的地方欢迎讨论。
copy的别人的算法思想总结:
1. 算法设计思想:
(1) 冒泡排序:将数组a[0,1,···,n-1]看做是垂直排列的,每个元素值看做该气泡的重量,因为轻重量的气泡不能在重重量之下,所以从最后一个气泡开始和其前面一个比较,若下面的轻则交换,如此反复直到所有轻气泡都在上面,重的都在下面为止。
(2) 选择排序:第一次循环从0的位置开始找所有元素中最小,与0位置元素交换···第i次循环从i-1的位置开始往后找此时最小元素与i-1元素交换,直到所有的都循环完。
(3) 插入排序:像揭牌一样,设第一个元素是排好序的,第二个元素和第一个元素比较找到它的位置····第i个元素和之前排好的i-1个元素比较找到自己的位置,直到所有的元素都排序完毕。
(4) 归并排序:本次实验中采取自顶向下的分治方法,先将一个大的数组分成近似相等的两部分,分别对两边进行排序,两边各自排好序后将两边的两个小数组在按非递减的顺序归并到一个数组中。具体归并思路是:先设一个大数组,取两个小数组中较小的元素放入这个大数组中直到其中一个小数组的元素插入完毕,然后将另一个数组剩余的值复制入大数组中。
(5) 快速排序:取第一个元素做基准,将所有元素分成左右两部分,用分治法分别对两边排序,然后将两边分别排序好的两组元素再按大小顺序合并成一个数组。
#include <iostream>
using namespace std;
const int size=10;
int a[size]={98,36,24,100,0,2,-1,23,5,26};
void output( int a[] )
{
for ( int i=0;i<size;i++)
cout << a[i] << " ";
cout << endl;
}
void swap(int &a,int &b)
{
int temp=a;
a=b;
b=temp;
}
void bubble_sort( int a[] )
{
cout << "bubble_sort" << endl;
int b[size];
for ( int i=0;i<size;i++)
b[i]=a[i];
for ( int i=0;i<size-1;i++)
{
for( int j=size-1;j>i;j--)
if (b[j]<b[j-1])
swap(b[j],b[j-1]);
cout << i+1 << "times ";
output(b);
}
output(b);
cout << endl << "//////////////////////////////////////////////////////////////////////////" << endl;
}
void select_sort( int a[] )
{
cout << "select_sort" << endl;
int b[size];
int min;
for ( int i=0;i<size;i++)
b[i]=a[i];
for ( int i=0;i<size-1;i++)
{
min=i;
for( int j=i+1;j<size;j++)
if (b[j]<b[min])
min=j;
if (min!=i)
swap(b[min],b[i]);
cout << i+1 << "times ";
output(b);
}
output(b);
cout << endl << "//////////////////////////////////////////////////////////////////////////" << endl;
}
void insert_sort( int a[] )
{
cout << "insert_sort" << endl;
int b[size];
int num,j;
for ( int i=0;i<size;i++)
b[i]=a[i];
for ( int i=1;i<size;i++)
{
if ( b[i]<b[i-1])
{
num=b[i];
j=i-1;
}
while (j>=0&&num<b[j])
{
b[j+1]=b[j];
j--;
}
b[j+1]=num;
cout << i << "times ";
output(b);
}
output(b);
cout << endl << "//////////////////////////////////////////////////////////////////////////" << endl;
}
void merge( int a[],int left,int right,int mid)
{
//此时以mid分开的两个小数组各自排列完毕 left→mid,mid+1→right
int i=left,j=mid+1,cc=left;//cc做b数组的索引用
int b[size];//存储修改后的a数组l到r的排列,稍候再赋值给a
while (i<=mid&&j<=right)
{
if ( a[i]<=a[j])
{
b[cc]=a[i];
i++;
}
else
{
b[cc]=a[j];
j++;
}
cc++;
}
while (j<=right)
b[cc++]=a[j++];
while (i<=mid)
b[cc++]=a[i++];
i=left;
while (i<=right)
{
a[i]=b[i];i++;
}
}
void merge_sort( int a[],int l,int r )
{
int mid=(r+l)/2;
if (l<r)
{
merge_sort(a,l,mid);
merge_sort(a,mid+1,r);
merge(a,l,r,mid);
}
}
int quick(int A[],int a,int b)//返回b[a]在b数组快速排序后的一个新的索引
{
int key=A[a];
while(a<b)
{
while(A[b]>=key&&a<b)//从哪边查找那边索引(a or b)就变化知道后面(b)找到小的或者前面(a)找到大的
b--;
if (a<b)
{
A[a]=A[b];//找到后就从将该值赋给另一边,另一边索引同时变化(a++ or b--)
a++;
//这样的结果是b或者a总在记录着key的位置
//例如此时key到了索引为b的地方
//暂时不需要令A[b]=key,可以等到key到了目标位置后再赋值
//目标位置就是index,index前的值小于key,后的值大于key
}
while (A[a]<=key&&a<b)
a++;
if (a<b)
{
A[b]=A[a];
b--;
}
}
A[a]=key;
return a;
}
void quick_sort(int b[],int left,int right)
{
int a;
if (left<right)
{
a=quick(b,left,right);
quick_sort(b,left,a-1);
quick_sort(b,a+1,right);
}
}
int main()
{
cout << "Test for learn:" << endl;
cout << "orginal array a=";
output(a);
bubble_sort(a);
select_sort(a);
insert_sort(a);
int x[size];
for ( int i=0;i<size;i++)
x[i]=a[i];
merge_sort(x,0,size-1);
cout << "merge_sort" << endl;
output(x);
cout << endl << "//////////////////////////////////////////////////////////////////////////" << endl;
for ( int i=0;i<size;i++)
x[i]=a[i];
quick_sort(x,0,size-1);
cout << "quic_sort" << endl;
output(x);
cout << endl << "//////////////////////////////////////////////////////////////////////////" << endl;
return 0;
}
output
Test for learn:
orginal array a=98 36 24 100 0 2 -1 23 5 26
bubble_sort
1times -1 98 36 24 100 0 2 5 23 26
2times -1 0 98 36 24 100 2 5 23 26
3times -1 0 2 98 36 24 100 5 23 26
4times -1 0 2 5 98 36 24 100 23 26
5times -1 0 2 5 23 98 36 24 100 26
6times -1 0 2 5 23 24 98 36 26 100
7times -1 0 2 5 23 24 26 98 36 100
8times -1 0 2 5 23 24 26 36 98 100
9times -1 0 2 5 23 24 26 36 98 100
-1 0 2 5 23 24 26 36 98 100
//////////////////////////////////////////////////////////////////////////
select_sort
1times -1 36 24 100 0 2 98 23 5 26
2times -1 0 24 100 36 2 98 23 5 26
3times -1 0 2 100 36 24 98 23 5 26
4times -1 0 2 5 36 24 98 23 100 26
5times -1 0 2 5 23 24 98 36 100 26
6times -1 0 2 5 23 24 98 36 100 26
7times -1 0 2 5 23 24 26 36 100 98
8times -1 0 2 5 23 24 26 36 100 98
9times -1 0 2 5 23 24 26 36 98 100
-1 0 2 5 23 24 26 36 98 100
//////////////////////////////////////////////////////////////////////////
insert_sort
1times 36 98 24 100 0 2 -1 23 5 26
2times 24 36 98 100 0 2 -1 23 5 26
3times 24 36 98 100 0 2 -1 23 5 26
4times 0 24 36 98 100 2 -1 23 5 26
5times 0 2 24 36 98 100 -1 23 5 26
6times -1 0 2 24 36 98 100 23 5 26
7times -1 0 2 23 24 36 98 100 5 26
8times -1 0 2 5 23 24 36 98 100 26
9times -1 0 2 5 23 24 26 36 98 100
-1 0 2 5 23 24 26 36 98 100
//////////////////////////////////////////////////////////////////////////
merge_sort
-1 0 2 5 23 24 26 36 98 100
//////////////////////////////////////////////////////////////////////////
quic_sort
-1 0 2 5 23 24 26 36 98 100
//////////////////////////////////////////////////////////////////////////
请按任意键继续. . .
算法过程 设要排序的数组是A[0]……A[N-1],首先任意选取一个数据(通常选用第一个数据)作为关键数据,然后将所有比它小的数都放到它前面,所有比它大的数都放到它后面,这个过程称为一趟快速排序。一趟快速排序的算法是:
1)设置两个变量I、J,排序开始的时候:I=0,J=N-1;
2)以第一个数组元素作为关键数据,赋值给key,即 key=A[0];
3)从J开始向前搜索,即由后开始向前搜索(J=J-1),找到第一个小于key的值A[J],并与A[I]交换;
4)从I开始向后搜索,即由前开始向后搜索(I=I+1),找到第一个大于key的A[I],与A[J]交换;
5)重复第3、4、5步,直到 I=J; (3,4步是在程序中没找到时候j=j-1,i=i+1,直至找到为止。找到并交换的时候i, j指针位置不变。另外当i=j这过程一定正好是i+或j+完成的最后另循环结束)
例如:待排序的数组A的值分别是:(初始关键数据:X=49) 注意关键X永远不变,永远是和X进行比较,无论在什么位子,最后的目的就是把X放在中间,小的放前面大的放后面。
A[0] 、 A[1]、 A[2]、 A[3]、 A[4]、 A[5]、 A[6]:
49 38 65 97 76 13 27
进行第一次交换后: 27 38 65 97 76 13 49
( 按照算法的第三步从后面开始找)
进行第二次交换后: 27 38 49 97 76 13 65
( 按照算法的第四步从前面开始找>X的值,65>49,两者交换,此时:I=3 )
进行第三次交换后: 27 38 13 97 76 49 65
( 按照算法的第五步将又一次执行算法的第三步从后开始找
进行第四次交换后: 27 38 13 49 76 97 65
( 按照算法的第四步从前面开始找大于X的值,97>49,两者交换,此时:I=4,J=6 )
此时再执行第三步的时候就发现I=J,从而结束一趟快速排序,那么经过一趟快速排序之后的结果是:27
8 13 49 76 97 65,即所以大于49的数全部在49的后面,所以小于49的数全部在49的前面。
快速排序就是递归调用此过程——在以49为中点分割这个数据序列,分别对前面一部分和后面一部分进行类似的快速排序,从而完成全部数据序列的快速排序,最后把此数据序列变成一个有序的序列,根据这种思想对于上述数组A的快速排序的全过程如图6所示:
初始状态 {49 38 65 97 76 13 27}
进行一次快速排序之后划分为 {27 38 13} 49 {76 97 65}
分别对前后两部分进行快速排序 {27 38 13} 经第三步和第四步交换后变成 {13 27 38} 完成排序。
{76 97 65} 经第三步和第四步交换后变成 {65 76 97} 完成排序。