| 网站首页 | 业界新闻 | 小组 | 威客 | 人才 | 下载频道 | 博客 | 代码贴 | 在线编程 | 编程论坛
欢迎加入我们,一同切磋技术
用户名:   
 
密 码:  
共有 4533 人关注过本帖, 2 人收藏
标题:发一些常见的排序算法的c++代码(每个排序以成员函数形式集成到了每个类中)
取消只看楼主 加入收藏
geninsf009
Rank: 3Rank: 3
等 级:论坛游民
威 望:8
帖 子:613
专家分:95
注 册:2008-8-16
收藏
得分:0 
直接选择排序:
////////////////////////////////////////////////////
//SelectSort()公有成员函数  直接选择排序
////////////////////////////////////////////////////
template<class T,class E>
void DataSortList<T,E>::SelectSort(int left,int right)
{
    for(int i=left;i<=right-1;i++)
    {
        //k是指向最小的元素的标号
        int k=i;
        //在i后面的所有元素中寻找最小的与第i个元素交换
        for(int j=i;j<=right;j++)
            //如果有更小的,就用k去指向
            if(Vector[j]<Vector[k])
                k=j;
        if(k!=i)
            //把最小的替换到第一个位置去
            Swap(Vector[i],Vector[k]);
    };
};
////////////////////////////////SelectSort()函数结束
2008-11-23 20:33
geninsf009
Rank: 3Rank: 3
等 级:论坛游民
威 望:8
帖 子:613
专家分:95
注 册:2008-8-16
收藏
得分:0 
MSD基数排序的算法:
////////////////////////////////////////////////////
//递归:RadixSort()公有成员函数
//采用MSD方法实现基数排序,left->right是排序的范围,
//d是表示采用第d位为基准进行排序
//算法的思想:利用优先级高的关键码i对序列进行分组,
//每个分组内都具有相同的关键码k,所有的关键码为k的元素
//都处于一个桶内,关键码k对应桶的大小放在BucketStart[k]
////////////////////////////////////////////////////
template<class T,class E>
void DataSortList<T,E>::RadixSort(int left,int right,int d)
{
    /*递归结束的条件*/
    if(left>=right||d<=0)
        return;
    int L=right-left+1;             //得到当前待排序序列长度
    /*首先按照关键码的第d位进行桶的划分*/
    int count[10];                  //数组:用于存放十个阿拉伯数字对应的桶的大小
    for(int i=0;i<10;i++)           //把count[]数组全部初始化为0
        count[i]=0;
    for(i=0;i<L;i++)                //统计每个字符对应的桶的大小
    {
        int k=getDigit(Vector[i],d);//获取第i个元素的第d个排序码k
        count[k]++;                 //统计d位置上排序码为k的元素的个数
    };

    /*把count[]数组中数据转换成每个桶开始的位置*/
    int start=0;                    //每个桶的开始位置
    int len;                        //当前处理的前个桶的长度
    int Bucketstart[10];            //记录每个桶的开始位置
    for(i=0;i<10;i++)               
    {
        len=count[i];               //记录下当前桶的长度
        count[i]=start;             //数据的替换
        Bucketstart[i]=start;
        start=len+start;            //计算下个桶的开始位置
    };

    /*把Vector[]中的数据以桶序放入辅助数组Arr*/
    Element<T,E>* Arr=              //开辟辅助数组的存储空间
        new Element<T,E>[L];
    for(i=0;i<L;i++)
    {
        int k=getDigit(Vector[i],d);//取出要进行比较的关键码
        int pos=count[k];           //得到要插入元素在桶中的位置
        Arr[pos]=Vector[i];         //把元素插入其中
        count[k]++;
    };

    /*把辅助数组中的元素复制回原来的Vector[]中*/
    for(i=0;i<L;i++)
        Vector[i]=Arr[i];

    /*对每个桶(子序列)再进行递归排序*/
    for(i=0;i<10;i++)
    {
        int p1=Bucketstart[i];      //当前桶的开始位置
        int p2=count[i+1]-1;        //当前桶的结束位置
        RadixSort(p1,p2,d-1);
    };
};
/////////////////////////////RadixSort()公有函数结束

////////////////////////////////////////////////////
//getDigit()公有成员函数
//获取关键码v的第d个排序码
////////////////////////////////////////////////////
template<class T,class E>
int DataSortList<T,E>::getDigit(
            Element<T,E>& v,int d)
{
    if(d==3)
        return int(v.key/1000);
    else if(d==2)
        return int(v.key%1000)/100;
    else if(d==1)
        return int(v.key%100)/10;
    else
        return int(v.key%10);
};
//////////////////////////////////getDigit()函数结束

#endif
2008-11-23 20:34
geninsf009
Rank: 3Rank: 3
等 级:论坛游民
威 望:8
帖 子:613
专家分:95
注 册:2008-8-16
收藏
得分:0 
基于静态链表的几种排序算法:
静态链表类的定义:
#ifndef LINKEDLISTSORT_H
#define LINKEDLISTSORT_H

#include<iostream.h>
#include<stdlib.h>
const int DefaultSize=50;
const int maxValue=10000;

//////////////////////////////////////////////////
//ListNode<T>链表结点结构的定义
//T是数据域的类型
//////////////////////////////////////////////////
template<class T>
struct ListNode
{
    T data;                //结点的数据域
    int link;              //结点的指针域
};
///////////////////////////ListNode<T>结构定义结束

//////////////////////////////////////////////////
//StaticList<T>静态链表类的实现
//T是数据域的类型
//////////////////////////////////////////////////
template<class T>
class StaticList
{
private:
    int maxSize;           //链表的最大空间
    int currentSize;       //链表的当前含有的元素个数
    ListNode<T>* Vector;   //链表的结点数组
public:
    StaticList(int* arr,
        int n)             //构造函数
    {
        maxSize=n+10;
        currentSize=n;
        Vector=new ListNode<T>[maxSize];
        Vector[0].data=maxValue;
        Vector[0].link=1;  //初始化附加头结点,指向第一个结点
        for(int i=1;i<=currentSize;i++)
        {                  //初始化当前静态链表
            Vector[i].data=arr[i-1];
            Vector[i].link=0;
        };
    };
    void InsertSort();     //对当前的静态链表进行插入排序
    void LSDSort(int d);   //采用LSD方法(最小排序码优先)进行排序
    void Display()         //显示当前的已经链接好的有序表
    {
        int ptr=Vector[0].link;
        while(ptr!=0)
        {
            cout<<Vector[ptr].data<<" ";
            ptr=Vector[ptr].link;
        };
    };

    ~StaticList()          //析构函数
    {delete [] Vector;};
    T GetDigit(T x,int d); //获得x的第i个排序码
};
///////////////////////////StaticList<T>类声明结束

[[it] 本帖最后由 geninsf009 于 2008-11-23 20:53 编辑 [/it]]
2008-11-23 20:36
geninsf009
Rank: 3Rank: 3
等 级:论坛游民
威 望:8
帖 子:613
专家分:95
注 册:2008-8-16
收藏
得分:0 
静态链表的直接插入排序:
//////////////////////////////////////////////////
//InsretSort()公有成员函数
//对当前的静态链表进行直接插入排序
//////////////////////////////////////////////////
template<class T>
void StaticList<T>::InsertSort()
{
    int ptr=0;                        //游标指针
    for(int i=2;i<=currentSize;i++)
    {
        ptr=0;                        //指向已经排好序的链表的第一个元素
        do                            //寻找插入的位置
        {
            int next=Vector[ptr].link;//得到ptr下个结点的地址
            if(Vector[i].data<Vector[next].data)
            {                         //如果当前元素小于元素next
                Vector[i].link=next;  //把新结点i插入到ptr和next之间
                Vector[ptr].link=i;
                break;                //退出内层循环进行下次插入
            }
            ptr=Vector[ptr].link;
        }
        while(ptr!=0);               
    };
};
//////////////////////InsertSort()公有成员函数结束
2008-11-23 20:37
geninsf009
Rank: 3Rank: 3
等 级:论坛游民
威 望:8
帖 子:613
专家分:95
注 册:2008-8-16
收藏
得分:0 
基于静态链表LSD最小关键码优先排序:
//////////////////////////////////////////////////
//GetDigit()公有成员函数
//获得关键码x的第i个排序码,i从右往左依次是0,1,2...
//////////////////////////////////////////////////
template<class T>
T StaticList<T>::GetDigit(T x,int d)
{
    if(d==3)
        return int(x/1000);
    else if(d==2)
        return int(x%1000)/100;
    else if(d==1)
        return int(x%100)/10;
    else
        return int(x%10);
};
////////////////////////////////GetDigit()函数结束

