2014年4月27日星期日
最近学习数据结构和GDI+,试着将两者结合在一起做练习,希望能够将数据结构图形化。
1. 编写基本的数据结构类文件DataStructure_Bag.cs,使用数组来实现,可以进行增、删、查、统计、排序等操作。
//FILE://DataStructure_Bag.cs
// CLASS IMPLMENT: class Bag
//
// CONSTRUCTORS for classBag
// Bag():
// Postcondition: default constructor, generatean instance of the bag class
// and the capacity of the bag class is 30
//
// Bag(bag_size size):
// Postcondition: generate an instance of thebag class, and the capacity is
// decided by the parameter users provide
//
// MODIFICATION MEMBERMETHODS for class Bag
// bool insert(bag_typemember):
// Precondition: it's not beyond the capacityof the bag
// Postcondition: if insert successfully returntrue, otherwise false
//
// bool erase(bag_type member):
// Postcondition: if erase successfully returntrue, otherwise false
//
// int search(bag_typetarget):
// Postcondition: if find return the index,otherwise NOT_FOUND(equal -1)
//
// CONST MEMBER METHOD forbag class (not const now)
// void travel():
// Postcondition: travel the bag
//
// int count(bag_typetarget):
// Postcondition: return how many times thetarget has been found, if
// not found, return 0
//
// uint getCapacity():
// Postcondition: return the capacity of thebag
//
// int getUsed():
// Postcondition: return room has been used
//
// bag_type getByIndex(intindex):
// Postcondition: return the item by the indexuser provides
//
// ArrayListgetAllFoundIndex():
// Postcondition: return all the indexs havebeen found
// during the search operation or countoperation
//
// void sort():
// Postcondition: sort all the items in the bag
using System;
using System.Collections.Generic;
using System.Collections;
using System.Linq;
using System.Text;
using System.Diagnostics;
// Alias the data type withmy own type
using bag_size = System.UInt32;
using bag_type = System.Int32;
namespace DataStructure_Bag
{
public classBag
{
private readonly bag_size BAG_CAPACITY;
private const bag_typeNOT_FOUND = -1;
private bag_type[] bagContainer;
private bag_type used;
private ArrayList theAllFoundIndex;
// CONSTRUCTORS
public Bag()
{
BAG_CAPACITY= 30;
bagContainer= new bag_type[BAG_CAPACITY];
used= 0;
theAllFoundIndex= new ArrayList();
}
public Bag(bag_size size)
{
if(size > 0)
{
BAG_CAPACITY= size;
bagContainer= new bag_type[BAG_CAPACITY];
used= 0;
theAllFoundIndex= new ArrayList();
}
else
thrownew Exception("the capacity of a bag can't be zero.");
}
// MODIFICATION MEMBER METHODS
public bool insert(bag_type member)
{
theAllFoundIndex.Clear();
if(used >= BAG_CAPACITY)
{
thrownew OverflowException("the bag has no capacity to insert one itemanymore.");
}
else
{
bagContainer[used++] = member;
}
returntrue;
}
public bool erase(bag_type member)
{
inttheIndex = search(member);
theAllFoundIndex.Clear();
if(NOT_FOUND == theIndex)
returnfalse;
else
bagContainer[theIndex] = bagContainer[--used];
returntrue;
}
public intsearch(bag_typetarget)
{
theAllFoundIndex.Clear();
for(int i = 0; i < used; ++i)
{
if(bagContainer[i]== target)
{
theAllFoundIndex.Add(i);
returni;
}
}
returnNOT_FOUND;
}
// CONST MEMBER METHODS
public intcount(bag_type target)
{
theAllFoundIndex.Clear();
for(int i = 0; i < used; ++i)
{
if(bagContainer[i]== target)
{
theAllFoundIndex.Add(i);
}
}
returntheAllFoundIndex.Count;
}
public uint getCapacity() { return BAG_CAPACITY; }
public int getUsed() { return used; }
public bag_type getByIndex(int index)
{
if(index < 0 || index>= used)
thrownew Exception("Illegal index");
returnbagContainer[index];
}
public ArrayList getAllFoundIndex() { return theAllFoundIndex; }
public voidtravel()
{
for(int i = 0; i < used; ++i)
{
Console.WriteLine(bagContainer[i]);
}
}
public void sort()
{
theAllFoundIndex.Clear();
for(int i = 0; i < used -1; ++i)
{
for(int j = i + 1; j < used; ++j)
{
if(bagContainer[i]> bagContainer[j])
{
bag_type temp = bagContainer[j];
bagContainer[j] = bagContainer[i];
bagContainer[i] = temp;
}
}
}
}
}
}
2. 设计数据结构的图形接口IShape
// File://Shape.cs
// INTERFACE FOR ALL SHAPES:Shape interface
//
// GENERAL METHODS for classimplementing the interface Shape
// Point getLocation():
// Postcondition: get the position of theshape where the shape locates
//
// Color getOutlineColor():
// Postcondition: get the outline color of theshape
//
// void draw():
// Postconditon: draw the shape on thegraphics
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Drawing;
namespace DataStructure_Shape
{
public interface IShape
{
// GENERAL METHODS for interface shape
Point getLocation();
Color getOutlineColor();
void draw(Graphicsgraphics);
}
}
3. 实现Bag类的图形类BagShape,实现IShape接口,用于绘制Bag数据结构
// FILE://BagShape.cs
// CLASS IMPLEMENT: theinterface Shape
//
// CONSTRUCTORS for classBagShape
// BagShape():
// Postcondition: initial the location,outlineColor and name with default value
//
// BagShape(Bag bag):
// Postcondition: initial the bag instance,others keep default value
//
// BagShape(Point location,Color outlineColor):
// Postcondition: initial the BagShape objectwith the provided value
//
// MEMBER METHODS forimplementing the interface IShape
// Point getLocation():
// Postcondition: get the location of theshape
// Color getOutlineColor():
// Postcondition: get the outline color ofthe shape
// void draw(Graphicsgraphics):
// Postcondition: draw the data structure andall items in it on the graphics
using System;
using System.Collections.Generic;
using System.Collections;
using System.Linq;
using System.Text;
using System.Drawing;
using DataStructure_Bag;
using Common;
namespace DataStructure_Shape
{
public class BagShape : IShape
{
// VARIABLES for the interface Shape
private Point location; //the start point of the bag
private stringname; // the name of the bag
private Color outlineColor; //the outline color of the bag
private float outlineWidth; //the width of the outline
private Size size; // the size of the bag
private Bag bag;
public BagBagContainer
{
get{ return bag;}
}
public stringName
{
get{ return name;}
}
// CONSTRUCTORS for the class BagShape
public BagShape()
{
this.location = new Point(0, 0);
this.name = "Bag";
this.outlineColor = Color.Black;
this.outlineWidth = 2;
this.size = new Size(100, 100);
this.bag = new Bag();
}
public BagShape(Bag bag)
{
this.location = new Point(0, 0);
this.name = "Bag";
this.outlineColor = Color.Black;
this.outlineWidth = 2;
this.size = new Size(100, 100);
this.bag = bag;
}
public BagShape(Point location,Color outlineColor,float outlineWidth,Size size,Bag bag)
{
this.location = location;
this.name = "Bag";
this.outlineColor = outlineColor;
this.outlineWidth = outlineWidth;
this.size = size;
this.bag = bag;
}
// MEMBER METHODS for the class BagShape
public Point getLocation() { return this.location; }
public Color getOutlineColor() { return this.outlineColor;}
public void draw(Graphics graphics)
{
stringcapacityString = "容量:"+ bag.getCapacity();
stringusedString = "已用:"+ bag.getUsed();
Font arial10 = new Font("Arial",10);
SizeF capacitySizeF = graphics.MeasureString(capacityString,arial10);
SizeF usedSizeF = graphics.MeasureString(usedString,arial10);
// 绘制文字和容器
graphics.DrawString(capacityString,arial10,
newSolidBrush(Color.Blue), new PointF(location.X, location.Y - capacitySizeF.Height));
graphics.DrawString(usedString,arial10,
newSolidBrush(Color.Blue), new PointF(location.X + size.Width - usedSizeF.Width, location.Y - capacitySizeF.Height));
graphics.DrawRectangle(new Pen(outlineColor,outlineWidth), newRectangle(location,size));
// 绘制元素
PointitemLocation = newPoint(location.X, location.Y + size.Height);
for(int i = 0; i < bag.getUsed(); ++i)
{
stringitemString = "<" + bag.getByIndex(i) + " >";
SizeFitemSizeF = graphics.MeasureString(itemString,arial10);
if(itemLocation.X+ itemSizeF.Width> location.X+ size.Width)
{
itemLocation.Y -= (int)itemSizeF.Height;
itemLocation.X = location.X;
}
if(bag.getAllFoundIndex().Contains(i))
{
graphics.DrawString(itemString,arial10,
newSolidBrush(Color.Red), new PointF(itemLocation.X, itemLocation.Y - itemSizeF.Height));
graphics.DrawRectangle(new Pen(Color.Red, 2),
new Rectangle(itemLocation.X,itemLocation.Y- (int)itemSizeF.Height, (int)itemSizeF.Width,(int)itemSizeF.Height));
}
else
{
graphics.DrawString(itemString,arial10,
newSolidBrush(Color.Blue), new PointF(itemLocation.X, itemLocation.Y - itemSizeF.Height));
graphics.DrawRectangle(new Pen(Color.Blue, 2),
new Rectangle(itemLocation.X,itemLocation.Y- (int)itemSizeF.Height, (int)itemSizeF.Width,(int)itemSizeF.Height));
}
itemLocation.X += (int)itemSizeF.Width;
}
// 资源清理
arial10.Dispose();
graphics.Dispose();
}
}
}
4. 设计逻辑控制类GraphicsToDraw,决定该绘制哪种数据结构;
// FILE:GraphicsToDraw.cs
// Note: decide which kinddata structure should be drawn
//
// STATIC METHOD for theGraphicsToDraw
// static void draw(Graphicsgraph, DATASTRUCTURETYPES dataStructureToDraw, IShape shape)
// Postcondition: according to thedataStructureToDraw, decide which kind of data structure
// should be drawn
// static voiddrawBag(Graphics graph, BagShape bagShape):
// Postcondition: draw the data structure bag
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using DataStructure_Bag;
using DataStructure_Shape;
using System.Drawing;
namespace DataStructureToSee
{
public class GraphicsToDraw
{
static Graphicsgraphics;
public static void draw(Graphics graph, DATASTRUCTURETYPES dataStructureToDraw, IShape shape)
{
graphics= graph;
switch(dataStructureToDraw)
{
caseDATASTRUCTURETYPES.BAG:
drawBag(graphics, (BagShape)shape);
break;
caseDATASTRUCTURETYPES.QUEUE:
//drawQueue();
break;
default:
break;
}
}
private static void drawBag(Graphics graph,BagShape bagShape)
{
bagShape.draw(graph);
}
//private static void drawQueue()
//{ }
}
}
5. 设计展示界面
其实现逻辑如下:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using DataStructure_Shape;
using DataStructure_Bag;
namespace DataStructureToSee
{
// 命名空间一级的枚举,表示数据结构类型
public enum DATASTRUCTURETYPES
{
NONE,
BAG,
QUEUE
}
public partial class DataStructureVisiable: Form
{
Graphics graphics; //作图用的画布
BagShape bagShape; //要绘制的数据结构图形
DATASTRUCTURETYPES theDataStructure; // 将要选择的数据结构类型
public DataStructureVisiable()
{
InitializeComponent();
btnInsert.Enabled = false;
btnDelete.Enabled = false;
btnSearch.Enabled = false;
btnCount.Enabled = false;
btnSort.Enabled = false;
}
///<summary>
///点击运行按钮,初始化数据结构
///</summary>
///<param name="sender"></param>
///<param name="e"></param>
private void btnApply_Click(object sender, EventArgs e)
{
if(string.IsNullOrEmpty(cbDataStructureType.Text))
MessageBox.Show("请先选择数据结构类型!");
else
{
switch(cbDataStructureType.Text.ToString())
{
#region 数据结构---包
case"包":
try
{
theDataStructure = DATASTRUCTURETYPES.BAG;
if (string.IsNullOrEmpty(tbCapacity.Text))
{
operateEnabled();
Size bagSize = new Size(200,200);
bagShape = new BagShape(new Point(plGraphics.Width / 2 - bagSize.Width / 2, plGraphics.Height / 2 - bagSize.Height / 2),
Color.Blue, 2, bagSize, new Bag());
draw();
}
else
{
uint theBagSize;
if (uint.TryParse(tbCapacity.Text, out theBagSize))
{
operateEnabled();
Size bagSize = new Size(200,200);
bagShape = new BagShape(new Point(plGraphics.Width / 2 - bagSize.Width / 2, plGraphics.Height / 2 - bagSize.Height / 2),
Color.Blue, 2, bagSize, new Bag(theBagSize));
GraphicsToDraw.draw(graphics, theDataStructure,bagShape);
}
else
MessageBox.Show("请输入有效的容量值!");
}
}
catch (Exception ex)
{
MessageBox.Show("异常:创建包异常," + ex.Message);
}
break;
#endregion
case"队列":
theDataStructure = DATASTRUCTURETYPES.QUEUE;
break;
default:
theDataStructure = DATASTRUCTURETYPES.NONE;
break;
}
}
}
private void operateEnabled()
{
btnInsert.Enabled = true;
btnDelete.Enabled = true;
btnSearch.Enabled = true;
btnCount.Enabled = true;
btnSort.Enabled = true;
}
///<summary>
///根据数据结构执行插入操作
///</summary>
///<param name="sender"></param>
///<param name="e"></param>
private void btnInsert_Click(object sender, EventArgs e)
{
try
{
switch(cbDataStructureType.Text.ToString())
{
case"包":
int insertValue;
if (int.TryParse(tbInsertValue.Text,out insertValue))
{
bagShape.BagContainer.insert(insertValue);
draw();
}
else
MessageBox.Show("请输入合法的插入值");
break;
}
}
catch(Exception ex)
{
MessageBox.Show("异常:插入异常,"+ ex.Message);
}
}
///<summary>
///根据数据结构执行删除操作
///</summary>
///<param name="sender"></param>
///<param name="e"></param>
private void btnDelete_Click(object sender, EventArgs e)
{
try
{
switch(cbDataStructureType.Text.ToString())
{
case"包":
int deleteValue;
if (int.TryParse(tbDeleteValue.Text,out deleteValue))
{
if (bagShape.BagContainer.erase(deleteValue))
{
draw();
}
else
MessageBox.Show("没有可以删除的元素!");
}
else
MessageBox.Show("请输入合法的删除值");
break;
}
}
catch(Exception ex)
{
MessageBox.Show("异常:删除异常,"+ ex.Message);
}
}
///<summary>
///根据数据结构执行查找操作
///</summary>
///<param name="sender"></param>
///<param name="e"></param>
private void btnSearch_Click(object sender, EventArgs e)
{
try
{
switch(cbDataStructureType.Text.ToString())
{
case"包":
int searchValue;
if (int.TryParse(tbSearchValue.Text,out searchValue))
{
if (bagShape.BagContainer.search(searchValue) >= 0)
{
draw();
MessageBox.Show("已找到元素");
}
else
MessageBox.Show("没有可以找到任何元素!");
}
else
MessageBox.Show("请输入合法的查找值");
break;
}
}
catch(Exception ex)
{
MessageBox.Show("异常:查找异常,"+ ex.Message);
}
}
///<summary>
///根据数据结构执行统计操作
///</summary>
///<param name="sender"></param>
///<param name="e"></param>
private void btnCount_Click(object sender, EventArgs e)
{
try
{
switch(cbDataStructureType.Text.ToString())
{
case"包":
int countValue;
if (int.TryParse(tbCountValue.Text,out countValue))
{
if (bagShape.BagContainer.count(countValue) > 0)
{
draw();
MessageBox.Show("总共找到元素个数:" + bagShape.BagContainer.count(countValue));
}
else
MessageBox.Show("没有可以找到任何元素!");
}
else
MessageBox.Show("请输入合法的统计值");
break;
}
}
catch(Exception ex)
{
MessageBox.Show("异常:统计异常,"+ ex.Message);
}
}
///<summary>
///根据数据结构执行排序操作
///</summary>
///<param name="sender"></param>
///<param name="e"></param>
private void btnSort_Click(object sender, EventArgs e)
{
switch(cbDataStructureType.Text.ToString())
{
case"包":
bagShape.BagContainer.sort();
draw();
break;
}
}
private void draw()
{
graphics= plGraphics.CreateGraphics();
graphics.Clear(this.BackColor);
GraphicsToDraw.draw(graphics, theDataStructure, bagShape);
}
}
}
6. 运行效果如下:
1) 初始化一个Bag:
2) 插入:
3) 删除:
4) 查找:
5) 统计:
6) 排序: