算法导论之排序算法学习

排序是数据处理中经常使用的一种重要运算,在很多种场合下都会用到。算法导论中第二部分重点讲述了排序的相关知识。
在讲述和给出各种排序代码之前,先稍微说下排序算法的分类,好对于分类的各种算法有一个清晰的概念。
排序算法的分类情况如下所示:
一.基于比较的排序
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&&<= 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;
}

 

posted on 2009-09-13 16:48  笔记  阅读(354)  评论(0编辑  收藏  举报

导航