//////////////////////////////////////////////////
//LSDSort()公有成员函数
//采用LSD的方法(最小关键码优先)的方法进行排序
//基本思想:先按排序码桶进行分配,再进行收集
//其中d是关键码的位数
//////////////////////////////////////////////////
template<class T>
void StaticList<T>::LSDSort(int d)
{
    /*设置每个桶队列的头尾指针*/
    int front[10];                 //10个桶队列的头指针数组
    int rear[10];                  //10个桶队列的尾指针数组

    /*把数据按初始顺序进行连接*/
    for(int i=0;i<10;i++)  
        Vector[i].link=i+1;
    Vector[i].link=0;              //构建单向循环链表

    /*进行d+1趟的分配和收集*/
    int p=0;
    while(p<=d)
    {
        /*首先初始化当前的队列指针*/
        for(i=0;i<10;i++)         
        {front[i]=-1;rear[i]=-1;};
        /*首先把第i个关键码按桶进行分配*/
        int ptr=Vector[0].link;    //链表遍历的游标指针
        while(ptr!=0)
        {
            T k=                   //获得第i个排序码
               GetDigit(Vector[ptr].data,p);   
            if(front[k]==-1)       //如果原来的队列是空的
            {
                front[k]=ptr;
                rear[k]=ptr;       //直接插入队列
            }
            else                   //如果队列不空
            {
                Vector[rear[k]].link=ptr;
                rear[k]=ptr;       //直接把结点挂入队列
            };

            ptr=Vector[ptr].link;  //指针向后推进一格
        };

        /*把当前元素收集起来重新链起来*/
        ptr=0;                     //游标指针
        for(i=0;i<10;i++)          //遍历当前所有的桶
        {
            if(front[i]!=-1)       //如果当前访问的桶不空
            {
                Vector[ptr].link=front[i];
                ptr=rear[i];       //把当前桶中的数据收集到链表中
            };
        };
        Vector[ptr].link=0;        //构建循环链表
        p++;                       //下趟分配和收集                       
    };
};
/////////////////////////////////LSDSort()函数结束

#endif
2008-11-23 20:38
geninsf009
Rank: 3Rank: 3
等 级:论坛游民
威 望:8
帖 子:613
专家分:95
注 册:2008-8-16
收藏
得分:0 
用于堆排序的最大堆类模板的定义:
#ifndef MAXHEAP_H
#define MAXHEAP_H

#define DefaultSize 50
#include<iostream.h>
#include<stdlib.h>


////////////////////////////////////////////////////
//数据表元素Element<T,E>类模板的实现
//T是数据元素的关键码类型,E是元素的数据域的类型
////////////////////////////////////////////////////
template<class T,class E>
class Element
{
public:
    T key;                   //数据元素的关键码
    E data;                  //数据元素的数据域

    Element()                //默认构造函数
    {key=0;data=0;};
    Element(T k,E d)         //构造函数
    {key=k;data=d;};
    T getkey()               //获取关键码
    {return key;};
    T getdata()              //获取关键码
    {return data;};

