您的位置:首页 > 编程语言

各种排序算法的代码

2014-07-04 20:19 204 查看
// ALLKindsOfSorts.cpp : 定义控制台应用程序的入口点。
//

#include "stdafx.h"
#include<iostream>
#include<vector>
#include<bitset>

using namespace std;

////////////////////////////////////////所有的排序总结////////////////////////////////////

//1、冒泡排序(O(n*n))
void MaopaoSort(int *a,int len)
{
//这里要明白
for(int i=0;i<len-1;i++)////这层循环控制的是需要排序的数的个数,即控制扫面的轮数
{
bool  IsChange=false;//这是冒泡改进的地方,增加一个标志来判断是否已经提前排好序了
//这里要注意由于比较的是在一个循环下前一个数跟后一个数比较
for(int j=0;j<len-i-1;j++)//这层循环是控制每一轮扫描之后,将最大的数放在最右边
{//这里的j<len-i-1要注意边界的原因,所以是j<len-i-1
if(a[j]>a[j+1])//相邻元素比较
{
//交换
int temp=a[j];
a[j]=a[j+1];
a[j+1]=temp;
IsChange=true;//如果一次扫描完之后都没发生任何的交换,则表明已经排好序了
}
}
if(!IsChange)
{
cout<<"提前结束排序"<<endl;
return;
}
}
}

//2、插入排序(O(n*n))
void InsertSort(int *a,const int len)
{

for(int i=1;i<len;i++)//扫描无序的数组
{
//记住:将第一个数作为已排序的数,从第二个数开始所有的数作为无序的数
if(a[i-1]>a[i])//跟已排序好的数进行比较,找出合适的位置
{
int temp= a[i];//将需要插入的无序数保存起来,并将所有都大于该需要插入的无序数的数后移
int j=i-1;
while(j>=0&&a[j]>temp)//从后往前扫描(j>=0是边界条件),判断已排序的数是否大于需要插入的无序数
{
a[j+1]=a[j];//如果不是合适的位置就往后移动,腾出位置出来
j--;
}
a[j+1]=temp;//找到了合适的位置,执行插入
}
}

}

//3、归并排序O(nlog(n))
void MeageSort(int *result,int* a,int len1,int* b,int len2)
{
if(a==NULL||b==NULL||len1<=0||len2<=0)
return ;
int i=0,j=0;
while(i<len1&&j<len2)
{
if(a[i]<b[j])//比较两个指针指向的元素的大小
{
*(result++)=a[i];
i++;
}
else
{
*(result++)=a[j];
j++;
}
}
if(i<len1)//若序列1比序列2长,将序列1剩下的元素都复制到合并的空间中
{
while(i<len1)
{
*(result++)=a[i++];
}
}
if(j<len2)//若序列2比序列1长,将序列2剩下的元素都复制到合并的空间中
{
while(j<len2)
{
*(result++)=b[j++];
}
}

//for (int i=0;i<15;i++)
//    cout<<*(--result)<<" ";
//cout<<endl;

}

//4、桶排序O(n)
//桶排序用到插入排序(O(n*n))
void InsertSort(vector<int>&a,const int len)
{

for(int i=1;i<len;i++)//扫描无序的数组
{
//记住:将第一个数作为已排序的数,从第二个数开始所有的数作为无序的数
if(a[i-1]>a[i])//跟已排序好的数进行比较,找出合适的位置
{
int temp= a[i];//将需要插入的无序数保存起来,并将所有都大于该需要插入的无序数的数后移
int j=i-1;
while(j>=0&&a[j]>temp)//从后往前扫描(j>=0是边界条件),判断已排序的数是否大于需要插入的无序数
{
a[j+1]=a[j];//如果不是合适的位置就往后移动,腾出位置出来
j--;
}
a[j+1]=temp;//找到了合适的位置,执行插入
}
}

}

