int l;再在循环多次使用l。比在循环里多次重复定义l速度快。
重复多次调用aa.bb.cc.dd。不如先保存cc。然后再多次调用cc.dd效率高。这个其实取决于有没有返回新的副本。
一:泛型编程
class Node<T>
{
public T data;
public Node<T> next;
public Node(T t,Node<T> _next)
{
data = t;
next = _next;
}
}
二:系统时间测试
namespace TimeTest
{
class SystemTimeTest
{
static public void Main()
{
int[] i=new int[50000];
double t=0;
double t2 = 0;
DateTime startTime= DateTime.Now;
BuildArray(i);
t = DateTime.Now.Subtract(startTime).TotalSeconds;//获取总秒数
Console.WriteLine("构建数组时间:" + t);
startTime = DateTime.Now;
Run(i);
t2 = DateTime.Now.Subtract(startTime).TotalSeconds;//获取总秒数
Console.WriteLine("遍历数组时间:" + t2);
// t = t2 + t;
Console.WriteLine("总时长:" + (t+t2));
}
static void BuildArray(int[] arr)
{
for (int i = 0; i < arr.GetUpperBound(0);i++ )
{
arr[i] = i;
}
}
static void Run(int[] arr)
{
for(int i=0;i<arr.GetUpperBound(0);i++)
{
Console.Write(i);
}
}
}
}
根据进程运行时间:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Diagnostics;//诊断
namespace TimeTest
{
class SystemTimeTest
{
static int[] a = new int[10000];
static public void Main()
{
BuildArray(a);
double[] d=new double[4];
string[] s=new string[4];
TimeSpan startTime=new TimeSpan(0), endTime=new TimeSpan(0);
GC.Collect();
GC.WaitForPendingFinalizers();//挂起当前进程,等待垃圾回收完。(等待期间完成)
for (int i = 0; i < d.Length;i++ )
{
startTime = Process.GetCurrentProcess().Threads[0].UserProcessorTime;
s[i] = Run(i+1);
endTime = Process.GetCurrentProcess().Threads[0].UserProcessorTime;
d[i] = endTime.Subtract(startTime).TotalSeconds;
}
Console.WriteLine();
for(int i=0;i<s.Length;i++)
{
Console.WriteLine(s[i] + ":所用的时间:" + d[i]);
}
//完成1计算。
}
static void BuildArray(int[] arr)
{
for (int i = 0; i < arr.GetUpperBound(0); i++)
{
arr[i] = i;
}
}
static string Run(int num)
{
int[] arr = a;
// double d;
if (num == 1)
{
for (int i = 0; i < arr.GetUpperBound(0); i++)
{
double d = Process.GetCurrentProcess().TotalProcessorTime.TotalSeconds;//获取所有线程的运行时间。
print();
}
return "调用所有成员";
}
if (num == 2)
{
Process p=Process.GetCurrentProcess();
for (int i = 0; i < arr.GetUpperBound(0); i++)
{
double d = p.Threads[0].UserProcessorTime.TotalSeconds;
print();
}
return "Process.GetCurrentProcess()";
}
if(num==3)
{
ProcessThread p = Process.GetCurrentProcess().Threads[0];//获取主线程的运行时间
for (int i = 0; i < arr.GetUpperBound(0); i++)
{
double d = p.UserProcessorTime.TotalSeconds;
print();
}
return "Process.GetCurrentProcess().Threads[0]";
}
if(num==4)
{
TimeSpan p = Process.GetCurrentProcess().Threads[0].UserProcessorTime;
for (int i = 0; i < arr.GetUpperBound(0); i++)
{
double d = p.TotalSeconds;
print();
}
return "Process.GetCurrentProcess().Threads[0].UserProcessorTime";
}
return "";
}
static void print()
{
//Console.Write("0");
}
}
}
三、1:静态数组
static void Main(string[] args)
{
string[] names;
names = new string[5];
//实例化数组
string[] names2 = new string[5];
int[] numbers=new int[] {1,2,3,4,5};
Console.WriteLine( names.GetLength(0));//5(个数)
Console.WriteLine(names.GetUpperBound(0));//4(最大元素)
Type t = numbers.GetType();
t.IsArray;//是否是数组
}
void sumNums(params int[] num)//变形参数函数
{
}
四、1:冒泡排序(按大、小)//最慢 数量越多 速度按倍数变慢
static void Main(string[] args)
{
CArray ca = new CArray(10);
Random rd=new Random(100);
for(int i=0;i<20;i++)
{
ca.Insert(rd.Next(0,100));
}
ca.PrintAll();
ca.BubbleSort(true);
ca.PrintAll();
}
}
class CArray
{
int[] arr;
private int upper;
private int count;
public int Upper { get { return upper; } }
public int Count { get { return count; } }
private int currEme = 0;
public CArray(int size)
{
arr = new int[size];
upper = size - 1;
count = size;
}
public bool Insert(int value)
{
if (currEme <= upper)
{
arr[currEme] = value;
currEme++;
return true;
}
else
{
return false;
}
}
public void PrintAll()
{
for(int i=0;i<count;i++)
{
Console.Write(arr[i] + " ");
}
Console.WriteLine("");
}
public void BubbleSort(bool big)//冒泡排序。是否按大小排序
{
for(int i=0;i<count;i++)
{
for(int k=i+1;k<Count;k++)
{
if(big)
{
Swap(ref arr[i], ref arr[k]);
}
else
{
Swap(ref arr[k], ref arr[i]);
}
}
}
}
void Swap(ref int a,ref int b)
{
int temp;
if (a > b)
{
temp = a;
a = b;//获取比较小的k
b = temp;//k变成比较大的i
}
}
}
选择排序://较快 数量越多 速度按倍数变慢
public void SelectionSort(bool big)//选择排序,是否按大小排序
{
int min;
int temp;
for (int i = 0; i < count; i++)
{
min = i;
for (int k = i + 1; k < count; k++)
{
if (big)
{
if (arr[min] < arr[k]) min = k;//前面的小于后面的才换。
}
else if (arr[min] > arr[k]) min = k;//前面的大于后面的才换
}
temp = arr[i];
arr[i] = arr[min];
arr[min] = temp;
}
}
自定义查找:自组织数据加快顺序查找速度。 如果查找的位置大于总数的百分之20.就向前移动一下。
public int CustomSearch(int value)
{
int sIndex=-1;
for(int i=0;i<count;i++)
{
if(arr[i]==value)
{
sIndex = i;
if(i>count*0.2)//如果查找的位置大于总数的百分之20.就向前移动一下。
{
int temp = arr[sIndex-1];//拿到上一个元素的值
arr[sIndex - 1] = arr[sIndex];//找到的值和上一个元素交换
arr[sIndex] = temp;
sIndex--;//返回上一个元素索引
}
return sIndex;
}
}
return sIndex;
}
二分算法:
public int binSearch(int value)
{
int upperBound=upper, loserBound=0, mid;
while (upperBound >= loserBound)
{
mid = (upperBound + loserBound) / 2;
if (value == arr[mid])
return mid;
if (value > arr[mid]) loserBound = mid+1;
else
upperBound = mid-1;
}
return -1;
}
五、1:栈的简单使用
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Collections;
using System.Text.RegularExpressions;//正则表达式
namespace ConsoleApplication7
{
class Program
{
static void Main(string[] args)
{
string expression = "5 + 10 + 15 + 20 - 1";
Stack nums = new Stack();
Stack ops = new Stack();
Calulate(nums, ops, expression);
Console.WriteLine(nums.Pop().ToString());
}
static bool IsNumberic(string input)
{
bool flag = true;
string pattern = @"^\d+$";
Regex validate = new Regex(pattern);
if (!validate.IsMatch(input))
flag = false;
return flag;
}
static void Calulate(Stack N, Stack O, string exp)
{
string ch, token = "";
for (int i = 0; i < exp.Length; i++)
{
ch = exp.Substring(i, 1);
if (IsNumberic(ch))
token += ch;
if (ch == " " || i == (exp.Length - 1))
{
if (IsNumberic(token))
{
N.Push(token);
token = "";
}
}
else if (ch == "+" || ch == "-")
O.Push(ch);
if (N.Count == 2)
Compute(N, O);
}
}
static void Compute(Stack N,Stack O)
{
int oper1, oper2;
string oper;
oper1 = Convert.ToInt32( N.Pop());
oper2 = Convert.ToInt32(N.Pop());
oper = O.Pop().ToString();
switch(oper)
{
case "+":
N.Push(oper1 + oper2);
break;
case "-":
N.Push(oper2 - oper1);
break;
}
}
}
}
计算X进制:
static void MulBase(int n,int b)
{
Stack Digits=new Stack();
do
{
Digits.Push(n % b);
n = n / b;
}
while (n > 0);
while(Digits.Count>0)
{
Console.Write(Digits.Pop());
}
}
正常表达式:
class Program
{
static void Main(string[] args)
{
Regex reg = new Regex("thea");
string str1 = "aaatheaaatheaa";
Match matchSet = reg.Match(str1);
if(matchSet.Success)
{
Console.WriteLine("找到的位置:" + matchSet.Index);
}
MatchCollection result = reg.Matches(str1);//多个结果
if(result.Count>0)
{
foreach(Match m in result)
{
Console.WriteLine("2找到的位置:" +m.Index );
}
}
string[] words = new string[] { "bad", "bd", "baaad", "bear", "bend" };
foreach(string word in words)
{
if (Regex.IsMatch(word, "ba+"))//a至少出现一次
Console.Write(word + " ");
}
Console.WriteLine();
foreach (string word in words)
{
if (Regex.IsMatch(word, "ba*"))//a可以出现任意次数(可以没有)
Console.Write(word + " ");
}
Console.WriteLine();
foreach (string word in words)
{
if (Regex.IsMatch(word, "ba?d"))//a最多出现一次(可以没有)bad或bd
Console.Write(word + " ");
}
Console.WriteLine();
Console.WriteLine("============================");
string[] ds = new string[] { "Part", "of", "this", "<b>string</b>", "bold" };
string regExp = "<.*?>";//<.*>贪心。<.*?>惰性
MatchCollection mc;
foreach(string word in ds)
{
if(Regex.IsMatch(word,regExp))//如果匹配到了
{
mc = Regex.Matches(word, regExp);
for(int i=0;i<mc.Count;i++)
{
Console.Write(mc[i].Value+" ");
}
}
}
//* 任意
//? 零次或一次
//+ 至少一次
//{3} 指定次数
//{n,m} 指定次数之间
//{n,} 至少匹配N次
//. 除了换行\n之外的任意单个字符,
//[abcd...] 匹配[]中任意字符中的一个,可以[a-z]。[^a-z]表示这些子集之外的,^a[a-z]表示a开头的字符
//\d 匹配一个数字 == [0-9]+
//\D 匹配一个非数字== [^0-9]+
//\n 匹配换行符
//\r 匹配回车符
//\t 匹配制表符
//\s 匹配任何空白符
//\S 匹配任何空白非空白符
//\w 匹配大小写a-z以及_任意一个字符
//\W 和\w相反
//$ 结束位置 匹配的字符 "\d$" 末尾是数字
//b 匹配单词边界的位置
//| 是或的意思
} }
十一:1、.net自带的双向链表
static void Main(string[] args)
{
LinkedListNode<string> node1 = new LinkedListNode<string>("字符串值");
LinkedList<string> names = new LinkedList<string>();
names.AddFirst(node1);
LinkedListNode<string> node2=new LinkedListNode<string>("Node2");
names.AddAfter(node1, node2);
names.AddAfter(node1, "传对象");
LinkedListNode<string> node3 = new LinkedListNode<string>("第三、四");
names.AddAfter(node2, node3);
LinkedListNode<string> aNode = names.First;
for(;aNode!=null;aNode=aNode.Next)//遍历
{
Console.WriteLine(aNode.Value);
}
Console.WriteLine("======查找========");
aNode = names.Find("Node2");//查找
if(aNode!=null)
Console.WriteLine(aNode.Value);
}
十二:二叉搜索树BinarySearchTree
class Node
{
public int Data;
public Node Left;
public Node Right;
public void DisplayNode()
{
Console.Write(Data + " ");
}
}
class BinarySearchTree
{
static void Main()
{
BinarySearchTree nums = new BinarySearchTree();
nums.Insert(23);
nums.Insert(45);
nums.Insert(16);
nums.Insert(37);
nums.Insert(3);
nums.Insert(99);
nums.Insert(22);
nums.InOrder(nums.root);
nums.Delete(23);
Console.WriteLine();
nums.InOrder(nums.root);
nums.Delete(99);
Console.WriteLine();
nums.InOrder(nums.root);
nums.Delete(16);
Console.WriteLine();
nums.InOrder(nums.root);
nums.Delete(3);
Console.WriteLine();
nums.InOrder(nums.root);
}
public Node root;
public BinarySearchTree()
{
root = null;
}
public void Insert(int _data)//插入可排序数据
{
Node newNode = new Node();
newNode.Data = _data;
if (root == null)
root = newNode;
else
{
Node current = root;
Node parent;
while(true)
{
parent = current;
if(_data<current.Data)
{
current = current.Left;
if(current==null)
{
parent.Left = newNode;
break;//OK,结束
}
}
else
{
current = current.Right;
if(current==null)
{
parent.Right = newNode;
break;
}
}
}
}
}
public void InOrder(Node theRoot)//中序递归遍历(小到大输出)
{
if(theRoot!=null)
{
InOrder(theRoot.Left);//先输出左边(小)
theRoot.DisplayNode();//再输出自己
InOrder(theRoot.Right);//最后输出右边(大)
}
}
public void PreOrder(Node theRoot)//先序递归遍历
{
if (theRoot != null)
{
theRoot.DisplayNode();//再输出自己
PreOrder(theRoot.Left);//先输出左边(小)
PreOrder(theRoot.Right);//最后输出右边(大)
}
}
public void PostOrder(Node theRoot)//后序递归遍历
{
if (theRoot != null)
{
PostOrder(theRoot.Left);//先输出左边(小)
PostOrder(theRoot.Right);//最后输出右边(大)
theRoot.DisplayNode();//再输出自己
}
}
public int FindMin()//找最小
{
Node current = root;
while (current.Left != null)
current = current.Left;
return current.Data;
}
public int FindMax()
{
Node current = root;
while (current.Right != null)
current = current.Right;
return current.Data;
}
public Node Find(int key)
{
Node current = root;
while(current.Data!=key)
{
if (key < current.Data)
current = current.Left;
else
current = current.Right;
if (current == null)//找完了 没找到
return null;
}
return current;
}
public bool Delete(int key)
{
Node current = root;
Node parent = root;
bool isLeftChild = true;
while(current.Data!=key)
{
parent = current;
if(key<current.Data)
{
isLeftChild = true;//如果被删除节点可能是左节点
current = current.Left;
}
else
{
isLeftChild = false;//如果被删除节点可能是右节点
current = current.Right;
}
if (current == null)//找不到
return false;
}
if((current.Left==null)&& (current.Right==null))//如果要删除的没有任何子节点
{
if (current == root)//如果删除的是root根节点
root = null;
else if (isLeftChild)
parent.Left = null;//如果要删除的是左节点,就丢掉左节点
else
parent.Right = null;//否则丢掉右节点
}
else if(current.Right==null)//如果右边是空的情况下
{
if (current == root)//如果要删除的是root根节点
root = current.Left;
else if (isLeftChild)
parent.Left = current.Left;
}
else if(current.Left==null)//当前节点没有左节点
{
if (current == root)//删除的是跟
root = current.Right;//那就把根的Right赋给自己
else if (isLeftChild == false)//如果不是左边
parent.Right = current.Right;
}
else//重要:要删除的节点有两个子节点
{
Node successor = GetSuccessor(current);//获取继任者
if (current == root)
root = successor;
else if (isLeftChild)//如果被删除节点是上一级的左节点
parent.Left = successor;
else
parent.Right = successor;
successor.Left = current.Left;
}
return true;
}
public Node GetSuccessor(Node delNode)//查找继任者
{
Node successorParent = delNode;//父节点
Node successor = delNode.Right;//先从右边的开始
while(successor.Left!=null)//然后查找左边最小值(与被删除数最接近)
{
successorParent = successor;
successor = successor.Left;
}
if(successor!=delNode.Right)//如果继承被删除节点不是被删除节点的右边第一个
{
successorParent.Left = successor.Right;//继承者的右边交给继承者上一级的左边来保管
successor.Right = delNode.Right;//继承者的右边将保存被删除节点的右边
}
return successor;
}
}
十四:希尔排序SheelStort
public void SheelSort()//希尔排序
{
int inner, temp;
int h = 1;
while(h<=count/3)//跨越次数要小于总数的三分之一
{
h = h * 3 + 1;//计算最大跨越次数
}
for(;h>0;h--)//循环跨越次数次
{
for(int outer=h;outer<count;outer++)//循环 总元素 - 跨越次数 - 1 次
{
temp = arr[outer];
inner = outer;
while((inner+1>h)&&arr[inner-h]>=temp)//+1是因为inner是下标索引,上一个跨越元素大于当前循环的元素
{
arr[inner] = arr[inner - h];//将较大的跨越元素赋值给较小的没跨越元素(里循环是从大的下标循环到小下标)
inner -= h;//继续往左缩小h个坐标
}
arr[inner] = temp;//
}
}
}
十五:最小生成树、深度优先搜索、广度优先搜索、括扑排序
class Vertex
{
public bool wasVisited;//有无访问过
/// <summary>
/// 标签
/// </summary>
public string label;
public Vertex(string lab)
{
label = lab;
wasVisited = false;
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Graph
{
//括扑排序的主要设计点:
//1.用行(row)索引来表示Vertex顶点索引,顶点存储额外信息
//2.用行(row)和列来表示连接路径(Edge边),连接路径的行(row)必须大于列。如(0,1)
//所以添加到栈的时候可以从最后列开始,往上添加
class Graph
{
private int UNM_VERTICES = 6;//图最多存顶点数
private Vertex[] vertices;
private int[,] adjMatrix;//边的临边矩阵
int numVers;//当前顶点数
//===深度优先搜索===========
public void DepthFirstSearch()
{
Stack<int> gStack = new Stack<int>();
vertices[0].wasVisited = true;
gStack.Push(0);//将第一个顶点放入栈
ShowVertex(0);//显示第一个顶点,的label
int v;//顶点序号
while(gStack.Count>0)//如果栈里还有顶点就继续循环
{
v = GetAdjUnvisitedVertex(gStack.Peek());//从最后添加进来的开始找
if(v==-1)
{
gStack.Pop();
}
else
{
vertices[v].wasVisited = true;
ShowVertex(v);
gStack.Push(v);
}
}
for (int j = 0; j < UNM_VERTICES; j++)
vertices[0].wasVisited = false;
}
private int GetAdjUnvisitedVertex(int v)//获取某个顶点相邻的未访问过的顶点
{
for(int j=0;j<UNM_VERTICES;j++)
{
if(adjMatrix[v,j]==1&&vertices[j].wasVisited==false)//由于要求某行的的wasVisited为false才执行。所以某行只会被索检一遍
{
return j;//返回某个还有边没被访问的顶点
}
}
return -1;
}
//======================
//=====广度优先搜索============
public void BreadthFirstSearch()
{
Queue<int> gQueue = new Queue<int>();
vertices[0].wasVisited = true;
ShowVertex(0);
gQueue.Enqueue(0);
int vert1, vert2;
while(gQueue.Count>0)
{
vert1 = gQueue.Dequeue();//返回并删除最先加进来的对象
vert2 = GetAdjUnvisitedVertex(vert1);//找未访问的顶点
while(vert2!=-1)
{
vertices[vert2].wasVisited = true;
ShowVertex(vert2);
gQueue.Enqueue(vert2);//添加到先进先出队列里
vert2 = GetAdjUnvisitedVertex(vert1);
}
}
for (int j = 0; j < UNM_VERTICES; j++)
vertices[0].wasVisited = false;
}
//==========================
//=======最小生成树算法==========
public void Mst()
{
Stack<int> gStack = new Stack<int>();
vertices[0].wasVisited = true;
gStack.Push(0);
int currVertex, ver;
while(gStack.Count>0)
{
currVertex = gStack.Peek();
ver = GetAdjUnvisitedVertex(currVertex);
if(ver==-1)
{
gStack.Pop();
}
else
{
vertices[ver].wasVisited = true;
gStack.Push(ver);
Console.Write(vertices[currVertex].label);
Console.Write(vertices[ver].label);
Console.Write(" ");
}
}
for (int j = 0; j < UNM_VERTICES; j++)
vertices[0].wasVisited = false;
}
//==========================
static void Main()
{
Graph aGraph = new Graph(13);
aGraph.AddVertex("A");
aGraph.AddVertex("B");
aGraph.AddVertex("C");
aGraph.AddVertex("D");
aGraph.AddVertex("E");
aGraph.AddVertex("F");
aGraph.AddVertex("G");
aGraph.AddEdge(0, 1);
aGraph.AddEdge(0,2);
aGraph.AddEdge(0,3);
aGraph.AddEdge(1,2);
aGraph.AddEdge(1,3);
aGraph.AddEdge(1,4);
aGraph.AddEdge(2,3);
aGraph.AddEdge(2,5);
aGraph.AddEdge(3,5);
aGraph.AddEdge(3,4);
aGraph.AddEdge(3,6);
aGraph.AddEdge(4,5);
aGraph.AddEdge(4,6);
aGraph.AddEdge(5,6);
aGraph.Mst();//最小生成树
Console.Read();
//aGraph.AddVertex("A");
//aGraph.AddVertex("B");
//aGraph.AddVertex("C");
//aGraph.AddVertex("D");
//aGraph.AddVertex("E");
//aGraph.AddVertex("F");
//aGraph.AddVertex("G");
//aGraph.AddVertex("H");
//aGraph.AddVertex("I");
//aGraph.AddVertex("J");
//aGraph.AddVertex("K");
//aGraph.AddVertex("L");
//aGraph.AddVertex("M");
//aGraph.AddEdge(0, 1);//AB
//aGraph.AddEdge(1,2);//BC
//aGraph.AddEdge(2, 3);//CD
//aGraph.AddEdge(0, 4);//AE
//aGraph.AddEdge(4, 5);//EF
//aGraph.AddEdge(5, 6);//FG
//aGraph.AddEdge(0, 7);//AH
//aGraph.AddEdge(7, 8);//
//aGraph.AddEdge(8, 9);//
//aGraph.AddEdge(0, 10);//AK
//aGraph.AddEdge(10, 11);//
//aGraph.AddEdge(11, 12);//
// aGraph.DepthFirstSearch();//深度优先搜索
//aGraph.BreadthFirstSearch();//广度优先搜索
//Graph theGraph = new Graph(4);//括扑排序
//theGraph.AddVertex("A");//0
//theGraph.AddVertex("B");//1
//theGraph.AddVertex("C");//2
//theGraph.AddVertex("D");//3
//theGraph.AddEdge(0, 1);
//theGraph.AddEdge(1, 2);
//theGraph.AddEdge(2, 3);
//theGraph.TopSort();
}
public Graph(int numvertices)
{
UNM_VERTICES = numvertices;
vertices = new Vertex[UNM_VERTICES];
adjMatrix = new int[UNM_VERTICES, UNM_VERTICES];
numVers = 0;
for(int outer=0;outer<UNM_VERTICES ;outer++)
{
for(int inner=0;inner<UNM_VERTICES;inner++)
{
adjMatrix[outer, inner] = 0;
}
}
}
public void AddVertex(string label)
{
vertices[numVers] = new Vertex(label);
numVers++;
}
public void ShowVertex(int v)
{
Console.Write(vertices[v].label + " ");
}
public void AddEdge(int start,int end)//添加边
{
adjMatrix[start, end] = 1;//表示表示第几行的第几列拥有边
}
public void TopSort()//括扑排序
{
Stack<string> gStack = new Stack<string>();
while(UNM_VERTICES>0)
{
int currVertex = NoSuccessors();
if(currVertex==-1)
{
Console.WriteLine("Error:图没有找到后继顶点");
return;
}
gStack.Push(vertices[currVertex].label);
DelVertex(currVertex);
}
Console.WriteLine("括扑排序的结果:");
while(gStack.Count>0)
{
Console.Write(gStack.Pop() + " ");
}
}
public int NoSuccessors()//查找无后续顶点的顶点
{
bool isEdge;
for(int row=0;row<UNM_VERTICES;row++)
{
isEdge = false;
for(int col=0;col<UNM_VERTICES;col++)
{
if(adjMatrix[row,col]>0)//有后继顶点
{
isEdge = true;
break;
}
}
if (isEdge == false)//说明这被当前顶点数限制列的行没有大于0的边,找到后继顶点。添加到栈中
return row;
}
return -1;
}
public void DelVertex(int vert)//要删除的顶点,从0开始
{
if(vert!=UNM_VERTICES-1)//如果删除的不是最后一行
{
for(int j=vert;j<UNM_VERTICES-1;j++)//从要删除的顶点开始往前移
{
vertices[j] = vertices[j + 1];
}
for(int row=vert;row<UNM_VERTICES-1;row++)
{
MoveRow(row, UNM_VERTICES);//将某一往抛弃,这一行的下一行将往上移动一行
}
for(int col=vert;col<UNM_VERTICES-1;col++)
{
MoveCol(col, UNM_VERTICES);
}
}
UNM_VERTICES--;//直接删除最后一行
}
public void MoveRow(int row,int length)//
{
for(int col=0;col<=length;col++)
{
adjMatrix[row, col] = adjMatrix[row + 1, col];//将某一往抛弃,这一行的下一行将往上移动一行
}
}
public void MoveCol(int col,int length)
{
for(int row=0;row<length;row++)
{
adjMatrix[row, col] = adjMatrix[row, col + 1];//将某一列抛弃,这一列的右一列将往左移动一列
}
}
}
}
十六:最短路径
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Graph
{
class Graph
{
private int[,] adjMatrix;//边的领接矩阵
private const int max_verts = 20;
int startToCurrent;
int currentVert;
/// <summary>
/// 最大值,表示未连接
/// </summary>
int infinity = 100000;
Vertex[] vertexList;
/// <summary>
/// 图里面加了几个顶点
/// </summary>
int nVerts;
/// <summary>
/// 加到树VertexList里几个顶点
/// </summary>
int nTree;
/// <summary>
/// 最短路径
/// </summary>
DistOriginal[] sPath;
//======================
static void Main()
{
Graph aGraph = new Graph();
aGraph.AddVertex("A");
aGraph.AddVertex("B");
aGraph.AddVertex("C");
aGraph.AddVertex("D");
aGraph.AddVertex("E");
aGraph.AddVertex("F");
aGraph.AddVertex("G");
aGraph.AddEdge(0, 1, 2);
aGraph.AddEdge(0, 3, 1);
aGraph.AddEdge(1, 3, 3);
aGraph.AddEdge(1, 4, 10);
aGraph.AddEdge(2, 5, 5);
aGraph.AddEdge(2, 0, 4);
aGraph.AddEdge(3, 2, 2);
aGraph.AddEdge(3, 5, 8);
aGraph.AddEdge(3, 4, 2);
aGraph.AddEdge(3, 6, 4);
aGraph.AddEdge(4, 6, 6);
aGraph.AddEdge(6, 5, 1);
aGraph.Path();
Console.Read();
}
public Graph()
{
vertexList = new Vertex[max_verts];
adjMatrix = new int[max_verts, max_verts];
nVerts = 0;
nTree = 0;
for(int outer=0;outer<max_verts ;outer++)
{
for (int inner = 0; inner < max_verts; inner++)
{
adjMatrix[outer, inner] = infinity;//对边长初始化,为最大值
}
}
sPath = new DistOriginal[max_verts];
}
public void Path()//路径计算
{
int startTree = 0;//从第一个顶点开始
vertexList[startTree].isInTree = true;//是否访问过
nTree = 1;//树里有几个顶点vertexList
for(int j=0;j<=nVerts;j++)//记录第一个顶点到其余所有顶点的距离。存储在sPath[]里
{
int tempDist = adjMatrix[startTree, j];//从领接矩阵中取取边长
sPath[j] = new DistOriginal(startTree, tempDist);
}
while(nTree<nVerts)//加到树VertexList顶点数<已添加的定点数
{
int indexMin = GetMin();//重新获取sPath剩余的最小顶点
int minDist = sPath[indexMin].distance;
currentVert = indexMin;
startToCurrent = sPath[indexMin].distance;//第一个顶点到当前顶点的最小距离
vertexList[currentVert].isInTree = true;//加到树里vertexList.意思是,最小的边
nTree++;//
AdjustShortPath();//最新最短路径
}
DisplayPaths();
nTree = 0;
for (int j = 0; j <= nVerts - 1; j++)
vertexList[j].isInTree = false;
}
void DisplayPaths()
{
for(int j=0;j<=nVerts-1;j++)
{
Console.Write(vertexList[j].label + "=");
if (sPath[j].distance == infinity)
Console.Write("inf");
else
Console.Write(sPath[j].distance);
string parent = vertexList[sPath[j].parentVert].label;
Console.Write("(" + parent + ") ");
}
}
public void AdjustShortPath()//调整最新最短路径
{
int column = 1;//列
while (column < nVerts)
if (vertexList[column].isInTree)//不循环自身、或已循环过的更优距离顶点
column++;
else//没有访问过该顶点
{
int currentToFring = adjMatrix[currentVert, column];//currentVert是最短顶点,最小路径那行的每列的距离
int startToFringe = startToCurrent + currentToFring;//第一个顶点到最短距离的顶点的距离+最短顶点到后面顶点的距离
int sPathDist = sPath[column].distance;//第一个顶点到某个顶点的距离
if(startToFringe<sPathDist)//第一个顶点到其他顶点的最短距离+最短顶点到某个顶点的距离 < 第一个顶点到某个顶点的距离
{
sPath[column].parentVert = currentVert;//设置上一个顶点的距离为第一个顶点到某个定点的最短距离
sPath[column].distance = startToFringe;//距离为:两个最短距离相加
}
column++;
}
}
public int GetMin()//获取最小路径
{
int minDist = infinity;//最小距离
int indexMin = 0;//最小顶点索引
for(int j=1;j<=nVerts-1;j++)//循环遍历,找第一个顶点(A)到其他顶点最短的一个顶点。并返回
{
if(!(vertexList[j].isInTree)&& sPath[j].distance<minDist)
{
minDist = sPath[j].distance;
indexMin = j;
}
}
return indexMin;//返回第一个顶点到其余顶点最短的顶点索引
}
public void AddVertex(string label)
{
vertexList[nVerts] = new Vertex(label);
nVerts++;
}
public void AddEdge(int start,int end,int weight)//添加边
{
adjMatrix[start, end] = weight;//表示某个顶点到另一个顶点的权重(长度距离)
}
}
}