    //成员重载赋值运算符
    Element<T,E>& operator=(Element<T,E>& R)
    {key=R.key;data=R.data;return *this;}
    //成员重载下列的关系运算符
    bool operator==(Element<T,E>& R)
    {return key==R.key;};
    bool operator<=(Element<T,E>& R)
    {return key<=R.key;};
    bool operator>=(Element<T,E>& R)
    {return key>=R.key;};
    bool operator<(Element<T,E>& R)
    {return key<R.key;};
    bool operator>(Element<T,E>& R)
    {return key>R.key;};
    bool operator!=(Element<T,E>& R)
    {return key!=R.key;};
    //友元重载<<输出运算符
    friend ostream& operator<<(ostream& os,Element<T,E>& R);
};
///////////////////////////////////Element类定义结束

////////////////////////////////////////////////////
//友元重载<<输出运算符
////////////////////////////////////////////////////
template<class T,class E>
ostream& operator<<(ostream& os,Element<T,E>& R)
{
    os<<R.key<<":"<<R.data;
    return os;
};
//////////////////////////////////////<<友元重载结束

////////////////////////////////////////////////////
//MaxHeap<T,E>最大堆的定义
//即根结点的元素大于它的左右子结点
////////////////////////////////////////////////////
template<class T,class E>
class MaxHeap
{
private:
    Element<T,E>* heap;            //存放最大堆中的元素
    int currentSize;               //当前堆中元素的个数
    int maxHeapSize;               //堆的最大容量
    void siftDown(int start,int m);//从start到m进行自顶向下的调整
    void siftUp(int start);        //从start到0自底向上调整
    void Swap(int i,int j)         //交换i和j对应的元素
    {
        Element<T,E> temp;
        temp=heap[i];
        heap[i]=heap[j];
        heap[j]=temp;
    };
public:
    MaxHeap(int sz=DefaultSize);   //默认构造函数,建立一个空堆
    MaxHeap(Element<T,E> arr[],    //构造函数,通过数组来初始化堆
        int n);
    ~MaxHeap(){delete [] heap;}    //析构函数,释放堆的内存
    bool Insert(Element<T,E>& x);  //把元素x插入到最大堆中
    bool Remove(Element<T,E>& x);  //删除堆顶的最大的元素
    bool IsEmpty()const            //判空
    {return currentSize==0;};
    bool IsFull()const             //判满
    {return currentSize==maxHeapSize};
    void HeapSort();               //利用当前的堆进行排序
};
///////////////////////////////////MaxHeap类模板结束

////////////////////////////////////////////////////
//默认构造函数  构造一个空的最大堆
////////////////////////////////////////////////////
template<class T,class E>
MaxHeap<T,E>::MaxHeap(int sz)
{
    maxHeapSize=sz;
    heap=new Element<T,E>[maxHeapSize];
    if(heap==NULL)
    {
        cout<<"内存分配失败!"<<endl;
        exit(1);
    }
    currentSize=0;
};
////////////////////////////////////默认构造函数结束

////////////////////////////////////////////////////
//带参数的构造函数
//通过数组来初始化当前的最大堆,n是元素的个数
////////////////////////////////////////////////////
template<class T,class E>
MaxHeap<T,E>::MaxHeap(Element<T,E> arr[],int n)
{
    /*初始化工作*/
    maxHeapSize=2*n;                 //最大元素个数是当前个数的两倍
    heap=new Element<T,E>[maxHeapSize];
    currentSize=n;                   //当前元素的个数
    for(int i=0;i<n;i++)             //对堆数组进行赋值
        heap[i]=arr[i];

    /*通过siftDown()进行堆序调整*/
    int currentPos=(currentSize-2)/2;//得到当前的最后一个分支结点的位置
    for(;currentPos>=0;currentPos--)
        siftDown(currentPos,currentSize-1);
};
////////////////////////////////带参数的构造函数结束

////////////////////////////////////////////////////
//siftDown()私有成员函数
//进行一次调整堆,即从当前结点start开始逐个向下调整
//一直到m为止结束,因为下沉调整的前提是当前结点的
//左右子树已经构成了一个堆,所以该函数的使用应该从
//最后一个分支结点往前进行调整进行
////////////////////////////////////////////////////
template<class T,class E>
void MaxHeap<T,E>::siftDown(int start,int end)
{
    int p=start;                  //当前的比较结点
    int q=2*p+1;                  //指向当前结点的左子女
    while(q<=end)
    {
        if(heap[p]<heap[q] || heap[p]<heap[q+1])
        {
            if(q+1<=end && heap[q]<heap[q+1])
                q=q+1;
            Swap(p,q);
            p=q;
            q=2*p+1;
        }
        else
            break;
    };
};
//////////////////////////////////siftDown()函数结束

////////////////////////////////////////////////////
//siftUp()公有成员函数
//从当前结点start开始向根结点0进行一次上浮调整
//一般认为start是从叶子结点开始
////////////////////////////////////////////////////
template<class T,class E>
void MaxHeap<T,E>::siftUp(int start)
{
    int p=start;                  //游标指针
    int q;                        //当前结点p的父结点指针
    while(p>0)                    //循环向上比较
    {
        q=int((p-1)/2);           //父结点指针
        if(heap[p]>heap[q])       //如果子结点大于父结点
            Swap(p,q);            //把大的元素上浮调整
        p=q;                      //不管怎样继续向上比较
    };
};
////////////////////////////siftUp()私有成员函数结束

////////////////////////////////////////////////////
//Insert()公有成员函数
//在堆中插入一个元素并重新调整堆序
//只需要从最后一个结点向根结点进行一次siftUp()调整
////////////////////////////////////////////////////
template<class T,class E>
bool MaxHeap<T,E>::Insert(Element<T,E>& x)
{
    //如果堆已经满了
    if(currentSize==maxHeapSize)
    {
        cout<<"当前的堆已经满了,无法插入!"<<endl;
        return false;
    };
    //把新元素插入到堆尾
    heap[currentSize]=x;
    //个数加一
    currentSize++;
    //对刚插入的结点进行一次向上调整
    siftUp(currentSize-1);
    //插入成功
    return true;
};
////////////////////////////Insert()公有成员函数结束

////////////////////////////////////////////////////
//Remove()公有成员函数
//删除堆的顶部的最大的元素,即可以将用heap数组中的
//最后一个元素填补到堆的顶部,并对该顶部结点作一次
//下沉调整,因为左右子树都已经是堆了
////////////////////////////////////////////////////
template<class T,class E>
bool MaxHeap<T,E>::Remove(Element<T,E>& x)
{
    if(currentSize==0)           //如果当前堆是空的
        return false;
    x=heap[0];
    heap[0]=heap[currentSize-1]; //用最后一个元素填充堆顶
    currentSize--;
    siftDown(0,currentSize-1);   //对刚替换的堆顶作一次下沉调整
    return true;
};
////////////////////////////////////Remove()函数结束
2008-11-23 20:39
geninsf009
Rank: 3Rank: 3
等 级:论坛游民
威 望:8
帖 子:613
专家分:95
注 册:2008-8-16
收藏
得分:0 
利用最大堆的堆排序:
////////////////////////////////////////////////////
//HeapSort()堆排序
//利用最大堆的删除函数,对当前的序列进行排序
////////////////////////////////////////////////////
template<class T,class E>
void MaxHeap<T,E>::HeapSort()
{
    Element<T,E> x;
    for(int i=currentSize-1;i>=0;i--)
    {
        Remove(x);
        cout<<x;
    };
};
//////////////////////////////////HeapSort()函数结束

#endif
2008-11-23 20:40
geninsf009
Rank: 3Rank: 3
等 级:论坛游民
威 望:8
帖 子:613
专家分:95
注 册:2008-8-16
收藏
得分:0 
二路归并算法:
#ifndef MERGESORT_H
#define MERGESORT_H

#include"DataSortList.h"

//////////////////////////////////////////////////////
//二路归并算法Merge()全局函数
//L1中已经有了两个有序的子序列,L2是一个辅助数组,
//首先把L1中数据元素复制到L2中,在把L2中的元素归并到L1中去
//left->mid是前一个有序子序列,mid+1->right是第二个有序子序列
//////////////////////////////////////////////////////
template<class T,class E>
void Merge(DataSortList<T,E>& L1,DataSortList<T,E>& L2,
               int left,int mid,int right)
{
    //首先把L1中的数据复制到L2这个辅助数组中来
    for(int i=left;i<=right;i++)
        L2[i]=L1[i];
    
    int p1=left;            //前一个有序序列的首指针
    int p2=mid+1;           //后一个有序序列的首指针
    int p=left;             //L1中序列最后元素的指针
    //再把L2中的数据元素归并到L1中来
    while(p1!=mid+1 && p2!=right+1)
    {
        if(L2[p1]<=L2[p2])  //如果是前一个有序序列的小
        {
            L1[p]=L2[p1];   //把小的加入到L1中去
            p1++;
        }
        else                //如果是后一个有序序列的小
        {
            L1[p]=L2[p2];
            p2++;
        }
        p++;
    };
    //把还剩下几个元素的序列的剩下的元素全部拷入L1中
    while(p1!=mid+1)        //如果是前个有序列还没有结束
    {
        L1[p]=L2[p1];
        p++;p1++;
    };
    while(p2!=right+1)      //如果是后一个有序序列
    {
        L1[p]=L2[p2];
        p++;p2++;
    };
};
///////////////////////////////MergeSort()全局函数结束
2008-11-23 20:42
geninsf009
Rank: 3Rank: 3
等 级:论坛游民
威 望:8
帖 子:613
专家分:95
注 册:2008-8-16
收藏
得分:0 
归并排序:
//////////////////////////////////////////////////////
//递归:MergeSort()全局函数
//对数组L中的元素,通过数组L2作为辅助进行递归归并排序
//划分子序列的原则是(left+right)/2
//////////////////////////////////////////////////////
template<class T,class E>
void MergeSort(DataSortList<T,E>& L,DataSortList<T,E>& L2,
               int left,int right)
{
    if(left<right)
    {
        int mid=(left+right)/2;     //确定分界点
        MergeSort(L,L2,left,mid);   //对左子序列递归归并排序
        MergeSort(L,L2,mid+1,right);//对右子序列递归归并排序
        Merge(L,L2,left,mid,right); //把左右两个子序列合并
    };
};
///////////////////////////////////MergeSort()全局函数
2008-11-23 20:42
geninsf009
Rank: 3Rank: 3
等 级:论坛游民
威 望:8
帖 子:613
专家分:95
注 册:2008-8-16
收藏
得分:0 
经过改进的归并算法:
//////////////////////////////////////////////////////
//MergeImprove()全局函数
//改进过的归并算法,在把L中的元素复制到L2的过程中,
//L2中右边的序列倒序复制到L中去,这样在归并的时候,指针
//可以从两边向中间靠拢,这样就免去了判断每个子序列是否结束
//L中是待排序的元素,L2是复制数组
//////////////////////////////////////////////////////
template<class T,class E>
void MergeImprove(DataSortList<T,E>& L1,DataSortList<T,E>& L2,
                  int left,int mid,int right)
{
    //把L中的元素复制到临时数组L2中去
    for(int i=0;i<=mid;i++)        //把L中左子序列复制到L2中
        L2[i]=L1[i];
    for(i=mid+1;i<=right;i++)      //把L中右子序列复制到倒序L2中
        L2[mid+right-i+1]=L1[i];
    //把L2中的元素归并到L中去
    int p1=left;                   //左边序列的指针
    int p2=right;                  //右边序列的指针
    int p=left;                    //L的最后一个元素的指针
    while(p<=right)
    {
        if(L2[p1]<=L2[p2])         //左序列从左向右
            L1[p++]=L2[p1++];
        else
            L1[p++]=L2[p2--];  //右序列从右往左
    };
};
////////////////////////////////MergeImprove()函数结束
2008-11-23 20:43
快速回复:发一些常见的排序算法的c++代码(每个排序以成员函数形式集成到了每个类 ...
数据加载中...
 
   



关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.020640 second(s), 10 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved