C#排序相关算法

http://www.cnblogs.com/zxjyuan/archive/2010/01/06/1640092.html

冒泡法:

Using directives

namespace BubbleSorter
{
    public class BubbleSorter
    {
        public void Sort(int[] list)
        {
            int i, j, temp;
            bool done = false;
            j = 1;
            while ((j < list.Length) && (!done))
            {
                done = true;
                for (i = 0; i < list.Length - j; i++)
                {
                    if (list[i] > list[i + 1])
                    {
                        done = false;
                        temp = list[i];
                        list[i] = list[i + 1];
                        list[i + 1] = temp;
                    }
                }
                j++;
            }
        }
    }
    public class MainClass
    {
        public static void Main()
        {
            int[] iArrary = new int[] { 1, 5, 13, 6, 10, 55, 99, 2, 87, 12, 34, 75, 33, 47 };
            BubbleSorter sh = new BubbleSorter();
            sh.Sort(iArrary);
            for (int m = 0; m < iArrary.Length; m++)
                Console.Write("{0}", iArrary[m]);
            Console.WriteLine();
        }
    }
}

选择排序法

Using directives

namespace SelectionSorter
{
    public class SelectionSorter
    {
        private int min;
        public void Sort(int[] list)
        {
            for (int i = 0; i < list.Length - 1; i++)
            {
                min = i;
                for (int j = i + 1; j < list.Length; j++)
                {
                    if (list[j] < list[min])
                        min = j;
                }
                int t = list[min];
                list[min] = list[i];
                list[i] = t;
            }
        }
    }
    public class MainClass
    {
        public static void Main()
        {
            int[] iArrary = new int[] { 1, 5, 3, 6, 10, 55, 9, 2, 87, 12, 34, 75, 33, 47 };
            SelectionSorter ss = new SelectionSorter();
            ss.Sort(iArrary);
            for (int m = 0; m < iArrary.Length; m++)
                Console.Write("{0}", iArrary[m]);
            Console.WriteLine();
        }
    }
}

插入排序法

Using directives

namespace InsertionSorter
{
    public class InsetionSorter
    {
        public void Sort(int[] list)
        {
            for (int i = 1; i < list.Length; i++)
            {
                int t = list[i];
                int j = i;
                while ((j > 0) && (list[j - 1] > t))
                {
                    list[j] = list[j - 1];
                    --j;
                }
                list[j] = t;
            }
        }
    }
    public class MainClass
    {
        public static void Main()
        {
            int[] iArrary = new int[] { 1, 13, 3, 6, 10, 55, 98, 2, 87, 12, 34, 75, 33, 47 };
            InsertionSorter ii = new InsertionSorter();
            ii.Sort(iArrary);
            for (int m = 0; m < iArrary.Length; m++)
                Console.Write("{0}", iArrary[m]);
            Console.WriteLine();
        }
    }
}

希尔排序法

Using directives

namespace ShellSorter
{
    public class ShellSorter
    {
        public void Sort(int[] list)
        {
            int inc;
            for (inc = 1; inc <= list.Length / 9; inc = 3 * inc + 1) ;
            for (; inc > 0; inc /= 3)
            {
                for (int i = inc + 1; i <= list.Length; i += inc)
                {
                    int t = list[i - 1];
                    int j = i;
                    while ((j > inc) && (list[j - inc - 1] > t))
                    {
                        list[j - 1] = list[j - inc - 1];
                        j -= inc;
                    }
                    list[j - 1] = t;
                }
            }
        }
    }
    public class MainClass
    {
        public static void Main()
        {
            int[] iArrary = new int[] { 1, 5, 13, 6, 10, 55, 99, 2, 87, 12, 34, 75, 33, 47 };
            ShellSorter sh = new ShellSorter();
            sh.Sort(iArrary);
            for (int m = 0; m < iArrary.Length; m++)
                Console.Write("{0}", iArrary[m]);
            Console.WriteLine();
        }
    }
}

以前空闲的时候用C#实现的路径规划算法,今日贴它出来,看大家有没有更好的实现方案。关于路径规划(最短路径)算法的背景知识,大家可以参考《C++算法--图算法》一书。
    该图算法描述的是这样的场景:图由节点和带有方向的边构成,每条边都有相应的权值,路径规划(最短路径)算法就是要找出从节点A到节点B的累积权值最小的路径。
    首先,我们可以将“有向边”抽象为Edge类:

public class Edge
    {
        public string StartNodeID ;
        public string EndNodeID   ;
        public double Weight      ; //权值,代价        
    }

节点则抽象成Node类,一个节点上挂着以此节点作为起点的“出边”表。

       public class Node
    {
        private string iD ;
        private ArrayList edgeList ;//Edge的集合--出边表

        public Node(string id )
     {
            this.iD = id ;
            this.edgeList = new ArrayList() ;
        }

        #region property
        public string ID
     {
            get
          {
                return this.iD ;
            }
        }

        public ArrayList EdgeList
      {
            get
          {
                return this.edgeList ;
            }
        }
        #endregion
    }

在计算的过程中,我们需要记录到达每一个节点权值最小的路径,这个抽象可以用PassedPath类来表示:

/// <summary>
    /// PassedPath 用于缓存计算过程中的到达某个节点的权值最小的路径
    /// </summary>
    public class PassedPath
    {
        private string     curNodeID ;
        private bool     beProcessed ;   //是否已被处理
        private double     weight ;        //累积的权值
        private ArrayList passedIDList ; //路径

public PassedPath(string ID)
        {
            this.curNodeID = ID ;
            this.weight    = double.MaxValue ;
            this.passedIDList = new ArrayList() ;
            this.beProcessed = false ;
        }

#region property
        public bool BeProcessed
        {
            get
            {
                return this.beProcessed ;
            }
            set
            {
                this.beProcessed = value ;
            }
        }

public string CurNodeID
        {
            get
            {
                return this.curNodeID ;
            }
        }

public double Weight 
        {
            get
            {
                return this.weight ;
            }
            set
            {
                this.weight = value ;
            }
        }

public ArrayList PassedIDList
        {
            get
            {
                return this.passedIDList ;
            }
        }
        #endregion
    }

另外,还需要一个表PlanCourse来记录规划的中间结果,即它管理了每一个节点的PassedPath。

/// <summary>
    /// PlanCourse 缓存从源节点到其它任一节点的最小权值路径=》路径表
    /// </summary>
    public class PlanCourse
    {
        private Hashtable htPassedPath ;

#region ctor
        public PlanCourse(ArrayList nodeList ,string originID)
        {
            this.htPassedPath = new Hashtable() ;

Node originNode = null ;
            foreach(Node node in nodeList)
            {
                if(node.ID == originID)
                {
                    originNode = node ;
                }
                else
                {
                    PassedPath pPath = new PassedPath(node.ID) ;
                    this.htPassedPath.Add(node.ID ,pPath) ;
                }
            }

if(originNode == null) 
            {
                throw new Exception("The origin node is not exist !") ;
            }        
    
            this.InitializeWeight(originNode) ;
        }

private void InitializeWeight(Node originNode)
        {
            if((originNode.EdgeList == null) ||(originNode.EdgeList.Count == 0))
            {
                return ;
            }

foreach(Edge edge in originNode.EdgeList)
            {
                PassedPath pPath = this[edge.EndNodeID] ;
                if(pPath == null)
                {
                    continue ;
                }

pPath.PassedIDList.Add(originNode.ID) ;
                pPath.Weight = edge.Weight ;
            }
        }
        #endregion

public PassedPath this[string nodeID]
        {
            get
            {
                return (PassedPath)this.htPassedPath[nodeID] ;
            }
        }
    }

在所有的基础构建好后,路径规划算法就很容易实施了,该算法主要步骤如下:
(1)用一张表(PlanCourse)记录源点到任何其它一节点的最小权值,初始化这张表时,如果源点能直通某节点,则权值设为对应的边的权,否则设为double.MaxValue。
(2)选取没有被处理并且当前累积权值最小的节点TargetNode,用其边的可达性来更新到达其它节点的路径和权值(如果其它节点   经此节点后权值变小则更新,否则不更新),然后标记TargetNode为已处理。
(3)重复(2),直至所有的可达节点都被处理一遍。
(4)从PlanCourse表中获取目的点的PassedPath,即为结果。
    
    下面就来看上述步骤的实现,该实现被封装在RoutePlanner类中:

/// <summary>
    /// RoutePlanner 提供图算法中常用的路径规划功能。
    /// 2005.09.06
    /// </summary>
    public class RoutePlanner
    {
        public RoutePlanner()
        {            
        }

#region Paln
        //获取权值最小的路径
        public RoutePlanResult Paln(ArrayList nodeList ,string originID ,string destID)
        {
            PlanCourse planCourse = new PlanCourse(nodeList ,originID) ;

Node curNode = this.GetMinWeightRudeNode(planCourse ,nodeList ,originID) ;

#region 计算过程
            while(curNode != null)
            {
                PassedPath curPath = planCourse[curNode.ID] ;
                foreach(Edge edge in curNode.EdgeList)
                {
                    PassedPath targetPath = planCourse[edge.EndNodeID] ;
                    double tempWeight = curPath.Weight + edge.Weight ;

if(tempWeight < targetPath.Weight)
                    {
                        targetPath.Weight = tempWeight ;
                        targetPath.PassedIDList.Clear() ;

for(int i=0 ;i<curPath.PassedIDList.Count ;i++)
                        {
                            targetPath.PassedIDList.Add(curPath.PassedIDList[i].ToString()) ;
                        }

targetPath.PassedIDList.Add(curNode.ID) ;
                    }
                }

//标志为已处理
                planCourse[curNode.ID].BeProcessed = true ;
                //获取下一个未处理节点
                curNode = this.GetMinWeightRudeNode(planCourse ,nodeList ,originID) ;
            }
            #endregion
            
            //表示规划结束
            return this.GetResult(planCourse ,destID) ;                
        }
        #endregion

#region private method
        #region GetResult
        //从PlanCourse表中取出目标节点的PassedPath,这个PassedPath即是规划结果
        private RoutePlanResult GetResult(PlanCourse planCourse ,string destID)
        {
            PassedPath pPath = planCourse[destID]  ;

if(pPath.Weight == int.MaxValue)
            {
                RoutePlanResult result1 = new RoutePlanResult(null ,int.MaxValue) ;
                return result1 ;
            }
            
            string[] passedNodeIDs = new string[pPath.PassedIDList.Count] ;
            for(int i=0 ;i<passedNodeIDs.Length ;i++)
            {
                passedNodeIDs[i] = pPath.PassedIDList[i].ToString() ;
            }
            RoutePlanResult result = new RoutePlanResult(passedNodeIDs ,pPath.Weight) ;

return result ;            
        }
        #endregion

#region GetMinWeightRudeNode
        //从PlanCourse取出一个当前累积权值最小,并且没有被处理过的节点
        private Node GetMinWeightRudeNode(PlanCourse planCourse ,ArrayList nodeList ,string originID)
        {
            double weight = double.MaxValue ;
            Node destNode = null ;

foreach(Node node in nodeList)
            {
                if(node.ID == originID)
                {
                    continue ;
                }

PassedPath pPath = planCourse[node.ID] ;
                if(pPath.BeProcessed)
                {
                    continue ;
                }

if(pPath.Weight < weight)
                {
                    weight = pPath.Weight ;
                    destNode = node ;
                }
            }

return destNode ;
        }
        #endregion
        #endregion
    }

时间: 2025-01-08 21:18:50

C#排序相关算法的相关文章

探索推荐引擎内部的秘密,第 2 部分: 深入推荐引擎相关算法 - 协同过滤(转)

第 2 部分: 深入推荐引擎相关算法 - 协同过滤 本系列的第一篇为读者概要介绍了推荐引擎,下面几篇文章将深入介绍推荐引擎的相关算法,并帮助读者高效的实现这些算法. 在现今的推荐技术和算法中,最被大家广泛认可和采用的就是基于协同过滤的推荐方法.它以其方法模型简单,数据依赖性低,数据方便采集 , 推荐效果较优等多个优点成为大众眼里的推荐算法“No.1”.本文将带你深入了解协同过滤的秘密,并给出基于 Apache Mahout 的协同过滤算法的高效实现.Apache Mahout 是 ASF 的一个

二分查找的相关算法题

最近笔试经常遇到二分查找的相关算法题 1)旋转数组中的最小数字 2)在旋转数组中查找某个数 2)排序数组中某个数的出现次数 下面我来一一总结 1 旋转数组的最小数字 题目:把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转.输入一个递增排序的数组的一个旋转,输出旋转数组的最小元素.例如数组{3,4,5,1,2}为{1,2,3,4,5}的一个旋转,该数组的最小值为1. 实现数组的旋转见左旋转字符串. 和二分查找法一样,用两个指针分别指向数组的第一个元素和最后一个元素. 我们注意到旋转

深入推荐引擎相关算法 - 协同过滤

集体智慧和协同过滤 什么是集体智慧 集体智慧 (Collective Intelligence) 并不是 Web2.0 时代特有的,只是在 Web2.0 时代,大家在 Web 应用中利用集体智慧构建更加有趣的应用或者得到更好的用户体验.集体智慧是指在大量的人群的行为和数据中收集答案,帮助你对整个人群得到统计意义上的结论,这些结论是我们在单个个体上无法得到的,它往往是某种趋势或者人群中共性的部分. Wikipedia 和 Google 是两个典型的利用集体智慧的 Web 2.0 应用: Wikip

容器set相关算法

 set_union 算法set_union可构造S1.S2的并集.此集合内含S1或S2内的每一个元素.S1.S2及其并集都是以排序区间表示.返回值是一个迭代器,指向输出区间的尾端. 由于S1和S2内的每个元素都不需唯一,因此,如果某个值在S1出现n次,在S2出现m次,那么该值再输出区间中会出现max(m,n)次,其中n个来自S1,其余来自S2.在STL set容器内,m小于等于1,n小于等于1. template <class InputIterator1,classInputIterat

【STL学习】堆相关算法详解与C++编程实现(Heap)

转自:https://blog.csdn.net/xiajun07061225/article/details/8553808 堆简介 堆并不是STL的组件,但是经常充当着底层实现结构.比如优先级队列(Priority Queue)等等. 堆是一种完全二叉树,因此我们可以用数组来存储所有节点.在这里的实现中,采用了一个技巧:将数组中索引为0的元素保留,设置为极大值或者为极小值(依据大顶堆或者小顶堆而定).那么当某个节点的索引是i时,其左子节点索引为2*i,右子节点索引为2*i+1.父节点是i/2

数据结构(C语言版)顺序栈相关算法的代码实现

这两天完成了栈的顺序存储结构的相关算法,包括初始化.压栈.出栈.取栈顶元素.判断栈是否为空.返回栈长度.栈的遍历.清栈.销毁栈.这次的实现过程有两点收获,总结如下: 一.清楚遍历栈的概念 栈的遍历指的是从栈底想栈顶方向运行visit()函数,这是之前的学习中所忽略的:栈的遍历解除了栈的输出顺序只能从栈顶像栈底方向的限制. 二.清空栈时要不要将stacksize重置 网上看到有的人在实现清空栈这一功能时,将stacksize重置为0,我觉得有点问题,起初的想法是将其重置为初始化时的值,在与同学讨论

图文并茂排序与算法

图文并茂排序与算法总结 转载请注明出处:http://www.cnblogs.com/Joanna-Yan/p/5094764.html 总结下常用的排序算法,方便以后查阅. 常见排序算法:冒泡排序.选择排序.插入排序.壳(shell)排序.合并排序.快速排序.堆排序. 要选择合适的算法,需考虑的因素:执行时间.存储空间和编程工作. 1.选择排序 具有二次方程增长阶,近适用于小列表排序. 通过列表反复扫描,每次扫描选择一项,然后将这一项移动到列表中正确的位置. 选择排序总比较次数=(n-1)+(

加密类型及其相关算法

在互联网通信过程中,如何保证数据的安全性? 在通信过程中,数据安全主要从三个方面考虑:机密性(数据的内容不能被窃取) 完整性(数据的内容不能被修改) 身份验证(确定通信双方的身份) 加密类型:1.对称加密,加密和解密使用同一个密钥,但是密钥如何安全传输比较重要,对称加密数度较快,适于加密数据 2.单向加密,提取数据指纹,主要用于保证数据的完整性 单向加密的特点:输入相同则输出一定相同 雪崩效应:输入的微小改变会引起结果的巨大反差 定长输出 3.非对称加密,使用一对密钥(public-key和pr

探索推荐引擎内部的秘密,第 3 部分: 深入推荐引擎相关算法 - 聚类

聚类分析 什么是聚类分析? 聚类 (Clustering) 就是将数据对象分组成为多个类或者簇 (Cluster),它的目标是:在同一个簇中的对象之间具有较高的相似度,而不同簇中的对象差别较大.所以,在很多应用中,一个簇中的数据对象可以被作为一个整体来对待,从而减少计算量或者提高计算质量. 其实聚类是一个人们日常生活的常见行为,即所谓"物以类聚,人以群分",核心的思想也就是聚类.人们总是不断地改进下意识中的聚类模式来学习如何区分各个事物和人.同时,聚类分析已经广泛的应用在许多应用中,包