C#算法(一)选择排序
嗨!朋友们,C#将是未来网络开发的首选语言。本人用了C#开发出选择排序算法。希望能为C#语言的学习者带来一些益处。
不要忘了,学语言要花大力气学数据结构和算法。
using System;
public class SelectionSorter
{
// public enum comp {COMP_LESS,COMP_EQUAL,COMP_GRTR};
private int min;
// private int m=0;
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;
// Console.WriteLine("{0}",list[i]);
}
}
}
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<=13;m++)
Console.WriteLine("{0}",iArrary[m]);
}
}
已经成功的编译。
C#算法(二)插入排序朋友们,我最近加紧写C#的一些算法。选择排序已经推出的。现推出插入算法。
对想提高C#语言编程能力的朋友,我们可以互相探讨一下。
如:下面的程序,并没有实现多态,来,帮它实现一下。
using System;
public class InsertionSorter
{
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,5,3,6,10,55,9,2,87,12,34,75,33,47};
InsertionSorter ii=new InsertionSorter();
ii.Sort(iArrary);
for(int m=0;m<=13;m++)
Console.WriteLine("{0}",iArrary[m]);
}
}
已经编译运行通过.这太简单了,我不做详细介绍了.
C#算法(三)希尔排序
朋友们,我最近加紧写C#的一些算法。选择排序,插入算法是我已经推出的。现推出希尔排序.今后,如有时间我将依次推出其它的算法编写。
希尔排序是将组分段,进行插入排序.
对想提高C#语言编程能力的朋友,我们可以互相探讨一下。
如:下面的程序,并没有实现多态,来,帮它实现一下。using System;
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,3,6,10,55,9,2,87,12,34,75,33,47};
ShellSorter sh=new ShellSorter();
sh.Sort(iArrary);
for(int m=0;m<=13;m++)
Console.WriteLine("{0}",iArrary[m]);
}
}
已经编译通过.
C#算法(四)快速排序
前面我已经推出了三种排序的算法,比较简单。今天我又写了快速排序的算法。希望多多指教。具体的思想,我不做答了。前人的经验。
using System;
namespace QuickSorter
{
public class QuickSorter
{
private void Swap(ref int l,ref int r)
{
int s;
s=l;
l=r;
r=s;
}
public void Sort(int [] list,int low,int high)
{
int pivot;
int l,r;
int mid;
if(high<=low)
return;
else if(high==low+1)
{
if(list[low]>list[high])
Swap(ref list[low],ref list[high]);
return;
}
mid=(low+high)>>1;
pivot=list[mid];
Swap(ref list[low],ref list[mid]);
l=low+1;
r=high;
do
{
while(l<=r&&list[l]<pivot)
l++;
while(list[r]>=pivot)
r--;
if(l<r)
Swap(ref list[l],ref list[r]);
}while(l<r);
list[low]=list[r];
list[r]=pivot;
if(low+1<r)
Sort(list,low,r-1);
if(r+1<high)
Sort(list,r+1,high);
}
}
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};
QuickSorter q=new QuickSorter();
q.Sort(iArrary,0,13);
for(int m=0;m<=13;m++)
Console.WriteLine("{0}",iArrary[m]);
}
}
}
已经编译通过,运行环境:windows xp VC#.net 7.0
C#冒泡算法
参加多次笔试,居然有几次都考到了冒泡算法,一次是C#版的填空,一次是javascript版的全部写出。
虽然每次都凭着我对冒泡法的理解给弄出来的,但是多多少少与标准模式有点差别,在网上搜了一下关于C#版的冒泡算法,居然也没有一个象样的,自己对照算法模式认真写了一个C#版的,已经测试成功。
同时附上【冒泡排序动画演示】
public void BubbleSort(int[] R)
{
int i,j,temp;
//交换标志
bool exchange;
//最多做R.Length-1趟排序
for(i=0; i<R.Length; i++)
{
//本趟排序开始前,交换标志应为假
exchange=false;
for(j=R.Length-2; j>=i; j--)
{
//交换条件
if(R[j+1]<R[j])
{
temp=R[j+1];
R[j+1]=R[j];
R[j]=temp;
//发生了交换,故将交换标志置为真
exchange=true;
}
}
//本趟排序未发生交换,提前终止算法
if(!exchange)
{
break;
}
}
}
}
#endregion
}
}
数据结构与算法(C#实现)系列---二叉树
using System;
using System.Collections;
namespace DataStructure
{
/// <summary>
/// BinaryTree 的摘要说明。
/// </summary>
public class BinaryTree:NaryTree
{
//构造二叉空树
public BinaryTree():base(2)
{
//
// TODO: 在此处添加构造函数逻辑
//
}
public BinaryTree(object _obj):base(2,_obj)
{}
//------------------------------------------------------------------
protected override object GetEmptyInstance(uint _degree)
{ return new BinaryTree(_degree); }
//------------------------------------------------------------------
//重写深度遍历
public override void DepthFirstTraversal(IPrePostVisitor _vis)
{
if ( !IsEmpty() )
{
_vis.PreVisit(this.Key);
this[0].DepthFirstTraversal(_vis);
_vis.Visit(this.Key);
this[1].DepthFirstTraversal(_vis);
_vis.PostVisit(this.Key);
}
}
//二叉树大小的比较
//先比较关键字,如果相等,再比较左子树,如果再相等,则比较右子树----如此递归
#region IComparable 成员
public override int CompareTo(object obj)
{
// TODO: 添加 BinaryTree.CompareTo 实现
//因为Comare()中已经进行了类型断定,故不会出现转型错误
BinaryTree tmpTree=(BinaryTree)obj;
if( this.IsEmpty() )
return tmpTree.IsEmpty()?0:-1;
if( tmpTree.IsEmpty() )
return 1;
int result=Comparer.Default.Compare(this,tmpTree);
if(result==0)
result=this[0].CompareTo(tmpTree[0]);
if(result==0)
result=this[1].CompareTo(tmpTree[1]);
return result;
}
#endregion
}
}
数据结构与算法(C#实现)系列---N叉树(二)
Heavenkiller(原创)
public override uint Degree
{
get
{
return this.degree;
}
}
//-------------------------------------------------------------------------------------
//只用于空树结点
public virtual void AttachKey(object _obj)
{
if(!IsEmpty())
throw new Exception("My:this node must be a empty tree node!");
this.key=_obj;
this.treeList=new ArrayList();//产生一个degree长的数组,并将其初始化为空树
this.treeList.Capacity=(int)this.degree;
for(int i=0;i<this.degree;i++)
{
treeList.Add(new NaryTree(this.degree));
}
/*
foreach(object tmpObj in this.treeList)
{
tmpObj=new NaryTree(this.degree);
}
*/
}
//只用于叶子结点,将叶子结点变为一个空结点,并返回叶子结点关键字的引用
public virtual object DetachKey()
{
if(!IsLeaf())
throw new Exception("My:this node must be a leaf node!");
object result=this.key;//store this leaf node temporary
this.key=null;
this.treeList=null;
return result;
}
//将子树连接到指定树的第num个结点上,前提是这个结点必须是空结点,并且度数相同,否则抛出异常
public virtual void AttachSubtree(uint num,NaryTree _naryTree)
{
if(this.IsEmpty())
throw new Exception("My:it can't be a empty tree!");
if(!(this[num-1].IsEmpty()) | this.degree!=_naryTree.degree )
throw new Exception("My:this[i-1] must be empty and they should have the same degree!");
this[num-1]=_naryTree;
}
//仅为非空树定义,从给定树中删去它的第i棵子树并连上一个空树,度数相同,并且返回删除的子树引用
public virtual NaryTree DetachSubtree(uint num)
{
if (IsEmpty())
throw new Exception("My:it can't be empty! ");
NaryTree tmpTree=this;
((NaryTree)this[num-1]).key=null;
((NaryTree)this[num-1]).treeList=null;
return this;
}
//----------------------------------------------------------------------------------
}
}
造函数逻辑
//
height=-1;
}
public AVLTree(object _obj):base(_obj)
{
height=0;
}
//------------------------------------------------------------------
protected override object GetEmptyInstance(uint _degree)
{ return new AVLTree(); }
//------------------------------------------------------------------
protected int BalanceFactor()
{
if (this.IsEmpty() )
return 0;
return ((AVLTree)this.Left).height-((AVLTree)this.Right).height;
}
//调整高度
protected void AdjustHeight(){ this.height=Math.Max( ((AVLTree)this.Left).height, ((AVLTree)this.Right).height)+1; }
//平衡时的四种旋转方式
protected void LLRotation()
{
if( this.IsEmpty() )
throw new Exception("My:invalid operation!");
AVLTree avlB=new AVLTree(this.key);
avlB.AttachSubtree(1,(AVLTree)this[0][1]);
avlB.AttachSubtree(2,(AVLTree)this[1]);
this.key=this[0].Key;
this[0]=this[0][0];
this[1]=avlB;
//调整两个节点的高度
((AVLTree)this.Right).AdjustHeight();
this.AdjustHeight();
}
protected void LRRotation()
{
if( this.IsEmpty() )
throw new Exception("My:invalid operation!");
((AVLTree)this.Left).RRRotation();
this.LLRotation();
}
protected void RRRotation()
{
if( this.IsEmpty() )
throw new Exception("My:invalid operation!");
AVLTree avlB=new AVLTree(this.key);
avlB.AttachSubtree(1,(AVLTree)this[0]);
avlB.AttachSubtree(2,(AVLTree)this[1][0]);
//avlA.AttachSubtree(1,avlB);
//this=avlA;
this.key=this[1].Key;
this[0]=avlB;
this[1]=this[1][1];
//调整两个节点的高度
((AVLTree)this.Left).AdjustHeight();
this.AdjustHeight();
}
protected void RLRotation()
{
if( this.IsEmpty() )
throw new Exception("My:invalid operation!");
((AVLTree)this.Right).LLRotation();
this.RRRotation();
}
数据结构与算法(C#实现)系列---AVLTree(二)
//---------------override--------------------
public override void AttachKey(object _obj)
{
if(!IsEmpty())
throw new Exception("My:this node must be a empty tree node!");
this.key=_obj;
//产生一个degree长的数组,并将其初始化为空树
this.treeList=new ArrayList();
this.treeList.Capacity=(int)this.degree;
for(int i=0;i<this.degree;i++)
{
treeList.Add(new AVLTree());
}
//
this.height=0;
}
//在改动树的结构后平衡树
public override void Balance()
{
this.AdjustHeight();
//大于1则说明不平衡
if( Math.Abs(this.BalanceFactor())>1)
{
if(this.BalanceFactor()>0)
{
if (((AVLTree)this.Left).BalanceFactor()>0)
this.LLRotation();
else
this.LRRotation();
}
else
{
if (((AVLTree)this.Right).BalanceFactor()<0)
this.RRRotation();
else
this.RLRotation();
}
}
}
public int Height{get{return this.height;}}
}
C#排序算法大全
冒泡排序
本人用了C#开发出冒泡排序算法。希望能为C#语言的学习者带来一些益处。不要忘了,学语言要花大力气学数据结构和算法。
using System;
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();
}
}
}
选择排序
本人用了C#开发出选择排序算法。希望能为C#语言的学习者带来一些益处。不要忘了,学语言要花大力气学数据结构和算法。
using System;
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();
}
}
}
插入排序
插入排序算法。对想提高C#语言编程能力的朋友,我们可以互相探讨一下。如:下面的程序,并没有实现多态,来,帮它实现一下。
using System;
namespace InsertionSorter
{
public class InsertionSorter
{
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();
}
}
}
希尔排序
希尔排序是将组分段,进行插入排序. 对想提高C#语言编程能力的朋友,我们可以互相探讨一下。如:下面的程序,并没有实现多态,来,帮它实现一下。
using System;
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#解答
改编自V星[视窗王子]应答程序,如下:
using System;
class Queen{
const int SIZE = 8;//皇后数
public static void Main()
{
int[] Queen = new int [SIZE];//每行皇后的位置
int y,x,i,j,d,t=0;
y = 0;
Queen[0] = -1;
while( true )
{
for (x=Queen[y]+1; x<SIZE; x++)
{
for (i=0;i<y;i++)
{
j = Queen[i];
d = y-i;
//检查新皇后是否与以前的皇后能相互攻击
if ((j==x)||(j==x-d)||(j==x+d))
break;
}
if (i>=y)
break;//不攻击
}
if (x == SIZE) //没有合适的位置
{
if (0==y)
{
//回朔到了第一行
Console.WriteLine("Done");
break; //结束
}
//回朔
Queen[y]=-1;
y--;
}
else
{
Queen[y]=x;//确定皇后的位置
y++;//下一个皇后
if (y<SIZE)
Queen[y]=-1;
else
{
//所有的皇后都排完了,输出
Console.WriteLine("\n" + ++t +':');
for(i=0;i<SIZE;i++)
{
for (j=0;j<SIZE;j++)
if(Queen[i] == j)
Console.Write('Q');
else
Console.Write('.');
Console.WriteLine();
}
y = SIZE -1;//回朔
}
}
}
}
}
八皇后有解92个。
另:我认为foreach和for循环在意义上是不同的,在这里应该用for.
望指正,此致。
重粒子@Y2K0928
--------------------------------------------------------------------------------
送交者: 视窗王子 列出所有还未回答的带星问题 于 9月 28, 2000 09:16:
主题:多谢重粒子兄 答复本贴
阅读相关的帖子
--------------------------------------------------------------------------------
回答: 给视窗王子:八皇后问题C#版 由 重粒子 于 9月 27, 2000 22:32:
非常感谢您的注解以及优化,不过比较了一下结果,好像我俩的结果是一致的。:-)
另外,关于打印的那部分,如果这样优化:
Console.Write(Queen[i]==j ? 'Q':'.');
似乎可以更简洁一些,粒子兄以为呢?
关于foreach和for, 的确,无论从字面上还是在文档中都让人感到for似乎比foreach更有确定性。然而,foreach毕竟是也一种遍历,关键是遍历的可重复性和法则,即,每次遍历的结果是可预计的和相同的。另外,我们可以通过定制Enumerator来决定foreach的遍历行为,使得“无法遍历”或“不可预计的”变成“可遍历”且“可预计的”,如同C++中重载[]算符使得链表“变成”了数组。
对于一些基本数据结构的遍历,比如数组,foreach还是和for一致的,不过粒子兄提醒的好,对任何事千万不要想当然,它除了会把你引入歧途外不会给你带来任何好处。
目前我正在和MS的C# Developer打交道,事实上现在MS中有部分产品的部分代码用上了C# (不知是正式的还是做试验)。很希望和粒子兄以及各位大大小小的虾兄弟姐妹们一起玩玩这新鲜玩意儿。
对C#泛型中的new()约束的一点思考
对于new()约束,大家可能有一个误解,以为使用了new约束之后,在创建对象时与非泛型的版本是一致的:
public class Tester<T>
where T:new()
{
public Tester()
{
t = new T();//等同于非泛型版本的new? 例如 object o = new object();?
}
private T t;
}
事实上,使用new关键字的作用只是让编译器在泛型实例化之处,检查所绑定的泛型参数是否具有无参构造函数:
Tester<SomeType> t = new Tester<SomeType>();
//此处编译器会检查SomeType是否具有无参构造函数。若没有则会有compile error。
而Tester<T>类的构造函数中的new代码,实际上等同于下面的代码:
public class Tester<T>
where T:new()
{
public Tester()
{
t = System.Activator.CreateInstance<T>();
}
private T t;
}
也就是说,仍然是用反射机制来获取泛型对象的实例的
C# 2.0新特性探究之模拟泛型和内置算法
在C#2.0中,匿名方法、IEnumerable接口和匿名方法的合作,使很多的编程任务变得非常的简单,而且写出来的程序非常的优美。
比如,我们可以写出如下的代码:
List<Book> thelib = Library.getbooks();
List<Book> found = thelib.FindAll(delegate(Book curbook)
{
if (curbook.isbn.StartsWith("..."))
return true;
return false;
});
foreach (Book b in found)
Console.WriteLine(b.isbn);
这段程序非常简单的展示给我们需要查找的信息,代码也非常的直接易懂。内置的数据结构给了我们强大的算法支持,不过,能不能够为自定义的类定义类似的算法呢?
比如,如果我有一个自定义的Library类并没有使用List<Book>存储数据,而是使用某种自定义的数据结构,我能不能也让用户使用类似的语法,忽略存储细节的使用匿名委托来实现特定的算法呢?
答案当然是肯定的,而且在C#中实现这样的功能是非常的简单。
首先让我们看看FindAll中用到的匿名委托的原型
public delegate bool Predicate<T>(T obj);
很明显的,上面的代码等于注册了一个搜索的回调,而在List内部定义了某种遍历的机制,从而实现了一个漂亮的算法结构Closure。
看到了这些,我们就可以定义自己的算法结构了,首先,我定义了一个如下的类
public class MyVec<T>
{
public static MyVec<T> operator +(MyVec<T> a, T b)
{
a._list.Add(b);
return a;
}
public override string ToString()
{
StringBuilder builder = new StringBuilder();
foreach (T a in _list)
{
builder.Append(a.ToString());
builder.Append(",");
}
string ret = builder.Remove(builder.Length - 1, 1).ToString();
return ret;
}
public MyVec<T<>findAll(Predicate<T> act)
{
MyVec<T:>t2 = new MyVec<T>();
foreach(T i in _list)
{
if (act(i))
t2._list.Add(i);
}
return t2;
}
// this is the inner object
private List<T> _list = new List<T>();
}
这个类中包含了一个的List<T>结构,主要是为了证实我们的想法是否可行,事实上,任何一个可以支持foreach遍历的结构都可以作为内置的数据存储对象,我们会在后面的例子中给出一个更加复杂的实现。
下面是用于测试这个实验类的代码:
static void Main(string[] args)
{
MyVec<int> a = new MyVec<int>();
a += 12;
a += 15;
a += 32;
MyVec<int> b = a.findAll(delegate(int x)
{
if (x < 20) return true; return false;
}
);
Console.WriteLine("vection original");
Console.WriteLine(a.ToString());
Console.WriteLine("vection found");
Console.WriteLine(b.ToString());
Console.ReadLine();
}
编译,执行,程序输出:
vection original
12,15,32
vection found
32
和我们预期的完全相同。很明显的,List内部的算法与我们预期的基本相同。
Predicate<T>仅仅是为了仿照系统的实现而采用的一个委托,事实上可以使用自己定义的任何委托作为回调的函数体。
通过使用IEnumberable接口,可以实现对任意结构的遍历,从而对任何数据结构定义强大的算法支持。
浙公网安备 33010602011771号