算法导论之排序算法学习
排序是数据处理中经常使用的一种重要运算,在很多种场合下都会用到。算法导论中第二部分重点讲述了排序的相关知识。
在讲述和给出各种排序代码之前,先稍微说下排序算法的分类,好对于分类的各种算法有一个清晰的概念。
排序算法的分类情况如下所示:
一.基于比较的排序
1. 插入排序
直接插入排序,希尔排序
2. 交换排序
起泡排序,快速排序
3. 选择排序
直接选择排序,堆排序
4. 归并排序
二.非基于比较的排序
计数排序,基数排序,桶排序
下面的代码是在看算法导论的过程中写下的,基本上是书中伪代码的实现。
//此代码中是以数字排序为例,且所有数字都存放在容器中,其它类型的排序类似
#include <iostream>
#include <vector>
using namespace std;
void InsertionSort1(vector<int> &ivec) //ascending --Find the right place to insert ivec[i] from back to front
{
vector<int>::size_type i;
int j;
int key;
for(i = 1;i<ivec.size();++i)
{
j = i - 1;
key = ivec[i];
while(j>=0&&ivec[j]>key)
{
ivec[j+1] = ivec[j];
--j;
}
ivec[j+1] = key; //the right place to insert ivec[i] is j+1
}
}
void InsertionSort2(vector<int> &ivec) //ascending --Find the right place to insert ivec[i] from front to back,the both methods has the same result
{
int i,j,k;
int key;
for(i = 1;i < ivec.size();++i)
{
key = ivec[i];
for(k = 0;k < i;++k)
if(ivec[k] > key)
break; //the right place to insert ivec[i] is k
//push back the elements between k and i-1 one place
for(j = i-1;j>=k;--j)
ivec[j+1] = ivec[j];
ivec[k] = key; //insert the element ivec[i]
}
}
void ChooseSort(vector<int> &ivec) //Choose Sort
{
int i,j,k;
for(i = 0;i < ivec.size()-1;++i)
{
k = i;
for(j = i+1;j<ivec.size();++j)
if(ivec[j] < ivec[k])
k = j;
int temp = ivec[k];
ivec[k] = ivec[i];
ivec[i] = temp;
}
}
void BubbleSort1(vector<int> &ivec)
{
int i,j;
for(i = 1;i < ivec.size();++i)
{
for(j = ivec.size()-1;j >= i;--j)
if(ivec[j] < ivec[j-1])
{
int temp = ivec[j];
ivec[j] = ivec[j-1];
ivec[j-1] = temp;
}
}
}
void BubbleSort2(vector<int> &ivec)
{
int i,j;
bool flag = true;
for(i = ivec.size()-1;i > 0;--i)
{
if(flag) //flag用来标志ivec[0---i]是否已经排好序,如果已经排好序就没有必要
{
flag = false;
for(j = 0;j < i;++j)
{
if(ivec[j] > ivec[j+1])
{
int temp = ivec[j+1];
ivec[j+1] = ivec[j];
ivec[j] = temp;
if(flag == false)
flag = true;
}
}
}
}
}
void Merge(vector<int> &resource,vector<int> &dest,int i,int m,int n)
//merge resource[im] and resource[m+1n] sortedly into dest[i.n]
{
int j,k;
for(j = m+1,k = i;i <= m&&j <= n;++k)
if(resource[i] < resource[j])
dest[k] = resource[i++];
else
dest[k] = resource[j++];
while(i <=m)
dest[k++] = resource[i++];
while(j <= n)
dest[k++] = resource[j++];
}
void Msort(vector<int> &origin,vector<int> &result,int beg,int end)
//sort origin[begend] and put the elements into result[begend]
{
int mid;
vector<int> transition(origin.size());
if(beg == end)
result[beg] = origin[beg];
else
{
mid = (beg + end)/2;
Msort(origin,transition,beg,mid);
Msort(origin,transition,mid+1,end);
Merge(transition,result,beg,mid,end);
}
}
void MergeSort(vector<int> &ivec)
{
Msort(ivec,ivec,0,ivec.size()-1);
}
void Max_Heapify(vector<int> &ivec,int i,int n) //堆调整函数,其中n用来标记ivec中参与排序的数字的个数
{
int l,r,largest;
l = 2*i+1;
r = 2*i+2;
largest = i;
if(l<=n&&ivec[l]>ivec[largest])
largest = l;
if(r<=n&&ivec[r]>ivec[largest])
largest = r;
if(largest == i)
return ;
else
{
int temp = ivec[i];
ivec[i] = ivec[largest];
ivec[largest] = temp;
Max_Heapify(ivec,largest,n);
}
}
void Build_Max_Heap(vector<int> &ivec,int n)//建堆
{
int i;
for(i = (n-1)/2;i>=0;--i)
Max_Heapify(ivec,i,n);
}
void HeapSort(vector<int> &ivec)//堆排序
{
int i,n;
n = ivec.size() - 1;
Build_Max_Heap(ivec,n);
for(i = n;i > 0;i--) //注意理解i的取值范围的意义,当i = 1执行完成时,整个数组有序
{
int temp = ivec[0];
ivec[0] = ivec[i];
ivec[i] = temp;
--n;
Max_Heapify(ivec,0,n);
}
}
int Partition(vector<int> &ivec,int beg,int end)//快速排序子过程---数组分割
{
int x = ivec[end];
int i,j,temp;
i = beg - 1;
for(j = beg;j < end;++j)
{
if(ivec[j] <= x)
{
i = i+1;
temp = ivec[i];
ivec[i] = ivec[j];
ivec[j] = temp;
}
}
temp = ivec[i+1];
ivec[i+1] = ivec[end];
ivec[end] = temp;
return i+1;
}
void QuickSort(vector<int> &ivec,int beg,int end)//快速排序
{
int bet;
if(beg >= end)
return ;
else
{
bet = Partition(ivec,beg,end);
QuickSort(ivec,beg,bet-1);
QuickSort(ivec,bet+1,end);
}
}
//注意此处k的取值意义,这表示ivec1中所有的数字都来自0~k-1之间
//ivec2中保存最终的排序结果
void CountingSort(vector<int> &ivec1,vector<int> &ivec2,int k) //计数排序
{
vector<int> tempvec(k);
int i,j;
for(i = 0;i < k;++i)
tempvec[i] = 0;
for(i = 0;i < ivec1.size();++i)
tempvec[ivec1[i]] = tempvec[ivec1[i]] + 1;
for(i = 1;i < k;++i)
tempvec[i] = tempvec[i] + tempvec[i - 1]; //此时tempvec[i]中保存的是排序序列中小于等于i的元素的个数
for(i = ivec1.size() - 1;i >= 0;--i)
{
ivec2[tempvec[ivec1[i]] - 1] = ivec1[i];
tempvec[ivec1[i]] = tempvec[ivec1[i]] - 1; //为了预防ivec中有相等的元素,此处才这样的
}
}
int MaxNum(vector<int> &ivec)//为计数排序所用,确定所要排序序列中关键字的范围
{
int i,max;
max = ivec[0];
for(i = 1;i < ivec.size();++i)
if(ivec[i] > max)
max = ivec[i];
return max;
}
int RandomizeSelect(vector<int> &ivec,int beg,int end,int k)//从一组数(存在ivec中)选择第k小的数
{
if(beg == end)
return ivec[beg];
int q;
q = Partition(ivec,beg,end);
int i;
i = q-beg+1;
if(i == k)
return ivec[q];
else if(i > k)
return RandomizeSelect(ivec,beg,q-1,k);
else
return RandomizeSelect(ivec,q+1,end,k-i);
}
void VectorOutput(vector<int> &ivec)
{
for(vector<int>::size_type i = 0;i<ivec.size();++i)
if(i == 0)
cout<<ivec[i];
else
cout<<"\t"<<ivec[i];
cout<<endl;
}
int main()
{
vector<int> ivec;
ivec.push_back(7);
ivec.push_back(2);
ivec.push_back(8);
ivec.push_back(1);
ivec.push_back(5);
ivec.push_back(5);
ivec.push_back(4);
//在此可以试验以上的各种排序方法
return 0;
}
#include <iostream>
#include <vector>
using namespace std;
void InsertionSort1(vector<int> &ivec) //ascending --Find the right place to insert ivec[i] from back to front
{
vector<int>::size_type i;
int j;
int key;
for(i = 1;i<ivec.size();++i)
{
j = i - 1;
key = ivec[i];
while(j>=0&&ivec[j]>key)
{
ivec[j+1] = ivec[j];
--j;
}
ivec[j+1] = key; //the right place to insert ivec[i] is j+1
}
}
void InsertionSort2(vector<int> &ivec) //ascending --Find the right place to insert ivec[i] from front to back,the both methods has the same result
{
int i,j,k;
int key;
for(i = 1;i < ivec.size();++i)
{
key = ivec[i];
for(k = 0;k < i;++k)
if(ivec[k] > key)
break; //the right place to insert ivec[i] is k
//push back the elements between k and i-1 one place
for(j = i-1;j>=k;--j)
ivec[j+1] = ivec[j];
ivec[k] = key; //insert the element ivec[i]
}
}
void ChooseSort(vector<int> &ivec) //Choose Sort
{
int i,j,k;
for(i = 0;i < ivec.size()-1;++i)
{
k = i;
for(j = i+1;j<ivec.size();++j)
if(ivec[j] < ivec[k])
k = j;
int temp = ivec[k];
ivec[k] = ivec[i];
ivec[i] = temp;
}
}
void BubbleSort1(vector<int> &ivec)
{
int i,j;
for(i = 1;i < ivec.size();++i)
{
for(j = ivec.size()-1;j >= i;--j)
if(ivec[j] < ivec[j-1])
{
int temp = ivec[j];
ivec[j] = ivec[j-1];
ivec[j-1] = temp;
}
}
}
void BubbleSort2(vector<int> &ivec)
{
int i,j;
bool flag = true;
for(i = ivec.size()-1;i > 0;--i)
{
if(flag) //flag用来标志ivec[0---i]是否已经排好序,如果已经排好序就没有必要
{
flag = false;
for(j = 0;j < i;++j)
{
if(ivec[j] > ivec[j+1])
{
int temp = ivec[j+1];
ivec[j+1] = ivec[j];
ivec[j] = temp;
if(flag == false)
flag = true;
}
}
}
}
}
void Merge(vector<int> &resource,vector<int> &dest,int i,int m,int n)
//merge resource[im] and resource[m+1n] sortedly into dest[i.n]
{
int j,k;
for(j = m+1,k = i;i <= m&&j <= n;++k)
if(resource[i] < resource[j])
dest[k] = resource[i++];
else
dest[k] = resource[j++];
while(i <=m)
dest[k++] = resource[i++];
while(j <= n)
dest[k++] = resource[j++];
}
void Msort(vector<int> &origin,vector<int> &result,int beg,int end)
//sort origin[begend] and put the elements into result[begend]
{
int mid;
vector<int> transition(origin.size());
if(beg == end)
result[beg] = origin[beg];
else
{
mid = (beg + end)/2;
Msort(origin,transition,beg,mid);
Msort(origin,transition,mid+1,end);
Merge(transition,result,beg,mid,end);
}
}
void MergeSort(vector<int> &ivec)
{
Msort(ivec,ivec,0,ivec.size()-1);
}
void Max_Heapify(vector<int> &ivec,int i,int n) //堆调整函数,其中n用来标记ivec中参与排序的数字的个数
{
int l,r,largest;
l = 2*i+1;
r = 2*i+2;
largest = i;
if(l<=n&&ivec[l]>ivec[largest])
largest = l;
if(r<=n&&ivec[r]>ivec[largest])
largest = r;
if(largest == i)
return ;
else
{
int temp = ivec[i];
ivec[i] = ivec[largest];
ivec[largest] = temp;
Max_Heapify(ivec,largest,n);
}
}
void Build_Max_Heap(vector<int> &ivec,int n)//建堆
{
int i;
for(i = (n-1)/2;i>=0;--i)
Max_Heapify(ivec,i,n);
}
void HeapSort(vector<int> &ivec)//堆排序
{
int i,n;
n = ivec.size() - 1;
Build_Max_Heap(ivec,n);
for(i = n;i > 0;i--) //注意理解i的取值范围的意义,当i = 1执行完成时,整个数组有序
{
int temp = ivec[0];
ivec[0] = ivec[i];
ivec[i] = temp;
--n;
Max_Heapify(ivec,0,n);
}
}
int Partition(vector<int> &ivec,int beg,int end)//快速排序子过程---数组分割
{
int x = ivec[end];
int i,j,temp;
i = beg - 1;
for(j = beg;j < end;++j)
{
if(ivec[j] <= x)
{
i = i+1;
temp = ivec[i];
ivec[i] = ivec[j];
ivec[j] = temp;
}
}
temp = ivec[i+1];
ivec[i+1] = ivec[end];
ivec[end] = temp;
return i+1;
}
void QuickSort(vector<int> &ivec,int beg,int end)//快速排序
{
int bet;
if(beg >= end)
return ;
else
{
bet = Partition(ivec,beg,end);
QuickSort(ivec,beg,bet-1);
QuickSort(ivec,bet+1,end);
}
}
//注意此处k的取值意义,这表示ivec1中所有的数字都来自0~k-1之间
//ivec2中保存最终的排序结果
void CountingSort(vector<int> &ivec1,vector<int> &ivec2,int k) //计数排序
{
vector<int> tempvec(k);
int i,j;
for(i = 0;i < k;++i)
tempvec[i] = 0;
for(i = 0;i < ivec1.size();++i)
tempvec[ivec1[i]] = tempvec[ivec1[i]] + 1;
for(i = 1;i < k;++i)
tempvec[i] = tempvec[i] + tempvec[i - 1]; //此时tempvec[i]中保存的是排序序列中小于等于i的元素的个数
for(i = ivec1.size() - 1;i >= 0;--i)
{
ivec2[tempvec[ivec1[i]] - 1] = ivec1[i];
tempvec[ivec1[i]] = tempvec[ivec1[i]] - 1; //为了预防ivec中有相等的元素,此处才这样的
}
}
int MaxNum(vector<int> &ivec)//为计数排序所用,确定所要排序序列中关键字的范围
{
int i,max;
max = ivec[0];
for(i = 1;i < ivec.size();++i)
if(ivec[i] > max)
max = ivec[i];
return max;
}
int RandomizeSelect(vector<int> &ivec,int beg,int end,int k)//从一组数(存在ivec中)选择第k小的数
{
if(beg == end)
return ivec[beg];
int q;
q = Partition(ivec,beg,end);
int i;
i = q-beg+1;
if(i == k)
return ivec[q];
else if(i > k)
return RandomizeSelect(ivec,beg,q-1,k);
else
return RandomizeSelect(ivec,q+1,end,k-i);
}
void VectorOutput(vector<int> &ivec)
{
for(vector<int>::size_type i = 0;i<ivec.size();++i)
if(i == 0)
cout<<ivec[i];
else
cout<<"\t"<<ivec[i];
cout<<endl;
}
int main()
{
vector<int> ivec;
ivec.push_back(7);
ivec.push_back(2);
ivec.push_back(8);
ivec.push_back(1);
ivec.push_back(5);
ivec.push_back(5);
ivec.push_back(4);
//在此可以试验以上的各种排序方法
return 0;
}
我没有什么雄心壮志,我只想给自己和关心自己的家人和朋友一个交代,仅此而已。