| 网站首页 | 业界新闻 | 小组 | 威客 | 人才 | 下载频道 | 博客 | 代码贴 | 在线编程 | 编程论坛
欢迎加入我们,一同切磋技术
用户名:   
 
密 码:  
共有 4534 人关注过本帖, 2 人收藏
标题:发一些常见的排序算法的c++代码(每个排序以成员函数形式集成到了每个类中)
只看楼主 加入收藏
geninsf009
Rank: 3Rank: 3
等 级:论坛游民
威 望:8
帖 子:613
专家分:95
注 册:2008-8-16
收藏
得分:0 
改进后的归并排序算法:
//////////////////////////////////////////////////////
//递归:MergeSortImprove()全局函数
//改进后的归并排序的算法,先划分子序列,在对各个自序列
//递归排序,再把子序列合并,如果子序列的长度短于M(指定)
//就递归返回,对已经基本有序的序列再进行一次直接插入排序
//L是待排序的序列,L2是排序所需要的辅助数组
//////////////////////////////////////////////////////
template<class T,class E>
void MergeSortImprove(DataSortList<T,E>& L
        ,DataSortList<T,E>& L2,int left,int right)
{
    if(right-left+1<3)                 //如果子序列的长度小于指定的M
        return;                        //就退出递归
    int mid=(left+right)/2;            //划分子区间
    MergeSortImprove(L,L2,left,mid);   //递归对左子序列排序
    MergeSortImprove(L,L2,mid+1,right);//递归对右子序列排序
    MergeImprove(L,L2,left,mid,right); //再把两个子序列归并
};
////////////////////////////MergeSortImprove()函数结束

//////////////////////////////////////////////////////
//DoSort()全局函数
//对已经进行过的归并排序后剩下的基本有序的序列再
//进行最后一次直接插入排序(因为已经基本有序,所以
//最后的直接插入排序的时间复杂度将很低)
//////////////////////////////////////////////////////
template<class T,class E>
void DoSort(DataSortList<T,E>& L,DataSortList<T,E>& L2,
            int left,int right)
{
    //先对待排序的序列进行一次归并排序
    MergeSortImprove(L,L2,left,right);
    //再对已经基本有序的序列进行一次直接插入排序
    L.InsertSort(left,right);
};
//////////////////////////////////////DoSort()函数结束

#endif
2008-11-23 20:44
geninsf009
Rank: 3Rank: 3
等 级:论坛游民
威 望:8
帖 子:613
专家分:95
注 册:2008-8-16
收藏
得分:0 
用于锦标赛排序的胜者树类的定义:
#ifndef WINNERTREE_H
#define WINNERTREE_H

#include<iostream.h>
#include<stdlib.h>
const int DS=100;
#include<cmath>

////////////////////////////////////////////////////
//WinTree<T>胜者树的类模板的定义
//参加比赛的人数n可以是任意的(不一定是2的幂方)
////////////////////////////////////////////////////
template<class T>
class WinTree
{
private:
    T* e;                 //存放参加比赛的数组元素
    int* t;               //存放胜者或者是offset之后的叶子结点
    int n;                //当前的参加比赛的人数
    int offset;           //最底层的叶子结点数
    int h;                //最大满二叉树的高度
    int maxValue;
public:
    WinTree(T* arr,int x);//构造函数
    int play();           //进行一趟比赛,返回每趟的冠军
    int PlayUp(int p);    //从数组e中的第p个元素开始向上重新比赛
    void WinSort();       //利用当前的胜者树进行排序
};
////////////////////////////////WinTree<T>类模板结束

////////////////////////////////////////////////////
//带参数的构造函数
//通过数组来对当前的胜者树进行初始化
//arr数组中是参加比赛的元素,x是参加比赛的人数
////////////////////////////////////////////////////
template<class T>
WinTree<T>::WinTree(T* arr,int x)
{
    /*初始化相关参数*/
    n=x;                            //参加比赛的人数
    e=new T[x];                     //开辟比赛选手的数组
    t=new int[x-1];                 //存放胜者的选手号的数组
    for(int i=0;i<x;i++)            //初始化选手数组
        e[i]=arr[i];
    maxValue=10000;

    /*首先根据参加比赛的选手数n求出最
    底曾叶子结点数和次底层叶子结点数*/
    h=int(log(2*n-1)/log(2));       //最大满二叉树的深度
    offset=int(2*n-1-(pow(2,h)-1)); //计算最底层的叶子结点数
};
////////////////////////////////////带参数的构造函数

[[it] 本帖最后由 geninsf009 于 2008-11-23 20:54 编辑 [/it]]
2008-11-23 20:45
geninsf009
Rank: 3Rank: 3
等 级:论坛游民
威 望:8
帖 子:613
专家分:95
注 册:2008-8-16
收藏
得分:0 
胜者树初次比赛的算法:
////////////////////////////////////////////////////
//play()公有成员函数  对所有的选手进行一次比赛
////////////////////////////////////////////////////
template<class T>
int WinTree<T>::play()
{
    /*首先让最底层的叶子结点进行比赛*/
    int parent;                          //存放胜者的父结点地址
    for(int i=0;i<offset;i+=2)
    {
        parent=int((pow(2,h)-1+i)/2);    //先计算父结点地址
        if(e[i]<=e[i+1])                 //如果e[i]胜者
            t[parent]=i;                 //把胜者放入t数组父结点位置
        else                             //如果e[i+1]是胜者
            t[parent]=i+1;
    };
    
    /*让次外层上的叶子结点进行比赛*/
    int p=offset;                        //处理次底层叶子的游标
   
    if(n%2!=0)                           //如果参赛人数是奇数
    {                                    //让次外层第一个叶子结点和
        if(e[t[parent]]<=e[p])             //前一个内部结点进行比赛
            t[(parent-1)/2]=t[parent];   //把胜者存入t中
        else
            t[(parent-1)/2]=p;
        p=p+1;
    };

    /*处理剩下的次外层上的叶子结点*/
    for(;p<n;p+=2)
    {
        int k=int(pow(2,h)-1-n+p);       //计算当前叶子结点p在当前二叉树中编号
        parent=int((k-1)/2);             //计算父结点在t中的地址
        if(e[p]<=e[p+1])                 //把胜者放入到t数组中的父结点位置
            t[parent]=p;
        else
            t[parent]=p+1;
    };

    /*对t中剩下的元素进行继续向上比赛*/
    if(n%2!=0)                           //如果n是奇数,说明已经有一个与叶
        p=n-3;                           //子结点比赛了,p从t中倒数第二个元素开始
    else
        p=n-2;                           //p从t中的倒数第一个元素开始向前比赛

    for(;p>0;p-=2)
    {                                    //p始终指向左子树
        parent=int((p-1)/2);
        if(e[t[p]]>=e[t[p-1]])           
            t[parent]=t[p-1];            //存放胜者的编号
        else
            t[parent]=t[p];
    };
                     
    return t[0];
};
//////////////////////////////play()公有成员函数结束
2008-11-23 20:46
geninsf009
Rank: 3Rank: 3
等 级:论坛游民
威 望:8
帖 子:613
专家分:95
注 册:2008-8-16
收藏
得分:0 
胜者树进行调整并重新局部比赛的算法:
////////////////////////////////////////////////////
//PlayUp() 从弹出的元素开始向上重新调整确定新的冠军
//p是刚刚作为冠军弹出的元素在e数组中的编号
//返回冠军元素的值
////////////////////////////////////////////////////
template<class T>
int WinTree<T>::PlayUp(int p)
{
    /*先进行叶子结点之间的比赛*/
    int parent;                         //存放当前结点p的父结点
    if(n%2!=0)                          //如果n是奇数
    {
        if(p<offset)                    //如果是最底层的叶子结点
        {
            int k=pow(2,h)-1+p;         //p在整个完全二叉树中的编号
            parent=(k-1)/2;
            if(p%2!=0)                  //如果p是奇数
            {
                if(e[p-1]<=e[p])
                    t[parent]=p-1;
                else
                    t[parent]=p;
            }
            else                        //如果p是偶数
            {
                if(e[p]<=e[p+1])
                    t[parent]=p;
                else
                    t[parent]=p+1;
            }
        }
        else if(p==offset)              //第一个次底层的叶子结点
        {
            parent=(n-2-1)/2;
            if(e[t[n-2]]<=e[p])
                t[parent]=t[n-2];
            else
                t[parent]=p;
        }
        else                            //次底层的叶子结点
        {
            int k=(n-1)+(p-offset);
            parent=(k-1)/2;
            if(p%2!=0)                  //如果p是奇数
            {
                if(e[p]<=e[p+1])
                    t[parent]=p;
                else
                    t[parent]=p+1;
            }
            else                        //如果p是偶数
            {
                if(e[p-1]<=e[p])
                    t[parent]=p-1;
                else
                    t[parent]=p;
            }
        }
    }
    else                                //如果n是偶数
    {
        if(p<offset)                    //如果是最底层叶子结点
        {
            int k=pow(2,h)-1+p;
            parent=(k-1)/2;
            if(p%2!=0)                  //如果p是奇数
            {
                if(e[p-1]<=e[p])
                    t[parent]=p-1;
                else
                    t[parent]=p;
            }
            else                        //如果p是偶数
            {
                if(e[p]<=e[p+1])
                    t[parent]=p;
                else
                    t[parent]=p+1;
            }
        }
        else                            //如果是次底层叶子结点
        {
            int k=(n-1)+(p-offset);
            parent=(k-1)/2;
            if(p%2!=0)                  //如果p是奇数
            {
                if(e[p-1]<=e[p])
                    t[parent]=p-1;
                else
                    t[parent]=p;
            }
            else                        //如果p是偶数
            {
                if(e[p]<=e[p+1])
                    t[parent]=p;
                else
                    t[parent]=p+1;
            }
        }
    }
    p=parent;                           //继续向上层比较
    /*如果p是最后一个内部结点,且n是奇数
    则此时p需要和次外层外部结点比赛*/
    if(p==n-2 && n%2!=0)
    {
        int k=n-2;
        parent=(k-1)/2;
        if(e[t[p]]<=e[offset])
            t[parent]=t[p];
        else
            t[parent]=offset;
        p=parent;
    };
    /*对剩下的内部结点循环向上进行比赛*/    
    while(p!=0)
    {
        parent=(p-1)/2;
        if(p%2!=0)
        {
            if(e[t[p]]<=e[t[p+1]])
                t[parent]=t[p];
            else
                t[parent]=t[p+1];
        }
        else
        {
            if(e[t[p-1]]<=e[t[p]])
                t[parent]=t[p-1];
            else
                t[parent]=t[p];
        };
        p=parent;
    };               
    return t[0];                         //返回冠军的选手号
};
////////////////////////////////////PlayUp()函数结束
2008-11-23 20:47
geninsf009
Rank: 3Rank: 3
等 级:论坛游民
威 望:8
帖 子:613
专家分:95
注 册:2008-8-16
收藏
得分:0 
胜者树排序算法:
////////////////////////////////////////////////////
//WinSort()公有成员函数  利用当前的胜者树进行排序
//时间复杂度是O(n*log2(n))
////////////////////////////////////////////////////
template<class T>
void WinTree<T>::WinSort()
{
    int p;                //每次移出的冠军选手号
    p=play();             //首先构造一棵胜者树,并产生第一个冠军
    for(int i=1;i<=n;i++)
    {
        cout<<e[p]<<" ";  //显示每次产生的冠军的内容
        e[t[0]]=maxValue;     //移出当前冠军选手
        p=PlayUp(p);      //进行从底层向上层的调整比赛
    };
};
///////////////////////////////////WinSort()函数结束

#endif
2008-11-23 20:48
geninsf009
Rank: 3Rank: 3
等 级:论坛游民
威 望:8
帖 子:613
专家分:95
注 册:2008-8-16
收藏
得分:0 
俺是个摄影师  ,所以所有自己编写的代码本身对我来说都没什么用,直接公开,大家参考也多
提意见啊!只是想学好编程去写一些影像处理算法,让拍出的照片更有味道!

[[it] 本帖最后由 geninsf009 于 2008-11-23 21:03 编辑 [/it]]
2008-11-23 21:00
中学者
Rank: 16Rank: 16Rank: 16Rank: 16
等 级:版主
威 望:20
帖 子:3554
专家分:80
注 册:2007-9-14
收藏
得分:0 
厉害!

樱花大战,  有爱.
2008-11-24 23:05
ivapple
Rank: 1
等 级:新手上路
帖 子:46
专家分:0
注 册:2008-7-31
收藏
得分:0 
我以为你是搞计算机的
2008-11-29 03:17
快速回复:发一些常见的排序算法的c++代码(每个排序以成员函数形式集成到了每个类 ...
数据加载中...
 
   



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

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