//由于桶排序需要将数据分成n等份的范围,每个范围的个数不一样,因此每个桶里面装的数的个数不相同,
//因此选用容器作为桶的数据结构
void BucketSort(vector<int> &result,int *Data,int len)
{
if(Data==NULL||len<=0)
return ;
//求原始数据的最大值与最小值
int max_value=Data[0];
int min_value=Data[0];
for (int i=0;i<len;i++)
{
if(Data[i]>max_value)
max_value=Data[i];
if(Data[i]<min_value)
min_value=Data[i];
}
//将数据分成n等份范围的桶
int k=(max_value-min_value+1)/10+1;//10个桶范围
vector<int > Bucket[10];
//将数据分别装入相应的桶中
for (int i=0;i<len;i++)
{
for(int j=0;j<10;j++)
{
if(Data[i]<min_value+(j+1)*k)
{
Bucket[j].push_back(Data[i]);
break;//将某数放进桶内后进行下一个数
}
}
}
//分别对每一个桶内部进行排序,选用的方法是插入排序
for (int i=0;i<10;i++)
{
InsertSort(Bucket[i],Bucket[i].size());
}
//依次输出每一个桶中的元素
for(int i=0;i<10;i++)
{
for (vector<int>::size_type it=0;it<Bucket[i].size();it++)
{
result.push_back(Bucket[i][it]);
//cout<<Bucket[i][it]<<" ";
}
}

}

//5、基数排序 O(max) max是最大值的位数
int GetPos(int a,int pos)
{
int temp=1;
for (int i=1;i<pos;i++)
temp*=10;
return (a/temp)%10;
}

void RadixSort(int *a,int len,int pos)
{
if(a==NULL||len<=0)
return ;
vector<int> temp[10];//10表示十进制

//将数据放入桶中
for (int i=0;i<len;i++)
{
//a[i]%10表示的是0-9的数
temp[GetPos(a[i],pos)].push_back(a[i]);
}

//按桶的顺序输出数据
for(int i=0;i<10;i++)
{
for (vector<int>::size_type it=0;it<temp[i].size();it++)
{
*(a++)=temp[i][it];
}
}
}

void RadisSort( int *a,int len)
{
if(a==NULL||len<=0)
return ;
int max=a[0];
for(int i=0;i<len;i++)//求出最大值,就可以知道需要排序的次数,即排序的次数等于最大值的位数
{
if(a[i]>max)
max=a[i];
}
int pos=1;//用来指定按哪一位来排序,最初是右边第一位
do
{
//RadixSort(a,len,pos);//也可以采用函数调用的方式,避免调整指针的指向,因为在调用函数时,指针进行了复制,原始指针并没有改变

vector<int> temp[10];//10表示十进制

//将数据放入桶中
for (int i=0;i<len;i++)
{
//a[i]%10表示的是0-9的数
temp[GetPos(a[i],pos)].push_back(a[i]);
}

//按桶的顺序输出数据
for(int i=0;i<10;i++)
{
for (vector<int>::size_type it=0;it<temp[i].size();it++)
{
*(a++)=temp[i][it];//这里要注意修改了指针本身的值
}
}
//因此这里要重新调整指针指向第一个元素
for(int i=0;i<len;i++)//求出最大值,就可以知道需要排序的次数,即排序的次数等于最大值的位数
{
a--;
}

pos++;
}
while(max=max/10);

}

//////////////以下是不稳定的排序//////////////////////////////////
//6、选择排序O(n*n)
void swap(int &a,int&b)
{
int temp;
temp=a;
a=b;
b=temp;
}
void SelectSort(int *a,int len)
{
if(a==NULL||len<=0)
return ;
for (int i=0;i<len;i++)//需要选择n次
{
//a[i]每次选择的临时选择的最小值
//将临时最小值跟后面的数进行比较,判断是否是真的最小值
for(int j=i;j<len;j++)
{
if(a[j]<a[i])//如果发现比最小值还小的元素则进行交换
swap(a[i],a[j]);
}
}
}

//7、希尔排序 O(n*n)

void ShellSort(int *a,int len)
{
if(a==NULL||len<=0)
return ;
for (int i=len/2-1;i>=1;i--)//控制增量的循环
{
for (int j=i;j<len;j=j+i)//控制需要插入元素的个数
{
int temp=a[j];//待插入的元素
int k=j-i;
if(a[k]>temp)
{
while(k>=0&&a[k]>temp)//查找合适的位置
{
a[k+i]=a[k];//按照增量的方式,将大的数按照增量的大小往后移增量个位置
k=k-i;//按照增量的方式递减
}
//找到合适的位置后,执行插入操作
a[k+i]=temp;
}
}
}
}

//8、快速排序

