#include
#include
#include
using namespace std;
template<class T>
class BinaryTreeNode
{
template<class T> friend class BinaryTree;
public:
BinaryTreeNode() { LeftChild = RightChild = NULL; };
BinaryTreeNode(const T & data) { this->data = data; LeftChild = RightChild = NULL; };
BinaryTreeNode(const T & data, BinaryTreeNode* l, BinaryTreeNode* r) { this->data = data; LeftChild = l; RightChild = r; };
private:
T data;
BinaryTreeNode *LeftChild;
BinaryTreeNode *RightChild;
};
template<class T>
class BinaryTree
{
public:
BinaryTreeNode<T> *root;
BinaryTree() { root = 0; _count = 0; };
~BinaryTree() {};
void MakeTreeByLevelOrder(const char* levelOrder, const int length);
void MakeTreeByPreOrderAndInOrder(const char* preOrder, const char* inOrder, const int length);
void MakeTreeByPreOrderAndInOrder(BinaryTreeNode<T>& t, const char* preOrder,int p1,int p2, const char* inOrder,int i1,int i2);
int Height()const { return Height(root); }
int NodeNumber(BinaryTreeNode<T> *x) {
if (x) {
_count++; //把visit一个节点改成节点数加一
NodeNumber(x->LeftChild);
NodeNumber(x->RightChild);
}
return _count;
}
void visit(BinaryTreeNode<T> *x) { if (x->data != NULL) { cout << x->data; cout << ","; } }
void levelOrder(BinaryTreeNode<T> *t) //层次遍历
{
queue<BinaryTreeNode<T>*> Q;
while (t)
{
visit(t); //访问t并将t的左右孩子放入队列
if (t->LeftChild) Q.push(t->LeftChild);
if (t->RightChild) Q.push(t->RightChild);
if (!Q.empty()) {
t = Q.front();
Q.pop(); //访问下一个节点 此时t被赋为了队列的第一个元素
}
else
{
return;
}
}
}
void preOrder(BinaryTreeNode<T> *t) //前序遍历
{
if (t)
{
visit(t);
preOrder(t->LeftChild);
preOrder(t->RightChild);
}
}
void inOrder(BinaryTreeNode<T> *t) //中序遍历
{
if (t != NULL)
{
inOrder(t->LeftChild);
visit(t);
inOrder(t->RightChild);
}
}
void postOrder(BinaryTreeNode<T> *t) //后序遍历
{
if (t != NULL)
{
postOrder(t->LeftChild);
postOrder(t->RightChild);
visit(t);
}
}
private:
int _count;
int Height(BinaryTreeNode<T>*t)const;
};
template<class T>
void BinaryTree<T>::MakeTreeByLevelOrder(const char* levelOrder, const int length)
{
queue<BinaryTreeNode<T>*> queue; //运用队列处理左右节点
for (int i = 0; i < length; i++)
{
if (i == 0) //root根的处理 树根的初始化
{
switch (length)
{
case 1:
root = new BinaryTreeNode<T>(levelOrder[0]);
break;
case 2:
root = new BinaryTreeNode<T>(levelOrder[0], new BinaryTreeNode<T>(levelOrder[1]),NULL);
break;
case 3:
root = new BinaryTreeNode<T>(levelOrder[0], new BinaryTreeNode<T>(levelOrder[1]), new BinaryTreeNode<T>(levelOrder[2]));
break;
default:
root = new BinaryTreeNode<T>(levelOrder[0], new BinaryTreeNode<T>(levelOrder[1]), new BinaryTreeNode<T>(levelOrder[2]));
queue.push(root->LeftChild);
queue.push(root->RightChild);
break;
}
}
else //不为根节点时
{
if (2 * i + 2 <= length-1) //如果当前节点有右孩子
{
queue.front()->LeftChild = new BinaryTreeNode<T>(levelOrder[2 * i + 1]);
queue.front()->RightChild = new BinaryTreeNode<T>(levelOrder[2 * i + 2]);
queue.push(queue.front()->LeftChild);
queue.push(queue.front()->RightChild);
queue.pop();
}
if (2 * i + 2 > length-1 && 2 * i + 1 <= length-1) //如果当前节点 没有右孩子且 有左孩子
{
queue.front()->LeftChild = new BinaryTreeNode<T>(levelOrder[2 * i + 1]);
queue.pop();
}
}
}
}
template<class T>
void BinaryTree<T>::MakeTreeByPreOrderAndInOrder(const char* preOrder, const char* inOrder, const int length)
{
root = new BinaryTreeNode<T>();
MakeTreeByPreOrderAndInOrder(*root, preOrder, 0, length - 1, inOrder, 0, length - 1);
}
template<class T>
void BinaryTree<T>::MakeTreeByPreOrderAndInOrder(BinaryTreeNode<T>& t, const char * preOrder, int p1, int p2, const char * inOrder, int i1, int i2)
{
//i1为inOrder的开头,p1为preOrder的开头,i2p2分别为结尾
t.data = preOrder[p1];
t.LeftChild = t.RightChild = NULL; //根的构建
int current = i1; //从中序i1处 声明current位置
while (inOrder[current] != preOrder[p1]) //用current记录与前序p1位置相同数的位置
current++;
int length = current - i1; //记录current根左子树的长度
if (current > i1) { //如果current有左子树就新建他的LeftChild并且用递归
t.LeftChild = new BinaryTreeNode<T>();
MakeTreeByPreOrderAndInOrder(*(t.LeftChild), preOrder, p1 + 1, p1 + length, inOrder, i1, current - 1);//inOrder的左树
}
if (current < i2) {
t.RightChild = new BinaryTreeNode<T>(); //如果current有右子树就新建他的RightChild并且用递归
MakeTreeByPreOrderAndInOrder(*(t.RightChild), preOrder, p1 + length + 1, p2, inOrder, current + 1, i2);//inOrder的右树
}
}
template<class T>
int BinaryTree<T>::Height(BinaryTreeNode<T>* t) const
{
if (!t) return 0;
int heightOfLeft = Height(t->LeftChild);
int heightOfRight = Height(t->RightChild);
if (heightOfLeft > heightOfRight)
{
return ++heightOfLeft;
}
else
{
return ++heightOfRight;
}
}
int main() {
cout << "Input1" << endl;
string levelOrderString;
cin >> levelOrderString;
const char*levelOrder = levelOrderString.c_str();
BinaryTree<char>*a = new BinaryTree<char>();
a->MakeTreeByLevelOrder(levelOrder, levelOrderString.length());
cout << "Output1" << endl;
a->preOrder(a->root);
cout << endl;
a->inOrder(a->root);
cout << endl;
a->postOrder(a->root);
cout << endl;
cout<< a->NodeNumber(a->root)<<endl;
cout << a->Height() << endl;
cout << "Input2" << endl;
string preOrderString;
cin >> preOrderString;
const char*preOrder = preOrderString.c_str();
string inOrderString;
cin >> inOrderString;
const char*inOrder = inOrderString.c_str();
BinaryTree<char>*b = new BinaryTree<char>();
b->MakeTreeByPreOrderAndInOrder(preOrder, inOrder, preOrderString.length());
cout << "Output2" << endl;
b->postOrder(b->root);
cout << endl;
b->levelOrder(b->root);
cout << endl;
cout << "End" << endl;
system("pause");
}
①、前五题运用最大堆及堆排序、最后一题运用最小堆生成霍夫曼树,运用递归实现霍夫曼编码的输出。
②、采用数组的形式实现最大堆,从2分之数组大小处向前依次移动,通过position不断*2来比较此时节点与其子节点中最大的一个数的大小,如果比其子节点中最大的一个数还大那么就不动,否则就把大孩子覆盖到该节点处,该节点下移到其子节点位置接着向下2*position处重复比较。
③、堆排序用不断删除堆顶最大元素在for循环中i--进行从小到大的排序。
④、构造二叉搜索树通过依次加入数据从root节点依次向下比较,小的放左面大的放右面。
⑤、首先按构造最大堆的方式构造最小堆,然后定义霍夫曼类 其中有生成霍夫曼编码的方法,与私有变量一个霍夫曼树节点 一个权重。另外单独一个生成霍夫曼树的方法,其中先声明一个霍夫曼类型的数组,其中的权重与霍夫曼节点全部赋值,霍夫曼节点的data为ABCD...符号 权重为输入的数据。
再定义一个存霍夫曼类型的最小堆,通过其权重进行排序,每次取权重最小的两个生成一个霍夫曼类,其data为0,权重为两节点相加,生成后再插入最小堆中,然后不断进行取两个生成一个的操作,直到最后返回剩下的最后一个节点,即为生成好的霍夫曼树的根节点。
⑥、霍夫曼编码通过递归,不断从根节点遍历到每个叶子节点,其中向左走字符串+0,向右走字符串+1,最后输出每个符号的霍夫曼编码。
#include
#include
#include
using namespace std;
template<class T>
class MaxHeap
{
public:
MaxHeap() {
currentSize = 0; //数组中从1开始
}
int Size()const { return currentSize; }
void creat(T a[], int size);
void outputByLevelOrder();
MaxHeap<T>& DeleteMax(T &x);
void HeapSort(int size);
T *heap;
private:
int maxSize=20;
int currentSize;
};
template<class T>
void MaxHeap<T>::creat(T a[], int size)
{
heap = a;
currentSize = size;
for (int i = currentSize/2; i >= 1; i--)
{
T rootOfChild = heap[i];//记录子树的根的值
int position = 2 * i; //子树根如果移动的话应该在的位置
while (position<=currentSize)
{
if (position
{
position++; //position指到右孩子的位置 否则position还在左孩子位置
}
if (rootOfChild >= heap[position]) //如果此时子树根大于两孩子中最大的一个跳出循环 位置不变
{
break;
}
heap[position / 2] = heap[position]; //否则 孩子中最大的内个覆盖子树根位置的值
position *= 2; //再把position指到内个大孩子的左子树根处 重复循环
}
heap[position / 2] = rootOfChild;
}
}
template<class T>
void MaxHeap<T>::outputByLevelOrder()
{
for (int i = 1; i <=currentSize; i++)
{
cout << heap[i];
if (i!=currentSize)
{
cout << ",";
}
else
{
cout << endl;
}
}
}
template<class T>
MaxHeap<T>& MaxHeap<T>::DeleteMax(T & x) //将最大元素放入x,并从堆中删除最大元素
{
if (currentSize == 0) //如果堆为空返回
return *this;
x = heap[1];
T y = heap[currentSize--];//保存最后一个元素
int i = 1; //堆的当前节点
int position = 2;
while (position <= currentSize) {
if (position
position++; //position指到右孩子的位置 否则position还在左孩子位置
if (y >= heap[position]) //如果此时最后一个元素大于当前节点两孩子中最大的一个跳出循环
break;
heap[i] = heap[position]; //否则 孩子中最大的内个覆盖子树根位置的值
i = position;
position *=2; //再把position指到内个大孩子的左子树根处 重复循环
}
heap[i] = y; //把最后一个元素放到i处
return *this;
}
template<class T>
void MaxHeap<T>::HeapSort(int size)
{
T x;
for (int i =size; i >=1 ; i--) //对当前堆进行最大堆排序
{
this->DeleteMax(x);
this->heap[i] = x;
}
for (int i = 1; i <= size; i++) //输出最大堆排序后的结果
{
cout << heap[i];
if (i != size)
{
cout << ",";
}
else
{
cout << endl;
}
}
}
template<class T>
class BinaryTreeNode
{
friend class Huffman;
template<class T> friend class BinaryTree;
public:
BinaryTreeNode() { LeftChild = RightChild = NULL; };
BinaryTreeNode(const T & data) { this->data = data; LeftChild = RightChild = NULL; };
BinaryTreeNode(const T & data, BinaryTreeNode* l, BinaryTreeNode* r) { this->data = data; LeftChild = l; RightChild = r; };
private:
T data;
BinaryTreeNode *LeftChild;
BinaryTreeNode *RightChild;
};
template<class T>
class BinaryTree
{
public:
BinaryTreeNode<T> *root;
BinaryTree() { root = 0;};
~BinaryTree() {};
void visit(BinaryTreeNode<T> *x) { if (x->data != NULL) { cout << x->data; cout << ","; } }
BinaryTree<T> makeSearchTree(const T &e);
void levelOrder(BinaryTreeNode<T> *t) //层次遍历
{
queue<BinaryTreeNode<T>*> Q;
while (t)
{
visit(t); //访问t并将t的左右孩子放入队列
if (t->LeftChild) Q.push(t->LeftChild);
if (t->RightChild) Q.push(t->RightChild);
if (!Q.empty()) {
t = Q.front();
Q.pop(); //访问下一个节点 此时t被赋为了队列的第一个元素
}
else
{
return;
}
}
}
void preOrder(BinaryTreeNode<T> *t) //前序遍历
{
if (t)
{
visit(t);
preOrder(t->LeftChild);
preOrder(t->RightChild);
}
}
void inOrder(BinaryTreeNode<T> *t) //中序遍历
{
if (t != NULL)
{
inOrder(t->LeftChild);
visit(t);
inOrder(t->RightChild);
}
}
private:
};
template<class T>
BinaryTree<T> BinaryTree<T>::makeSearchTree(const T &e)
{
BinaryTreeNode<T> *current = root;
BinaryTreeNode<T> *before = 0;
while (current)
{
before = current; //记录应该插入到谁的后面 由于current最后为null 所以要跟一个
if (e < current->data) current = current->LeftChild;
else if (e > current->data) current = current->RightChild;
}
BinaryTreeNode<T> *element = new BinaryTreeNode<T>(e);
if (root)
{
if (e < before->data) before->LeftChild = element;
else before->RightChild = element;
}
else
{
root = element;
}
return *this;
}
template<class T>
class MinHeap
{
public:
MinHeap() {
currentSize = 0; //数组中从1开始
}
int Size()const { return currentSize; }
void creat(T a[], int size);
void outputByLevelOrder()
{
for (int i = 1; i <= currentSize; i++)
{
cout << heap[i];
if (i != currentSize)
{
cout << ",";
}
else
{
cout << endl;
}
}
}
MinHeap<T>& Insert(const T&x);
MinHeap<T>& DeleteMin(T &x);
T *heap;
private:
int maxSize = 20;
int currentSize;
};
template<class T>
void MinHeap<T>::creat(T a[], int size)
{
heap = a;
currentSize = size;
for (int i = currentSize / 2; i >= 1; i--)
{
T rootOfChild = heap[i];//记录子树的根的值
int position = 2 * i; //子树根如果移动的话应该在的位置
while (position <= currentSize)
{
if (position
{
position++; //position指到右孩子的位置 否则position还在左孩子位置
}
if (rootOfChild < heap[position]) //如果此时子树根小于两孩子中最小的一个跳出循环 位置不变
{
break;
}
heap[position / 2] = heap[position]; //否则 孩子中最小的内个覆盖子树根位置的值
position *= 2; //再把position指到内个小孩子的左子树根处 重复循环
}
heap[position / 2] = rootOfChild;
}
}
template<class T>
MinHeap<T>& MinHeap<T>::Insert(const T & x)
{
if (currentSize == maxSize)
return *this;
currentSize++;
int position = currentSize;
while (position>1)
{
if (x>=heap[position/2])
{
heap[position] = x;
break;
}
heap[position] = heap[position/ 2]; //下移父节点
position = position / 2;
}
heap[position] = x;
return *this;
}
template<class T>
MinHeap<T>& MinHeap<T>::DeleteMin(T & x) //将最大元素放入x,并从堆中删除最大元素
{
if (currentSize == 0) //如果堆为空返回
return *this;
x = heap[1];
int last = currentSize;
T y = heap[last];//保存最后一个元素
int i = 1; //堆的当前节点
int position = 2;
while (position <= currentSize) {
if (position
position++; //position指到右孩子的位置 否则position还在左孩子位置
if (y <= heap[position]) //如果此时最后一个元素小于当前节点两孩子中最大的一个跳出循环
break;
heap[i] = heap[position]; //否则 孩子中最大的内个覆盖子树根位置的值
i = position;
position *= 2; //再把position指到内个大孩子的左子树根处 重复循环
}
heap[i] = y; //把最后一个元素放到i处
currentSize--;
return *this;
}
int number = 0;
string *huffmancode1 = new string[20];
class Huffman
{
friend BinaryTree<char> HuffmanTree(int[], int);
public:
operator int()const { return weight; }
void HuffmanCode(BinaryTree<char> HuffmanTree, string code) {
BinaryTreeNode<char> *t;
BinaryTree<char> Left, Right;
t = HuffmanTree.root;
if (!t->LeftChild && !t->RightChild) {
int symbolposition = t->data - 'A';
huffmancode1[symbolposition] = code;
number++;
}else{
if (t->LeftChild)
{
Left.root = t->LeftChild;
HuffmanCode(Left, code+"0");
}
if (t->RightChild)
{
Right.root = t->RightChild;
HuffmanCode(Right, code+"1");
}
}
}
private:
BinaryTreeNode<char> *HuffmanTreeNode;
int weight;
};
BinaryTree<char> HuffmanTree(int a[], int n) {
Huffman *w = new Huffman[n+1]; //底下从1开始
char symbol = 'A';
for (int i = 1; i <=n; i++)
{
w[i].weight = a[i];
w[i].HuffmanTreeNode = new BinaryTreeNode<char>(symbol);
symbol++;
}
MinHeap<Huffman>minheap;
minheap.creat(w, n);
Huffman x, y;
for (int i = 1; i < n; i++)
{
minheap.DeleteMin(x);
minheap.DeleteMin(y);
BinaryTreeNode<char> *z = new BinaryTreeNode<char>(0,x.HuffmanTreeNode,y.HuffmanTreeNode);
x.weight += y.weight;
x.HuffmanTreeNode = z;
minheap.Insert(x);
}
minheap.DeleteMin(x);
BinaryTree<char> huffmantree;
huffmantree.root = x.HuffmanTreeNode;
return huffmantree;
}
int main(){
cout << "Input1" << endl;
int array[21]; //创建一个最多可输入20个数的数组
int array2[21];
int n, m; //n为当前输入的数据
for (int i = 1; i <= 21; i++)
{
cin >> n;
if (n == 0) {
m = i - 1; //m为了记住0前一共输入了几个数 由于array【0】没有数据 故-1
break;
}
if (i==21)
{
array[i] = n;
array2[i] = n;
break;
}
array[i] = n;
array2[i] = n;
}
MaxHeap<int> *a = new MaxHeap<int>();
a->creat(array, m);
cout << "Output" << endl;
a->outputByLevelOrder();
a->HeapSort(m);
BinaryTree<int> *searchTree = new BinaryTree<int>();
for (int i = 1; i <= m; i++)
{
searchTree->makeSearchTree(array2[i]);
}
searchTree->preOrder(searchTree->root);
cout << endl;
searchTree->inOrder(searchTree->root);
cout << endl;
Huffman *c = new Huffman();
c->HuffmanCode(HuffmanTree(array2, m), "");
for (int i = 0; i < number; i++)
{
char symbol = 'A'+i;
cout << symbol << ":" << huffmancode1[i];
if (i < number-1){ cout << ","; } else { cout << endl; }
}
cout << "End" << endl;
system("pause");
return 0;
}
#include
#include
#include
using namespace std;
template<class T>
void Make2DArray(T** &x, int numberOfRows, int numberOfColumns)
{
x = new T *[numberOfColumns];
for (int i = 0; i < numberOfRows; i++)
{
x[i] = new T[numberOfColumns];
}
}
template<class T>
void Delete2DArray(T ** &x, int numberOfRows)
{
for (int i = 0; i < numberOfRows; i++)
{
delete[] x[i];
}
delete[] x;
x = NULL;
}
template<class T>
class AdjacencyWDigraph { //加权无向图的耗费邻接矩阵
public:
AdjacencyWDigraph(int Vertices = 10, T noEdge = 0);
~AdjacencyWDigraph() { Delete2DArray(a, n + 1); }
bool Exist(int i, int j)const;
AdjacencyWDigraph<T>& Add(int i, int j, const T& w);
AdjacencyWDigraph<T>& Delete(int i, int j);
void BFS(int v, int reach[], int label); //广度优先
void DFS(int v, int reach[], int label); //深度优先
bool findPath(int v, int w,int reach[], int label);
int findTheShortestPath(int begin, int end); //迪克斯特拉算法找最短路径
void Prim(int n, int **c);
int Begin(int i);
T** getA() { return a; } //get方法获取私有成员变量a
int NextVertex(int i) {
//返回下一个与i邻接的顶点
if (i<1 || i>n) return 0;
for (int j = pos[i] + 1; j <= n; j++)
if (a[i][j] != NoEdge) {
pos[i] = j;
return j;
}
pos[i] = n + 1;
return 0;
}
private:
T NoEdge;//用于没有边存在的情形
int n;//顶点数目
int e;//边数
T **a;//二维数组
int *pos;//记录每个顶点的邻接顶点
};
template<class T>
AdjacencyWDigraph<T>::AdjacencyWDigraph(int Vertices, T noEdge)
{ // 构造函数
n = Vertices;
e = 0;
NoEdge = noEdge;
Make2DArray(a, n + 1, n + 1);//程序1-13
pos = new int[n + 1];
for (int i = 1; i <= n; i++)
pos[i] = 0;
//初始化为没有边的图
for (int i = 1; i <= n; i++)
for (int j = 1; j <= n; j++)
a[i][j] = NoEdge;
}
template<class T>
bool AdjacencyWDigraph<T>::Exist(int i, int j) const
{// 边(i, j)是否存在
if (i<1 || j<1 || i>n || j>n || a[i][j] == NoEdge) return false;
return true;
}
template<class T>
AdjacencyWDigraph<T>& AdjacencyWDigraph<T> ::Add(int i, int j, const T& w)
{// 如果边(i,j) 不存在,则将该边加入无向图中
if (i<1 || j<1 || i>n || j>n || i == j || a[i][j] != NoEdge)
return *this;
a[i][j] = w;
a[j][i] = w;
e++;
return *this;
}
template<class T>
AdjacencyWDigraph<T>& AdjacencyWDigraph<T> ::Delete(int i, int j)
{
/ /删除边(i, j) .
if (i<1 || j<1 || i>n || j>n || a[i][j] == NoEdge)
return *this;
a[i][j] = NoEdge;
e--;
return *this;
}
class OutofBounds : exception {
public: OutofBounds() {};
};
template<class T>
int AdjacencyWDigraph<T>::Begin(int i) {
//返回第一个与i邻接的顶点
if (i<1 || i>n) throw OutofBounds();
for (int j = 1; j <= n; j++){
if (a[i][j] != NoEdge) {
pos[i] = j;
return j;
}
}
pos[i] = n + 1;//没有下一个顶点
return 0;
}
template<class T>
void AdjacencyWDigraph<T>::BFS(int v, int reach[], int label)
{
//宽度优先搜索
queue<int> Q;
reach[v] = label;
Q.push(v);
cout << v << ",";
while (!Q.empty()) {
int w = Q.front();
Q.pop();//获取一个已经标记的顶点
//对邻接的顶点进行标记
for (int i = 1; i <= n; i++)
if (a[w][i] != NoEdge&&reach[i] != label) {
Q.push(i);
cout << i;
if (i!=n)
{
cout << ",";
}
reach[i] = label;
}
}
}
template<class T>
void AdjacencyWDigraph<T>::DFS(int v, int reach[], int label)
{
reach[v] = label;
cout << v <<",";
int u = Begin(v);
while (u) {
if (reach[u] != label)
DFS(u, reach, label);
u = NextVertex(v);
}
}
template<class T>
bool AdjacencyWDigraph<T>::findPath(int v, int w, int reach[], int label)
{// 实际搜索v到w的路径,其中v != w.// 按深度优先方式搜索一条路径
reach[v] = label;
int u = Begin(v);
while (u) {
if (reach[u]!= label) {
if (u == w) return true;
if (findPath(u, w,reach, label))
return true;
} u = NextVertex(v);
} return false;
}
int findMIN(int a[],int length) {
int min = a[0];
int positionOfMin = 0;
for (int i = 1; i <=length; i++)
{
if (a[i] <= min) {
min = a[i];
positionOfMin = i;
}
}
return positionOfMin;
}
template<class T>
int AdjacencyWDigraph<T>::findTheShortestPath(int begin, int end) //实现Dijkstra算法
{
const int MAX = 9999;
const int Label = 999;
int *Dijkstra = new int [end +1];
int weightOfPath=0;
int positionOfMin = 0;
for (int i = 0; i < end + 1; i++) //初始化保存路径数组 使数据全为-1
{
Dijkstra[i] = MAX;
}
Dijkstra[begin] = 0;
int *reach = new int [end+1];
if (findPath(begin,end,reach, Label)) //如果存在从begin 到end 的通路
{
while (Dijkstra[end] != Label)
{
positionOfMin = findMIN(Dijkstra, end);
weightOfPath = Dijkstra[positionOfMin];
Dijkstra[positionOfMin] = Label;
for (int i = 1; i <end + 1; i++)
{
if (Dijkstra[i] != Label&&a[positionOfMin][i] != NoEdge&&a[positionOfMin][i] + weightOfPath < Dijkstra[i]) //如果没走过 且 其上一步走到的地方的临边存在 且 它的值加上之前走过的比直接到此处路途更短 就更新一遍表
{
Dijkstra[i] = a[positionOfMin][i] + weightOfPath;
}
}
}
}
return weightOfPath;
}
template<class T>
void AdjacencyWDigraph<T>::Prim(int n, int **graph) //Prim算法从节点1开始实现最小生成树
{
int *lowcost= new int[n+1]; //以i为终点的边的最小权值当lowcost[i]=0说明以i为终点的边的最小权值=0,也就是表示i点加入了MST
int *mst= new int[n+1]; //mst[i]:表示对应lowcost[i]的起点,即说明边
int i, j, min, minid;
for (i = 2; i <= n; i++)
{
lowcost[i] = graph[1][i];
if(lowcost[i]!=0)
mst[i] = 1;
else mst[i] = 0;
}
lowcost[1] = 0;
mst[1] = 0;
int begin = 1;
int end = n;
int *reach = new int[end + 1];
int Label = 999;
if (findPath(begin, end, reach, Label)) {
for (i = 2; i <= n; i++)
{
min = 999999;
minid = 0;
for (j = 2; j <= n; j++)
{
if (lowcost[j] < min && lowcost[j] != 0)
{
min = lowcost[j];
minid = j;
}
}
cout << mst[minid] << "-" << minid << ":" << min << endl;
lowcost[minid] = 0;
for (j = 2; j <= n; j++)
{
if (graph[minid][j] != 0 && graph[minid][j] < lowcost[j])
{
lowcost[j] = graph[minid][j];
mst[j] = minid;
}
}
}
}
else
{
cout <<"0-0"<< ":" << "0" << endl;
}
}
int main(){
cout << "Input" << endl;
int point;
int edge;
cin >> point;
if (cin.get()==',')
{
cin >> edge;
}
AdjacencyWDigraph<int> gragh(point, 0); //初始化一个无边图
int start, end, weight;
for (int i = 1; i <= edge; i++)
{
cin >> start;
if (cin.get()==',')
{
cin >> end;
}
if (cin.get()==',')
{
cin >> weight;
}
gragh.Add(start, end, weight);
}
cout << "Output" << endl;
int Label = 9; //定义reach数组中走过的点标记为9
int *reach = new int [point+1];
gragh.BFS(1, reach, Label);
cout << endl;
int *reach2 = new int[point + 1];
gragh.DFS(1, reach2, Label);
cout << endl;
cout << gragh.findTheShortestPath(1, point)<<endl;
gragh.Prim(point, gragh.getA());
cout << "End" << endl;
system("pause");
}