课程作业1(单链表C++实现)
//单链表的操作C++实现
#include <iostream>
using namespace std;//使用命名空间
template<typename dataType> //定义一个数据类型模板
class linkedList{//定义单链表类
struct Node{
dataType data;
Node *next;
Node(const dataType &x,Node *p=NULL):data(x),next(p){}
Node():next(NULL){}
~Node(){}
};
Node *head;
Node *move(int i){//返回第i个节点的地址
i=i-1;
Node * p = head;
while (i-- >= 0) p = p->next;
return p;
}
int currentLength;
public:
linkedList();//构建一个单链表
~linkedList();//销毁一个单链表
void clear();
void insertTail(const dataType &x);// 链表尾部插入元素
void insertPosition(int position,const dataType &x);//链表指定位置插入元素
void remove(int position);//链表删除指定位置元素
dataType visit(int position);// 查找指定位置元素
int search(const dataType &x);//查找某个元素值是否存在
void traverse();//打印链表
void reverse();//逆序链表
};
template<typename dataType>
linkedList<dataType>::linkedList(){//创建一个空的单链表,带表头
head=new Node;
currentLength=0;
}
template<typename dataType>
linkedList<dataType>::~linkedList(){//把单链表清空,再删除头节点
clear();
delete head;
}
template<typename dataType>
void linkedList<dataType>::clear(){//把单链表清空
Node *p = head->next, *tmp;
while (p != NULL)
{
tmp = p;
p = p->next;
delete tmp;
}
head->next = NULL;
currentLength = 0;
}
template<typename dataType>
void linkedList<dataType>::insertTail(const dataType &x){
Node * newNode = new Node; //定义一个Node结点指针newNode
newNode->next = NULL; //定义newNode的数据域和指针域
newNode->data = x;
Node *p=head; //定义指针p指向头结点
if (head == NULL) { //当头结点为空时,设置newNode为头结点
head = newNode;
}
else //循环知道最后一个节点,将newNode放置在最后
{
while (p->next != NULL)
{
p = p->next;
}
p->next = newNode;
}
currentLength++;
}
template<typename dataType>
void linkedList<dataType>::insertPosition(int position,const dataType &x){
Node * pos;
pos = move(position - 1);
pos->next = new Node(x, pos->next);
currentLength++;
}
template<typename dataType>
void linkedList<dataType>::remove(int position) {
Node * pos = move(position-1 ), * tmp;
tmp = pos->next;
pos->next = tmp->next;
delete tmp;
currentLength--;
}
template<typename dataType>
int linkedList<dataType>::search(const dataType &x){
Node * pos = head;
for (int num = 0; num <=currentLength; num++)
//while(pos!=NULL)
{
if (pos->data == x) return num;
pos = pos->next;
}
return -1;
}
template<typename dataType>
dataType linkedList<dataType>::visit(int position){
return move(position)->data;
}
template<typename dataType>
void linkedList<dataType>::traverse(){
Node *p = head->next;
cout<<"输出链表:";
while (p != NULL)
{
cout << p->data << " ";
p = p->next;
}
cout << endl;
cout<<endl;
}
template<typename dataType>
void linkedList<dataType>::reverse(){
Node * p = head->next;//头结点之后的第1个节点
Node * q = head->next->next;//头结点之后的第2节点
Node * m = head->next->next->next;//头结点之后的第3个节点
p->next = NULL;//将头接点之后的第1个节点的next指针置为空
//根据m是否为空来判断 以此逆序每一个节点
while(m){
q->next = p;
p = q;
q = m;
m = m->next;
}
//将最后一个节点逆序
q->next = p;
//将头从新指向新的的第1个节点(之前的最后一个节点)
head ->next = q;
}
//template<typename dataType>
int main(){
//template<typename dataType>
linkedList<double> l;
int i;
double d;
int p;
int n;
cout<<endl;
cout << "0.创建一个链表 1.尾部插入元素 2.指定位置插入元素\n";
cout << "3.删除指定位置元素 4.查找指定位置的元素 5.查找某个元素\n";
cout << "6.逆序链表 7.删除链表 其他数字.退出程序\n";
cout <<endl ;
do {
cout<<"请输入要执行的操作:";
cin>>i;
switch(i){
case 0:
cout<<"创建一个链表:";
cout<<"请输入单链表的长度: ";
cin>>n;
for (int i=0; i<n; i++){
cin>>d;
l.insertTail(d);
}
l.traverse();break;
case 1:
cout<<"尾部插入元素:";
cout << "请输入要在尾部插入的值: ";
cin>>d;
l.insertTail(d);
l.traverse();break;
case 2:
cout<<"指定位置插入元素:" ;
cout << "请输入位置: ";
cin>>p;
cout << "请输入要在插入的值: ";
cin>>d;
l.insertPosition(p,d);
l.traverse();break;
case 3:
cout<<"删除指定位置元素:";
cout << "请输入位置: ";
cin>>p;
l.remove(p);
l.traverse();break;
case 4:
cout<<"查找指定位置的元素:";
cout<<"请输入需要查找的位置:";
cin>>p;
cout<<"#"<<p<<": "<<l.visit(p)<< "\n";
cout<<endl;
break;
case 5:
cout<<"查找某个元素:";
cout << "请输入需要查找的数据:";
cin >>d;
if (l.search(d) == -1)
cout << "数据不存在\n";
else{
cout << "值为" <<d<< "的数据存在,"<<"位置为"<< l.search(d)<<"\n";
}
cout<<endl;
break;
case 6:
cout<<"逆序链表:";
l.reverse();
l.traverse();
break;
case 7:
cout<<"链表已删除";
l.~linkedList();cout<<endl<<endl;break;
default:
cout<<"测试结束";cout<<endl<<endl ;
break;
}
}while(i==0||i==1||i==2||i==3||i==4||i==5||i==6||i==7);
system("pause") ;
cout<<"主程序结束" <<endl;
return 0;
}
彭总的做法
/一、单链表类头文件:
#pragma once
#include<iostream>
#include<fstream>
//定义节点
//定义链表的类模板
template <typename T>
class linked_list
{
private:
struct node {
T data;
node * next;
};
node * phead;
int isize;
public:
linked_list(); //构造函数
~linked_list(); //析构函数
void insert_tail(T a);//尾部插入数据
void insert(T a,int n);//指定位置插入数据
bool delete_element(int n);//指定位置删除数据
T find_th(int k);//查找指定位置的数据,如不存在报错
int find_x(T x);//查找指定数据,如不存在返回-1
void show();//打印链表
void reverse();//逆序链表
void menu();
};
//构造函数
template <typename T>
linked_list<T>::linked_list() :phead(NULL), isize(0)
{
phead = new node;
phead->next = NULL;
}
//析构函数
template <typename T>
linked_list<T>::~linked_list()
{
node * temp = NULL;
node * p = phead->next;
while (p != NULL)
{
temp = p->next;
delete p;
p = temp;
}
delete temp;
temp = NULL;
delete phead;
p = NULL;
isize = 0;
}
//尾部插入数据
template <typename T>
void linked_list<T>::insert_tail(T a)
{
node * temp = new node;
node * p = phead;
temp->data = a;
temp->next = NULL;
while (p->next != NULL)
{
p = p->next;
}
p->next = temp;
isize++;
temp = NULL;
p = NULL;
}
//指定位置插入数据
template <typename T>
void linked_list<T>::insert(T a, int n)
{
using std::cout;
using std::endl;
if (n<1 || n>isize)
{
cout << "输入错误!!!" << endl;
}
else
{
node * temp = new node;
temp->data = a;
node *p = phead;
for (int i = 1; i < n; i++)
{
p = p->next;
}
temp->next = p->next;
p->next = temp;
isize++;
}
}
//指定位置删除数据
template <typename T>
bool linked_list<T>::delete_element(int n)
{
using std::cout;
using std::endl;
if (n<1 || n>isize )
{
cout << "输入错误!!!" << endl;
return false;
}
else
{
node * p = phead;
for (int i = 1; i < n; i++)
{
p = p->next;
}
node * temp;
temp = p->next;
p->next = p->next->next;
delete temp;
temp = NULL;
isize--;
return true;
}
}
//查找指定位置的数据,如不存在报错
template <typename T>
T linked_list<T>::find_th(int k)
{
using std::cout;
using std::endl;
if (k<1 || k>isize )
{
cout << "输入错误!!!" << endl;
return -1;
}
else
{
node * p = phead;
for (int i = 1; i < k; i++)
{
p = p->next;
}
return p->next->data;
}
}
//查找指定数据,如不存在返回-1
template <typename T>
int linked_list<T>::find_x(T x)
{
node * p = phead->next;
int i = 1;
while (p != NULL)
{
if (p->data == x)
{
return i;
}
p = p->next;
i++;
}
p = NULL;
return -1;
}
//打印链表
template <typename T>
void linked_list<T>::show()
{
using std::cout;
using std::endl;
int count = 1;
node *temp = NULL;
temp = phead->next;
cout << "当前链表: " << endl;
while (temp != NULL)
{
cout << "#" << count << ": " << temp->data << " ";
if (count % 5 == 0)
cout << endl;
temp = temp->next;
count++;
}
temp = NULL;
cout << endl;
}
//逆序链表
template <typename T>
void linked_list<T>::reverse()
{
node * prenode = NULL;
node * curnode = NULL;
node * nextnode = NULL;
if (isize == 1 || isize == 0)
{
return;
}
else if (isize >= 2)
{
prenode = phead->next;
curnode = prenode->next;
nextnode = curnode->next;
prenode->next = NULL;
while (nextnode != NULL)
{
curnode->next = prenode;
prenode = curnode;
curnode = nextnode;
nextnode = nextnode->next;
}
curnode->next = prenode;
phead->next = curnode;
}
prenode = NULL;
curnode = NULL;
nextnode = NULL;
}
template <typename T>
void linked_list<T>::menu()
{
using std::cout;
using std::endl;
cout << "***********************************************\n";
cout << "功能选择如下:\n";
cout << "0.创建一个链表 1.在尾部插入一个元素 2.在指定位置插入一个元素\n";
cout << "3.删除指定位置元素 4.查找指定位置的元素 5.查找某个元素是否存在\n";
cout << "6.逆序链表 7.打印链表 8.删除链表 \n";
cout << "9.退出程序\n";
cout << "***********************************************\n";
cout << "请根据菜单选择:";
}
///二、单链表类主函数:
#include"single linked list.h"
int main()
{
using std::cin;
using std::cout;
using std::endl;
linked_list<double> mylist;
char choice;
int x;
double y;
mylist.menu();
while (cin >> choice)
{
switch (choice)
{
case'0':
cout << "请输入链表的元素个数N:\n";
cin >> x;
cout << "请输入元素数据:\n";
for (int i = 0; i < x; i++)
{
cin >> y;
mylist.insert_tail(y);
}
mylist.show();
break;
case'1':
cout << "请输入在尾部插入的数据:\n";
cin >> y;
mylist.insert_tail(y);
mylist.show();
break;
case'2':
cout << "请输入位置: \n";
cin >> x;
cout << "请输入数据:\n";
cin >> y;
mylist.insert(y, x);
mylist.show();
break;
case'3':
cout << "请输入需要删除数据的位置:\n";
cin >> x;
if (mylist.delete_element(x) == true)
{
cout << "删除成功\n";
}
else
{
cout << "删除失败\n";
}
mylist.show();
break;
case'4':
cout << "请输入需要查找数据的位置:\n";
cin >> x;
cout << "#" << x << ": " << mylist.find_th(x) << "\n";
break;
case'5':
cout << "\n请输入需要查找数据:\n";
cin >> y;
if (mylist.find_x(y) == -1)
cout << "数据不存在\n";
else
{
cout << "\n值为" <<y << "存在,"<<"位置为"<< mylist.find_x(y)<<"\n";
}
break;
case'6':
mylist.reverse();
cout << "\n逆置成功\n";
mylist.show();
break;
case'7':
mylist.show();
break;
case'8':
mylist.~linked_list();
break;
case'9':
goto exit;
default:
break;
}
cout << "请根据菜单选择:";
//mylist.menu();
}
exit:
cout << "Bye Bye!!!!!";
cin.get();
cin.get();
return 0;
}
课程作业2(stack的实现与应用)
1.两种实现方法
//数组实现
#pragma once
#ifndef _ARRAYSTACK_H_
#define _ARRAYSTACK_H_
const int SIZE = 1024;
template <typename dataType>
class arrayStack {
private:
dataType buffer[SIZE];
int index;
public:
arrayStack():index(-1){}
void push(dataType data) { buffer[++index] = data; }//自加入栈
dataType pop() { return buffer[index--]; }//出栈自减
dataType top() { return buffer[index]; }//返回栈顶元素
bool isEmpty() { return -1 == index; }//判断栈是否为空
bool isFull() { return (SIZE - 1) == index; }//判断栈是否溢出
};
#endif // !_ARRAYSTACK_H_
//链式实现
#pragma once
#ifndef _LINKEDSTACK_H_
#define _LINKEDSTACK_H_
template<class dataType>
class linkedStack
{
public:
linkedStack():head(NULL),p(NULL){}
~linkedStack();
void push(dataType d);
dataType pop();
dataType top() { return *head.data; }
bool isEmpty() { return NULL == head; }
private:
struct Node
{
dataType data;
Node *next;
}*head,*p;
};
template<class dataType>
linkedStack<dataType>::~linkedStack()
{
p = head;
while (p)
{
head = p->next;
delete p;
p = head;
}
}
template<class dataType>
void linkedStack<dataType>::push(dataType d)
{
p = new Node;
p->data = d;
p->next = head;
head = p;
p = NULL;
}
template<class dataType>
dataType linkedStack<dataType>::pop()
{
dataType tmp = head->data;
p = head;
head = head->next;
delete p;
p = NULL;
return tmp;
}
#endif // !_LINKEDSTACK_H_
2.应用计算表达式
/*******************************main.cpp******************************/
#include<iostream>
#include"arrayStack.h"
#include"stackApplication.h"
using namespace std;
int main()
{
char e[100];
int i;
cout << "是否开始计算?(开始请输入‘1’,结束请输入‘0’)" << endl;
cin >> i;
while (i == 1)
{
cout << "请输入表达式:";
cin >> e;//="5+7*3-(6*2+1)/10"
cout <<"表达式运算:"<<e<<"="<<ExpressionEvaluation(e)<<endl<< endl;
cout << "是否开始计算?(开始请输入‘1’,结束请输入‘0’)" << endl;
cin >> i;
}
system("pause");
return 0;
}
/*******************************arrayStack.h******************************/
//数组实现栈
#pragma once
#ifndef _ARRAYSTACK_H_
#define _ARRAYSTACK_H_
const int SIZE = 1024;
template <typename dataType>
class arrayStack {
private:
dataType buffer[SIZE];
int index;
public:
arrayStack():index(-1){}
void push(dataType data) { buffer[++index] = data; }//自加入栈
dataType pop() { return buffer[index--]; }//出栈自减
dataType top() { return buffer[index]; }//返回栈顶元素
bool isEmpty() { return -1 == index; }//判断栈是否为空
bool isFull() { return (SIZE - 1) == index; }//判断栈是否溢出
};
#endif // !_ARRAYSTACK_H_
/*******************************stackApplication.h******************************/
#pragma once
#ifndef _STACKAPPLICATION_H_
#define _STACKAPPLICATION_H_
double ExpressionEvaluation(char* expression);//求解表达式
double Str2Num(char* s);//字符型转为可计算的数
bool isNum(char c);//判断字符是否为数字
bool isOpt(char c);//判断字符是否为操作符
double compute(double a1, double a2, char opt);
int PriorityTable(char c);//比较各操作符的优先级
#endif // !_STACKAPPLICATION_H_
/*******************************stackApplication.cpp******************************/
#include<iostream>
#include"arrayStack.h"
#include"stackApplication.h"
using namespace std;
double ExpressionEvaluation(char* expression) {//求解表达式
char buf[16];//缓冲区
double num1, num2;
char opt;//操作符
arrayStack<double> num_stack;//数栈
arrayStack<char> opt_stack;//符栈
while (*expression)
{
if (isNum(*expression))//判断字符是否为数字
{
int i = 0;
do
{
buf[i++] = *(expression++);
} while (isNum(*expression));
buf[i] = 0;
num_stack.push(Str2Num(buf));
}
if (isOpt(*expression))//判断字符是否为操作符
{
if (*expression==')')
{
while (opt_stack.top()!='(')
{
opt = opt_stack.pop();
num1 = num_stack.pop();
num2 = num_stack.pop();
num_stack.push(compute(num2, num1, opt));
}
opt_stack.pop();//pop '('
}
else
{
if (opt_stack.isEmpty() || PriorityTable(*expression)>PriorityTable(opt_stack.top()))
{
opt_stack.push(*expression);
}
else
{//弹出操作符,直到栈顶有一个较低的优先级
while (!opt_stack.isEmpty()&&(PriorityTable(*expression)<= PriorityTable(opt_stack.top()))&&opt_stack.top()!='(')
{
opt = opt_stack.pop();
num1 = num_stack.pop();
num2 = num_stack.pop();
num_stack.push(compute(num2, num1, opt));
}
opt_stack.push(*expression);//压入该操作符
}
}
expression++;
}
}
//字符串读取完成后,弹出所有剩余的操作符
while (!opt_stack.isEmpty())
{
opt = opt_stack.pop();
num1 = num_stack.pop();
num2 = num_stack.pop();
num_stack.push(compute(num2, num1, opt));
}
return num_stack.pop();
}
double Str2Num(char* s)//字符型数转为可计算的数
{
double num = 0;
bool decimal = 0;
double exp = 0.1;
while (*s)
{
if (*s=='.')
{
decimal = 1;
s++;
continue;
}
if (!decimal)
{
num = num * 10 + (*s - '0');
}
else
{
num = num + (*s - '0')*exp;
exp *= 0.1;
}
s++;
}
return num;
}
bool isNum(char c)//判断字符是否为数字
{
return (c >= '0' && c <= '9' || c == '.');
}
bool isOpt(char c)//判断字符是否为操作符
{
return (c == '+' || c == '-' || c == '*' || c == '/' || c == '(' || c == ')');
}
double compute(double a1, double a2, char opt)
{
switch (opt)
{
case '+':
return a1 + a2;
case '-':
return a1 - a2;
case '*':
return a1 * a2;
case '/':
return a1 / a2;
default:
break;
}
}
int PriorityTable(char c)//比较各操作符的优先级
{
switch (c)
{
case '+':
case '-':
return 1;
case '*':
case '/':
return 2;
case '(':
return 3;
case ')':
return -1;
default:
break;
}
}
课程作业3(二叉查找树)
/********************mainTest.cpp**********************/
#include<iostream>
#include"binarySearchTree.h"
using namespace std;
int main()
{
cout << "请按前序输入一棵树,使用-1代表空树" << endl;
cout << "例子: 6 2 1 -1 -1 4 3 -1 -1 -1 8 -1 -1" << endl << endl;
//8 3 1 -1 -1 6 4 -1 -1 7 -1 -1 10 -1 14 13 -1 -1 -1
binarySearchTree *root;
root = createBiTree();//创建一个树
cout << endl;
cout << endl << "前序遍历:" ;
preTravel(root);
cout << endl << endl;
cout << "后序遍历:" ;
postTravel(root);
cout << endl << endl;
cout << "中序遍历:" ;
inorderTravel(root);
cout << endl << endl;
cout << "最小值:" << findMin(root) << endl;
cout << "最大值:" << findMax(root) << endl << endl;
cout << "插入5" << endl;
insert(root, 5);
cout << "中序遍历:" ;
inorderTravel(root);
cout << endl << endl;
cout << "删除8" << endl;
remove(root, 8);
cout << "中序遍历:" ;
inorderTravel(root);
cout << endl << endl;
cout << "查询5" << endl;
visit(root, 5);
cout << "查询100" << endl;
visit(root, 100);
cout << endl;
cout << "删除前,后序遍历:";
postTravel(root);
cout<< endl;
cout << "删除树" << endl;
deleteTree(root);
cout <<endl <<endl;
system("pause");
return 0;
}
/********************binarySearchTree.h**********************/
#pragma once
#ifndef _BINARYSEARCHTREE_H_
#define _BINARYSEARCHTREE_H_
struct binarySearchTree
{
int data;
binarySearchTree *leftChild;
binarySearchTree *rightChild;
};
binarySearchTree *createBiTree();//创建树
void deleteTree(binarySearchTree *&tree);//删除树
void preTravel(binarySearchTree *tree);//前序遍历
void postTravel(binarySearchTree *tree);//后序遍历
void inorderTravel(binarySearchTree *tree);//中序遍历
int findMin(binarySearchTree *tree);//找最小值
int findMax(binarySearchTree *tree);//找最大值
//指针的引用,可改变指针tree
void remove(binarySearchTree *&tree, int data);//删除一个数,按二叉查找树规则
void insert(binarySearchTree *&tree, int data); //插入一个数,按二叉查找树规则
void visit(binarySearchTree *tree, int data);//查找一个数是否存在
#endif // !_BINARYSEARCHTREE_H_
/********************binarySearchTree.cpp**********************/
#include<iostream>
#include"binarySearchTree.h"
using namespace std;
binarySearchTree *createBiTree()//创建树
{
int data;
binarySearchTree *T;
cin >> data;
if (-1==data)
{
return NULL;//T = NULL
}
else
{
T = new binarySearchTree;
T->data = data;
T->leftChild = createBiTree();
T->rightChild = createBiTree();
return T;
}
//return T;
}
void deleteTree(binarySearchTree *&tree)//删除树
{
if (tree)
{
deleteTree(tree->leftChild);
deleteTree(tree->rightChild);
cout << "删除:" << tree->data << ";";
delete tree;
tree = NULL;
}
}
void preTravel(binarySearchTree *tree)//前序遍历
{
if (tree)
{
cout << tree->data << " ";
preTravel(tree->leftChild);
preTravel(tree->rightChild);
}
}
void postTravel(binarySearchTree *tree)//后序遍历
{
if (tree)
{
postTravel(tree->leftChild);
postTravel(tree->rightChild);
cout << tree->data << " ";
}
}
void inorderTravel(binarySearchTree *tree)//中序遍历
{
if (tree)
{
inorderTravel(tree->leftChild);
cout << tree->data << " ";
inorderTravel(tree->rightChild);
}
}
int findMin(binarySearchTree *tree)//找最小值
{
if (tree)
{
if (tree->leftChild)
{
return findMin(tree->leftChild);
}
else
{
return tree->data;
}
}
else
{
return -1;
}
}
int findMax(binarySearchTree *tree)//找最大值
{
if (tree)
{
if (tree->rightChild)
{
return findMax(tree->rightChild);
}
else
{
return tree->data;
}
}
else
{
return -1;
}
}
//指针的引用,可改变指针tree
void remove(binarySearchTree *&tree, int data)//删除一个数,按二叉查找树规则
{
if (!tree)
{
return;
}
if (tree->data>data)
{
remove(tree->leftChild, data);
}
else if (tree->data<data)
{
remove(tree->rightChild, data);
}
else if (tree->leftChild&&tree->rightChild)
{
//tree->data = findMax(tree->leftChild);
//remove(tree->leftChild, tree->data);
tree->data = findMax(tree->rightChild);
remove(tree->rightChild, tree->data);
}
else
{
binarySearchTree *tmp = tree;
tree = ((tree->leftChild) ? tree->leftChild : tree->rightChild);
delete tmp;
tmp = NULL;
}
}
void insert(binarySearchTree *&tree, int data)//插入一个数,按二叉查找树规则
{
if (tree)
{
if (tree->data<data)
{
insert(tree->rightChild,data);
}
else if(tree->data>data)
{
insert(tree->leftChild, data);
}
}
else
{
tree = new binarySearchTree;
tree->data = data;
tree->leftChild = NULL;
tree->rightChild = NULL;
}
}
void visit(binarySearchTree *tree, int data)//查找一个数是否存在
{
if (!tree)
{
cout << "该数字不存在" << endl;
}
else if (tree->data>data)
{
visit(tree->leftChild, data);
}
else if(tree->data<data)
{
visit(tree->rightChild, data);
}
else
{
cout << "该数字存在" << endl;
}
}
课程作业4(dijkstra’s algorithm)
/********************mainTest.cpp**********************/
#include<iostream>
#include"ALG.h"
using namespace std;
int main()
{
ALGraph graph;
graph.createGraph();
graph.printGraph();
cout << endl << "以 v1为顶点的算法: 为顶点的算法: 为顶点的算法: "<<endl;
graph.dijkstra("v1");
cout << endl << "以 v2为顶点的算法: 为顶点的算法: 为顶点的算法: " << endl;
graph.dijkstra("v2");
cout << endl << "以 v6为顶点的算法: 为顶点的算法: 为顶点的算法: " << endl;
graph.dijkstra("v6");
cout << endl << "以 v7为顶点的算法: 为顶点的算法: 为顶点的算法: " << endl;
graph.dijkstra("v7");
system("pause");
return 0;
}
/******************** ALG.h**********************/
#pragma once
#include<iostream>
#include<string>
#define INF 100000000
using namespace std;
//边结点信息 边结点信息 边结点信息
struct ArcNode
{
string adjvex;//存储邻接点 存储邻接点 存储邻接点
int weight;//权重
ArcNode *nextarc;//指向下一个邻接点 指向下一个邻接点 指向下一个邻接点 指向下一个邻接点
};
//顶点信息 顶点信息
struct VNode
{
string vexname;//存储顶点 存储顶点 存储顶点
ArcNode *firstarc;//指向第一个邻接点 指向第一个邻接点 指向第一个邻接点 指向第一个邻接点
bool known=false;
int dist=INF;
VNode *path=NULL;
};
class ALGraph
{
public:
~ALGraph();
void createGraph();//创建邻接链表图 创建邻接链表图 创建邻接链表图 创建邻接链表图
void printGraph();//打印
void dijkstra(string s);
void printPath(VNode *v);
private:
VNode *vertex;//指向动态申请的各顶点数组 指向动态申请的各顶点数组 指向动态申请的各顶点数组 指向动态申请的各顶点数组 指向动态申请的各顶点数组 指向动态申请的各顶点数组 指向动态申请的各顶点数组
int vexnum;//存储顶点数 存储顶点数
int arcnum;//存储边数 存储边数 存储边数
void addArcToList(string from, int weight,string to);//将边加入相应链表 将边加入相应链表 将边加入相应链表 将边加入相应链表
VNode* findSmallUnknownDistanceVertex();
};
/******************** ALG.cpp**********************/
#include<iostream>
#include<string>
#include"ALG.h"
using namespace std;
void ALGraph::createGraph()//创建邻接链表图 创建邻接链表图 创建邻接链表图 创建邻接链表图
{
cout << "please input number of vertex:";
cin >> vexnum;
vertex = new VNode[vexnum];
cout << "please input all the name of vertexes:";
for (int i = 0; i < vexnum; i++)
{
string c = "v0";
cin >> c;
vertex[i].vexname = c;
vertex[i].firstarc = NULL;
}
cout << "please input number of arc:";
cin >> arcnum;
cout << "please input arc information:" << endl;
for (int i = 0; i < arcnum; i++)
{
cout << "the edge " << i + 1 << ":" << endl;
//起点
string from = "v0";
cout << "From:"; cin >> from;
//终点
string to = "v0";
cout << "To:"; cin >> to;
//权值
int weight = 0;
cout << "Weight:"; cin >> weight;
cout << endl;
//创建有权边的操作 创建有权边的操作 创建有权边的操作 创建有权边的操作
addArcToList(from, weight, to);
}
}
//将边加入相应链表 将边加入相应链表 将边加入相应链表 将边加入相应链表
void ALGraph::addArcToList(string from, int weight, string to)
{
ArcNode *arc = new ArcNode;
arc->adjvex = to;
arc->weight = weight;
arc->nextarc = NULL;
for (int i = 0; i < vexnum; i++)
{
if (vertex[i].vexname == from)
{
if (vertex[i].firstarc)
{
ArcNode *tmp = vertex[i].firstarc;
while (tmp->nextarc)
{
tmp = tmp->nextarc;
}
tmp->nextarc = arc;
}
else
{
vertex[i].firstarc = arc;
}
break;
}
}
}
//打印出图的邻接链表示 打印出图的邻接链表示 打印出图的邻接链表示 打印出图的邻接链表示 打印出图的邻接链表示 打印出图的邻接链表示
void ALGraph::printGraph()
{
cout << "图的邻接表结构: 图的邻接表结构: 图的邻接表结构: 图的邻接表结构: " << endl;
for (int i = 0; i < vexnum; i++)
{
cout << "List" << i + 1 << ":" << vertex[i].vexname << "->";
ArcNode *tmp = vertex[i].firstarc;
while (tmp)
{
cout << "(" << tmp->weight << ")" << tmp->adjvex << "->";
tmp = tmp->nextarc;
}
cout << "NULL" << endl;
}
}
ALGraph::~ALGraph()
{
for (int i = 0; i < vexnum; i++)
{
ArcNode *tmp = vertex[i].firstarc;
ArcNode *tmp1 = NULL;
//先删除链表,再头 先删除链表,再头 先删除链表,再头 先删除链表,再头 先删除链表,再头 先删除链表,再头
while (tmp)
{
tmp1 = tmp;
tmp = tmp->nextarc;
delete tmp1;
tmp1 = NULL;
}
}
delete[]vertex;
}
//寻找最小距离,在所有未知是否到短路径的顶点中 寻找最小距离,在所有未知是否到短路径的顶点中 寻找最小距离,在所有未知是否到短路径的顶点中 寻找最小距离,在所有未知是否到短路径的顶点中 寻找最小距离,在所有未知是否到短路径的顶点中 寻找最小距离,在所有未知是否到短路径的顶点中 寻找最小距离,在所有未知是否到短路径的顶点中 寻找最小距离,在所有未知是否到短路径的顶点中 寻找最小距离,在所有未知是否到短路径的顶点中 寻找最小距离,在所有未知是否到短路径的顶点中 寻找最小距离,在所有未知是否到短路径的顶点中
VNode* ALGraph::findSmallUnknownDistanceVertex()
{
VNode *tmp=new VNode;
for (int i = 0; i < vexnum; i++)
{
if (!vertex[i].known)
{
if (tmp->dist>vertex[i].dist)
{
tmp = &vertex[i];
}
}
}
if (tmp->dist==INF)
{
return NULL;
}
return tmp;
}
void ALGraph::dijkstra(string str)
{
//初始化各顶点信息值 初始化各顶点信息值 初始化各顶点信息值 初始化各顶点信息值 初始化各顶点信息值
for (int i = 0; i < vexnum; i++)
{
vertex[i].dist = INF;
vertex[i].known = false;
vertex[i].path = NULL;
}
//遍历寻找相应顶点 遍历寻找相应顶点 遍历寻找相应顶点 遍历寻找相应顶点
for (int i = 0; i < vexnum; i++)
{
if (str == vertex[i].vexname)
{
vertex[i].dist = 0;
break;
}
}
//算法核心操作,寻找最短路 算法核心操作,寻找最短路 算法核心操作,寻找最短路 算法核心操作,寻找最短路 算法核心操作,寻找最短路 算法核心操作,寻找最短路 径
for (; ; )
{
VNode *v = findSmallUnknownDistanceVertex();
if (v == NULL)
{
break;
}
v->known = true;
ArcNode *tmp = v->firstarc;
while (tmp)
{
for (int i = 0; i < vexnum; i++)
{
if (tmp->adjvex == vertex[i].vexname)
{
if (!vertex[i].known)
{
if (v->dist + tmp->weight < vertex[i].dist)
{
vertex[i].dist = v->dist + tmp->weight;
vertex[i].path = v;
}
}
break;
}
}
tmp = tmp->nextarc;
}
}
//打印 dijkstra算法结果表 算法结果表 算法结果表
for (int i = 0; i < vexnum; i++)
{
cout << "路径为: 路径为: ";
printPath(&vertex[i]);
if (vertex[i].dist==INF)
{
cout << ";无法到达该点。 ;无法到达该点。 ;无法到达该点。 ;无法到达该点。 " << endl;
}
else
{
cout << ";距离是: ;距离是: ;距离是: " << vertex[i].dist << endl;
}
}
}
void ALGraph::printPath(VNode *v)
{
if (v->path)
{
printPath(v->path);
cout << "->";
}
cout << v->vexname;
}
//input.txt
7
v1 v2 v3 v4 v5 v6 v7
12
v1
v2
2
v1
v3
4
v1
v4
1
v2
v4
3
v2
v5
10
v3
v6
5
v4
v3
2
v4
v6
8
v4
v7
4
v5
v4
2
v5
v7
6
v7
v6
1
课程作业5(Prim算法最小生成树)
/******Prim算法最小生成树*******/
#include<iostream>
using namespace std;
#define MAX 8//最大顶点数
#define MAXCOST 0x7fffffff
int COST[MAX][MAX];
int NEAR[MAX];
void FindMinCost(int COST[][MAX],int n, int &k,int &l)
{
int min = COST[1][1];
for (int i = 1; i <= n; i++)
{
for (int j = 1; j <= i; j++)
{
if (min > COST[i][j])
{
min = COST[i][j];
k = i;
l = j;
}
}
}
}
void Prim(int COST[][MAX],int n,int T[][2], int &mincost)
{
int k, l,i,j;
//寻找最小成本的边
FindMinCost(COST,n,k,l);
mincost = COST[k][l];
T[1][1] = k, T[1][2] = l;
cout << "V" << T[1][1] << "->V" << T[1][2] << " COST=" << COST[k][l] << " Total=" << mincost << endl;
for (i = 1; i <= n; i++)
{
if (COST[i][l] < COST[i][k])
NEAR[i] = l;
else
NEAR[i] = k;
}
NEAR[k] = NEAR[l] =0;
NEAR[0] = 0;
for (i = 2; i <= n - 1; i++)
{
//寻找满足条件的j
j = 0;
for (int index = 1; index <= n; index++)
{
if (NEAR[index] != 0&&COST[index][NEAR[index]]<COST[j][NEAR[j]])
{
j = index;
}
}
T[i][1] = j;
T[i][2] = NEAR[j];
mincost = mincost + COST[j][NEAR[j]];
cout << "V" << T[i][1] << "->V" << T[i][2] <<" COST="<< COST[j][NEAR[j]]<<" Total="<<mincost<< endl;
NEAR[j] = 0;
for (k = 1; k <= n; k++)
{
if (NEAR[k] != 0 && COST[k][NEAR[k]] > COST[k][j])
NEAR[k] = j;
}
}
if (mincost >= MAXCOST)
cout << "NO SPANNING TREE\n";
}
int main()
{
int i, j, k, m, n,cost;
cin >> m >> n;//m=顶点的个数,n=边的个数
//初始化图G
for (i = 0; i <= m; i++)
{
for (j = 0; j <= m; j++)
{
COST[i][j] = MAXCOST;
}
}
//构建图G
for (k = 1; k <= n; k++)
{
cin >> i >> j >> cost;
COST[i][j] = cost;
COST[j][i] = cost;
}
//求解最小生成树
int t[MAX][2], mincost=MAXCOST;
Prim(COST, m,t,mincost);
//输出最小权值和
cout << "最小权值和=" << mincost << endl;
system("pause");
return 0;
}