void QuickSort(int *a,int left,int right)
{
if(a==NULL||left<0||right<0)
return ;
int i=left,j=right;
if(left<right)
{
//每次都是取第一个数来作为基准,并把它拿出来,腾出一个空位用作排序
int temp=a[i];//这里可以改进:就是选取中值或平均值作为基准,只需将它们跟第一个数进行交换位置即可,在按照相同的办法进行
while(i<j)//当i=j时,表明一次排序已经结束,此时对应的i的位置就是
{
//由于开始状态是第一个位置作为第一个空位子
//从右向左找出比基准小的数
while(i<j&&a[j]>=temp)//若退出循环就是找到了比基准小的数
{
j--;
}
if(i<j)
{
a[i]=a[j];//发现右边存在比基准小的数,则将右边的数放到左边来,留下一个位置
}
//由于a[j]是右边留下的一个位置,因此可以从左边找出一个比基准大的数来填
//从左向右找出比基准大的数
while(i<j&&a[i]<=temp)//若退出循环就是找到了比基准大的数
{
i++;
}
if(i<j)
{
a[j]=a[i];
}
}
//此时i表示原来第一个元素应该放置的正确的位置
a[i]=temp;//将原来假设第一个位置放到他正确的位置上
////一次排序结束,即已经将基准值放到正确的位置上了,下面是递归排序左右两边的序列
QuickSort(a,left,i-1);
QuickSort(a,i+1,right);
}
}

//9、堆排序
//通过比较二叉树父节点和左右节点的大小来调整
void HeapAdjust(int *a,int i,int size)  //调整堆 i>=1,size是序列长度
{
int lchild=2*i;       //i的左孩子节点序号
int rchild=2*i+1;     //i的右孩子节点序号
int max=i;            //父节点
if(i<=size/2)          //如果i是叶节点就不用进行调整
{
//判断父节点和左右之节点的大小,找出最大值
if(lchild<=size&&a[lchild]>a[max])
{
max=lchild;
}
if(rchild<=size&&a[rchild]>a[max])
{
max=rchild;
}
//如果最大值不是父节点
if(max!=i)
{
swap(a[i],a[max]);//则进行交换
//继续比较,直到所有的父节点都比较完为止
HeapAdjust(a,max,size);//由于max的值没变,因此最大值就是根节点
}
}
}

void BuildHeap(int *a,int size)    //建立堆
{
//由于需要确保最后根节点是最大值,因此是从下往上开始建堆
for(int i=size/2;i>=1;i--)    //非叶节点最大序号值为size/2
{
HeapAdjust(a,i,size);
for(int i=1;i<=10;i++)
cout<<a[i]<<" ";
cout<<endl;
}
}

void HeapSort(int *a,int size)    //堆排序
{
BuildHeap(a,size);//首先建堆
//再排序
for(int i=size;i>=1;i--)
{//每次将最大值放入最后一个位置中,对剩下的进行调整
swap(a[1],a[i]);//交换堆顶和最后一个元素,即每次将剩余元素中的最大者放到最后面
HeapAdjust(a,1,i-1);//重新调整堆顶节点成为大顶堆
}
}

int _tmain(int argc, _TCHAR* argv[])
{
//int a[10]={0,11,21,31,41,56,6,7,8,9};
//int b[5]={1,2,3,4,5};
//cout<<"排序之前的值:"<<endl;
//for (int i=0;i<10;i++)
//    cout<<a[i]<<" ";
//cout<<endl;
//vector<int> c;
//MeageSort(c,a,10,b,5);

//BucketSort(c,a,10);
//RadisSort( a,10);

//cout<<"排序之后的值:"<<endl;
//for (int i=0;i<10;i++)
//    cout<<a[i]<<" ";
//cout<<endl;
/*
float a=1.0f;
cout<<sizeof(a)<<endl;
cout<<(int)a<<endl;
cout<<&a<<endl;
cout<<(int &)a<<endl;
cout<<boolalpha<<((int)a==(int&)a)<<endl;

float b=0.0f;
cout<<sizeof(b)<<endl;
cout<<(int)b<<endl;
cout<<&b<<endl;
cout<<(int &)b<<endl;
cout<<boolalpha<<((int)b==(int&)b)<<endl;

int a[10]={0,11,21,31,41,56,6,7,8,9};
for (int i=0;i<10;i++)
cout<<a[i]<<" ";
cout<<endl;
QuickSort(a,0,9);
for (int i=0;i<10;i++)
cout<<a[i]<<" ";
//int a[]={0,16,20,3,11,17,8};*/
//这里需要注意,对排序是从a[1]开始排序,因此,待排序的数要从a[1]开始
int a[11]={0,11,21,31,41,56,6,7,8,9,10};
HeapSort(a,10);
for(int i=1;i<=10;i++)
cout<<a[i]<<" ";
cout<<endl;

return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: