C++数据结构与算法 -- 图

存储方式

  • 邻接表
  • 邻接矩阵

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-5shB04Kf-1644656228144)(C:\Users\26737\AppData\Roaming\Typora\typora-user-images\image-20220211170457179.png)]

class Edge
{
public:
	//权重
	int weight;
	//该边从from点指向to点
	Node* from;
	Node* to;
	Edge(int w, Node* f, Node* t) :weight(w), from(f), to(t) {}
};
class Node
{
public:
	//值
	int value;
	//入度
	int in;
	//出度
	int out;
	vector<Node*>nexts;
	vector<Edge*>edges;
	Node(int v) :value(v),in(0),out(0),nexts(vector<Node*>()),edges(vector<Edge*>()) {}
};

//图的结构
class Graph
{
public:
	//int是点的编号
	unordered_map<int, Node*>node;
	unordered_set<Edge*>edge;
};

转化

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-BCIGjtiO-1644656228147)(C:\Users\26737\AppData\Roaming\Typora\typora-user-images\image-20220211174301232.png)]

Graph createGraph(vector<vector<int>>matrix)
{
	Graph graph;
	//from点:matrix[i][0]  to点:matrix[i][1]  权重:matrix[i][2]
	for (size_t i = 0; i < matrix.size(); i++)
	{
		int from = matrix[i][0];
		int to = matrix[i][1];
		int weight = matrix[i][2];
		if (graph.node.find(from) == graph.node.end())
			//from节点在结构中没有出现 
			graph.node.insert(make_pair(from, new Node(from)));
		if (graph.node.find(to) == graph.node.end())
			//to节点在结构中没有出现 
			graph.node.insert(make_pair(to, new Node(to)));
		//下面操作时 肯定有from和to

		//获取from和to
		Node* fromNode = graph.node.at(from);
		Node* toNode = graph.node.at(to);
		Edge* newEdge = new Edge(weight, fromNode, toNode);
		//在from节点的邻居加上to节点
		fromNode->nexts.push_back(toNode);
		//from出度加一
		fromNode->out++;
		//to的入度加一
		toNode->in++;
		//form指出的边
		fromNode->edges.push_back(newEdge);
		//把新建的边放到边集中
		graph.edge.insert(newEdge);
	}
	return graph;
}

宽度优先遍历

  1. 利用队列实现
  2. 从源节点开始依次按照宽度进队列,然后弹出
  3. 每弹出一个点,把该节点所有没有进过队列的邻接点放入队列
  4. 直到队列变空

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-l1I0Kocr-1644656228148)(C:\Users\26737\AppData\Roaming\Typora\typora-user-images\image-20220211174253291.png)]

//图的宽度优先遍历
void bfs(Node* node)
{
	if (node == nullptr)return;
	queue<Node*>q;
	unordered_set<Node*>setHash;
	q.push(node);
	setHash.insert(node);
	while (!q.empty())
	{
		Node* node = q.front();
		q.pop();
		cout << node->value << " ";
		for (Node* cur : node->nexts)
		{
			if (setHash.find(cur) == setHash.end())
			{
				q.push(cur);
				setHash.insert(cur);
			}
		}
	}
}

深度优先遍历

  1. 准备一个栈
  2. 从源节点开始把节点按照深度放入栈,然后弹出
  3. 每弹出一个点,把该节点下一个没有进栈的邻接节点放入栈
  4. 直到栈空

一条路走到黑

//图的深度优先遍历
void depthFirstTraversal(Node* node)
{
	if (node == nullptr)return;
	stack<Node*>s;
	unordered_set<Node*>setHash;
	s.push(node);
	setHash.insert(node);
	cout << node->value << " ";
	while (!s.empty())
	{
		Node* node = s.top();
		s.pop();
		for (auto& cur : node->nexts)
		{
			if (setHash.find(cur) == setHash.end())
			{
				cout << cur->value << " ";
				setHash.insert(cur);
				s.push(node);
				s.push(cur);
				//跳出循环
				break;
			}
		}
	}
}

拓扑排序算法

适用于有向图,有入度为0的节点,没有环

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-cnsMTQSr-1644656228149)(C:\Users\26737\AppData\Roaming\Typora\typora-user-images\image-20220211203520118.png)]

vector<int> topologySorting(Graph g)
{
	//用来存放结果
	vector<int>v;
	//key:节点
	//value:入度
	//为了防止修改原来的图
	unordered_map<Node*, int>mapHash;
	//存放入度为0的节点
	queue<Node*>in;
	for (size_t i = 0; i < g.node.size(); i++)
	{
		Node* curNode = g.node.at(i);
		mapHash.insert(make_pair(curNode, curNode->in));
		if (curNode->in == 0)in.push(curNode);
	}
	while (!in.empty())
	{
		Node* node = in.front();
		in.pop();
		v.push_back(node->value);
		for (auto& next : node->nexts)
		{
			mapHash.insert(make_pair(next, mapHash.find(next)->second--));
			if (mapHash.find(next)->second == 0)in.push(next);
		}
	}
	return v;
}

kruskal 算法

适用范围:无向图

生成最小生成树

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-GvYVnF9S-1644656228150)(C:\Users\26737\AppData\Roaming\Typora\typora-user-images\image-20220212132210022.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-SZhCuoqH-1644656228150)(C:\Users\26737\AppData\Roaming\Typora\typora-user-images\image-20220211213847017.png)]

//判断是否有环()
class MySets
{
public:
	//节点 以及 对应的集合
	unordered_map<Node*, vector<Node*>>setMap;
	MySets(unordered_map<int, Node*>node)
	{
		for (auto &cur : node)
		{
			vector<Node*>n;
			n.push_back(cur.second);
			setMap.insert(make_pair(cur.second, n));
		}

	}
	bool isSameSet(Node* &from, Node* &to)
	{
		return setMap.at(from) == setMap.at(to);
	}
	void union_(Node* &from, Node* &to)
	{
		vector<Node*>fromSet = setMap.at(from);
		vector<Node*>toSet = setMap.at(to);
		for (auto& toNode : toSet)
		{
			//把to节点集合中所有元素加到from对应集合中
			fromSet.push_back(toNode);
			//setMap.erase(toNode);
			把to节点对应的集合的所有点所对应的集合变为from所属的集合
			//setMap.insert(make_pair(toNode, fromSet));
		}
		for (auto& node : fromSet)
		{
			setMap.erase(node);
			setMap.insert(make_pair(node, fromSet));
		}

	}
};
class C
{
public:
	bool operator()(Edge*e1, Edge*e2)
	{
		return e1->weight > e2->weight;
	}
};
//k算法生成最小生成树
set<int> kruskalMST(Graph &graph)
{
	//小根堆
	priority_queue<Edge*, vector<Edge*>, C>priorityQueue;
	//生成集合
	MySets mysets(graph.node);
	//所有的边加到小根堆
	for (auto edge : graph.edge)
		priorityQueue.push(edge);
	set<int> result;
	while (!priorityQueue.empty())
	{
		Edge* e = priorityQueue.top();//最小的元素
		priorityQueue.pop();
		if (!mysets.isSameSet(e->from, e->to))
		{
			result.insert(e->weight);
			//不在一个集合,加到一个集合
			mysets.union_(e->from, e->to);
		}
	}
	return result;
}

prim算法

适用范围:无向图

生成最小生成树

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-qim93l6V-1644656228151)(C:\Users\26737\AppData\Roaming\Typora\typora-user-images\image-20220212144616654.png)]

//p算法生成最小生成树
set<int> primMST(Graph& graph)
{
	//小根堆
	priority_queue<Edge*, vector<Edge*>, C>priorityQueue;
	//存放节点,在这里面的节点代表着已经走过了
	unordered_set<Node*>setNode;
	set<int>result;
	for (auto& node : graph.node)//防止森林结构(图可能不是连通的)
	{
		if (setNode.find(node.second) == setNode.end())
		{
			setNode.insert(node.second);
			//初始节点所连接的边
			for (auto& edge : node.second->edges)
				priorityQueue.push(edge);
			while (!priorityQueue.empty())
			{
				Edge* e = priorityQueue.top();//最小的
				priorityQueue.pop();
				if (setNode.find(e->to) == setNode.end())
				{
					setNode.insert(e->to);
					result.insert(e->weight);
					//下一个选中节点的边
					for (auto& nextEdge : e->to->edges)
						priorityQueue.push(nextEdge);
				}
			}
		}
	}
	return result;
};

迪杰克斯拉算法

使用条件:没有权重累加和为负数的环

寻找一个节点到指定节点的最短路径

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-60eiAIYk-1644656228152)(C:\Users\26737\AppData\Roaming\Typora\typora-user-images\image-20220212165556632.png)]

Node* getMinDistanceAndUnselectedNode(unordered_map<Node*, int>distanceMap, unordered_set<Node*>selectedNode)
{
	Node* minNode = nullptr;
	int minValue = INT32_MAX;
	for (auto& node : distanceMap)
	{
		if (selectedNode.find(node.first) == selectedNode.end() && minValue > node.second)
		{
			minNode = node.first;
			minValue = node.second;
		}
	}
	return minNode;
}
//djkstra
unordered_map<Node*, int>dijkstra(Node* head)
{
	unordered_map<Node*, int>distanceMap;//从Node*到head的最小距离是int
	distanceMap.insert(make_pair(head, 0));
	unordered_set<Node*>selectedNode;//记录已经被选择的节点
	Node* minNode = getMinDistanceAndUnselectedNode(distanceMap, selectedNode);//选择最小的节点head
	while (minNode != nullptr)
	{
		int distance = distanceMap.at(minNode);//最短距离
		for (auto& edge : minNode->edges)//遍历该节点邻接的边
		{
			Node* node = edge->to;//边的另一头的点
			if (distanceMap.find(node) == distanceMap.end())
				distanceMap.insert(make_pair(node, distance + edge->weight));
			else
                //此处注意当key相同的时候
                //使用insert插入会失败(无法做到替换的作用)
                //使用下标可以替换
				distanceMap[node] =(min(distanceMap.at(node), distance + edge->weight));
		}
		selectedNode.insert(minNode);
		minNode = getMinDistanceAndUnselectedNode(distanceMap, selectedNode);
	}
	return distanceMap;
}

所有代码

#include<iostream>
#include<unordered_map>
#include<unordered_set>
#include<vector>
#include<queue>
#include<stack>
#include<set>
using namespace std;
class Node;
class Edge;
class Edge
{
public:
	//权重
	int weight;
	//该边从from点指向to点
	Node* from;
	Node* to;
	Edge(int w, Node* f, Node* t) :weight(w), from(f), to(t) {}
};
class Node
{
public:
	//值
	int value;
	//入度
	int in;
	//出度
	int out;
	vector<Node*>nexts;
	vector<Edge*>edges;
	Node(int v) :value(v),in(0),out(0),nexts(vector<Node*>()),edges(vector<Edge*>()) {}
};

//图的结构
class Graph
{
public:
	//int是点的编号
	unordered_map<int, Node*>node;
	unordered_set<Edge*>edge;
};
Graph createGraph(vector<vector<int>>matrix)
{
	Graph graph;
	//from点:matrix[i][0]  to点:matrix[i][1]  权重:matrix[i][2]
	for (size_t i = 0; i < matrix.size(); i++)
	{
		int from = matrix[i][0];
		int to = matrix[i][1];
		int weight = matrix[i][2];
		if (graph.node.find(from) == graph.node.end())
			//from节点在结构中没有出现 
			graph.node.insert(make_pair(from, new Node(from)));
		if (graph.node.find(to) == graph.node.end())
			//to节点在结构中没有出现 
			graph.node.insert(make_pair(to, new Node(to)));
		//下面操作时 肯定有from和to

		//获取from和to
		Node* fromNode = graph.node.at(from);
		Node* toNode = graph.node.at(to);
		Edge* newEdge = new Edge(weight, fromNode, toNode);
		//在from节点的邻居加上to节点
		fromNode->nexts.push_back(toNode);
		//from出度加一
		fromNode->out++;
		//to的入度加一
		toNode->in++;
		//form指出的边
		fromNode->edges.push_back(newEdge);
		//把新建的边放到边集中
		graph.edge.insert(newEdge);
	}
	return graph;
}
//图的宽度优先遍历
void bfs(Node* node)
{
	if (node == nullptr)return;
	queue<Node*>q;
	unordered_set<Node*>setHash;
	q.push(node);
	setHash.insert(node);
	while (!q.empty())
	{
		Node* node = q.front();
		q.pop();
		cout << node->value << " ";
		for (Node* cur : node->nexts)
		{
			if (setHash.find(cur) == setHash.end())
			{
				q.push(cur);
				setHash.insert(cur);
			}
		}
	}
}
//图的深度优先遍历
void depthFirstTraversal(Node* node)
{
	if (node == nullptr)return;
	stack<Node*>s;
	unordered_set<Node*>setHash;
	s.push(node);
	setHash.insert(node);
	cout << node->value << " ";
	while (!s.empty())
	{
		Node* node = s.top();
		s.pop();
		for (auto& cur : node->nexts)
		{
			if (setHash.find(cur) == setHash.end())
			{
				cout << cur->value << " ";
				setHash.insert(cur);
				s.push(node);
				s.push(cur);
				//跳出循环
				break;
			}
		}
	}
}
vector<int> topologySorting(Graph g)
{
	//用来存放结果
	vector<int>v;
	//key:节点
	//value:入度
	//为了防止修改原来的图
	unordered_map<Node*, int>mapHash;
	//存放入度为0的节点
	queue<Node*>in;
	for (size_t i = 0; i < g.node.size(); i++)
	{
		Node* curNode = g.node.at(i);
		mapHash.insert(make_pair(curNode, curNode->in));
		if (curNode->in == 0)in.push(curNode);
	}
	while (!in.empty())
	{
		Node* node = in.front();
		in.pop();
		v.push_back(node->value);
		for (auto& next : node->nexts)
		{
			mapHash.insert(make_pair(next, mapHash.find(next)->second--));
			if (mapHash.find(next)->second == 0)in.push(next);
		}
	}
	return v;
}

//判断是否有环()
class MySets
{
public:
	//节点 以及 对应的集合
	unordered_map<Node*, vector<Node*>>setMap;
	MySets(unordered_map<int, Node*>node)
	{
		for (auto &cur : node)
		{
			vector<Node*>n;
			n.push_back(cur.second);
			setMap.insert(make_pair(cur.second, n));
		}

	}
	bool isSameSet(Node* &from, Node* &to)
	{
		return setMap.at(from) == setMap.at(to);
	}
	void union_(Node* &from, Node* &to)
	{
		vector<Node*>fromSet = setMap.at(from);
		vector<Node*>toSet = setMap.at(to);
		for (auto& toNode : toSet)
		{
			//把to节点集合中所有元素加到from对应集合中
			fromSet.push_back(toNode);
			//setMap.erase(toNode);
			把to节点对应的集合的所有点所对应的集合变为from所属的集合
			//setMap.insert(make_pair(toNode, fromSet));
		}
		for (auto& node : fromSet)
		{
			setMap.erase(node);
			setMap.insert(make_pair(node, fromSet));
		}

	}
};
class C
{
public:
	bool operator()(Edge*e1, Edge*e2)
	{
		return e1->weight > e2->weight;
	}
};
//k算法生成最小生成树
set<int> kruskalMST(Graph &graph)
{
	//小根堆
	priority_queue<Edge*, vector<Edge*>, C>priorityQueue;
	//生成集合
	MySets mysets(graph.node);
	//所有的边加到小根堆
	for (auto edge : graph.edge)
		priorityQueue.push(edge);
	set<int> result;
	while (!priorityQueue.empty())
	{
		Edge* e = priorityQueue.top();//最小的元素
		priorityQueue.pop();
		if (!mysets.isSameSet(e->from, e->to))
		{
			result.insert(e->weight);
			//不在一个集合,加到一个集合
			mysets.union_(e->from, e->to);
		}
	}
	return result;
}
//p算法生成最小生成树
set<int> primMST(Graph& graph)
{
	//小根堆
	priority_queue<Edge*, vector<Edge*>, C>priorityQueue;
	//存放节点
	unordered_set<Node*>setNode;
	set<int>result;
	for (auto& node : graph.node)//防止森林结构(图可能不是连通的)
	{
		if (setNode.find(node.second) == setNode.end())
		{
			setNode.insert(node.second);
			//初始节点所连接的边
			for (auto& edge : node.second->edges)
			{
				priorityQueue.push(edge);
			}
			while (!priorityQueue.empty())
			{
				Edge* e = priorityQueue.top();//最小的
				priorityQueue.pop();
				if (setNode.find(e->to) == setNode.end())
				{
					setNode.insert(e->to);
					result.insert(e->weight);
					//下一个选中节点的边
					for (auto& nextEdge : e->to->edges)
						priorityQueue.push(nextEdge);
				}
			}
		}
	}
	return result;
};

Node* getMinDistanceAndUnselectedNode(unordered_map<Node*, int>distanceMap, unordered_set<Node*>selectedNode)
{
	Node* minNode = nullptr;
	int minValue = INT32_MAX;
	for (auto& node : distanceMap)
	{
		if (selectedNode.find(node.first) == selectedNode.end() && minValue > node.second)
		{
			minNode = node.first;
			minValue = node.second;
		}
	}
	return minNode;
}
//djkstra
unordered_map<Node*, int>dijkstra(Node* head)
{
	unordered_map<Node*, int>distanceMap;//从Node*到head的最小距离是int
	distanceMap.insert(make_pair(head, 0));
	unordered_set<Node*>selectedNode;//记录已经被选择的节点
	Node* minNode = getMinDistanceAndUnselectedNode(distanceMap, selectedNode);//选择最小的节点head
	while (minNode != nullptr)
	{
		int distance = distanceMap.at(minNode);//最短距离
		for (auto& edge : minNode->edges)//遍历该节点邻接的边
		{
			Node* node = edge->to;//边的另一头的点
			if (distanceMap.find(node) == distanceMap.end())
				distanceMap.insert(make_pair(node, distance + edge->weight));
			else
				distanceMap[node] =(min(distanceMap.at(node), distance + edge->weight));
		}
		selectedNode.insert(minNode);
		minNode = getMinDistanceAndUnselectedNode(distanceMap, selectedNode);
	}
	return distanceMap;
}
int main()
{
	vector<vector<int>>matrix;
	vector<int>m1(3);

	m1[0] = 1;
	m1[1] = 2;
	m1[2] = 7;
	matrix.push_back(m1);
	m1[0] = 2;
	m1[1] = 1;
	m1[2] = 7;
	matrix.push_back(m1);
	m1[0] = 1;
	m1[1] = 3;
	m1[2] = 2;
	matrix.push_back(m1);
	m1[0] = 3;
	m1[1] = 1;
	m1[2] = 2;
	matrix.push_back(m1);
	m1[0] = 1;
	m1[1] = 4;
	m1[2] = 100;
	matrix.push_back(m1);
	m1[0] = 4;
	m1[1] = 1;
	m1[2] = 100;
	matrix.push_back(m1);
	m1[0] = 2;
	m1[1] = 4;
	m1[2] = 1000;
	matrix.push_back(m1);
	m1[0] = 4;
	m1[1] = 2;
	m1[2] = 1000;
	matrix.push_back(m1);
	m1[0] = 2;
	m1[1] = 5;
	m1[2] = 10000;
	matrix.push_back(m1);
	m1[0] = 5;
	m1[1] = 2;
	m1[2] = 10000;
	matrix.push_back(m1);
	m1[0] = 3;
	m1[1] = 4;
	m1[2] = 4;
	matrix.push_back(m1);
	m1[0] = 4;
	m1[1] = 3;
	m1[2] = 4;
	matrix.push_back(m1);


	//m1[0] = 0;
	//m1[1] = 1;
	//m1[2] = 5;
	//matrix.push_back(m1);
	//m1[0] = 1;
	//m1[1] = 2;
	//m1[2] = 3;
	//matrix.push_back(m1);
	//m1[0] = 0;
	//m1[1] = 2;
	//m1[2] = 7;
	//matrix.push_back(m1);
	//m1[0] = 0;
	//m1[1] = 3;
	//m1[2] = 6;
	//matrix.push_back(m1);


	/*m1[0] = 1;
	m1[1] = 2;
	m1[2] = 1;
	matrix.push_back(m1);
	m1[0] = 2;
	m1[1] = 1;
	m1[2] = 1;
	matrix.push_back(m1);
	m1[0] = 1;
	m1[1] = 3;
	m1[2] = 1;
	matrix.push_back(m1);
	m1[0] = 3;
	m1[1] = 1;
	m1[2] = 1;
	matrix.push_back(m1);
	m1[0] = 1;
	m1[1] = 4;
	m1[2] = 1;
	matrix.push_back(m1);
	m1[0] = 4;
	m1[1] = 1;
	m1[2] = 1;
	matrix.push_back(m1);
	m1[0] = 3;
	m1[1] = 5;
	m1[2] = 1;
	matrix.push_back(m1);
	m1[0] = 5;
	m1[1] = 3;
	m1[2] = 1;
	matrix.push_back(m1);
	m1[0] = 4;
	m1[1] = 5;
	m1[2] = 1;
	matrix.push_back(m1);
	m1[0] = 5;
	m1[1] = 4;
	m1[2] = 1;
	matrix.push_back(m1);*/


	Graph graph = createGraph(matrix);
	//bfs(graph.node[1]);
	//cout << endl;
	//depthFirstTraversal(graph.node[1]);
	//vector<int> v = topologySorting(graph);
	//for (auto i = v.begin(); i!=v.end(); i++)
	//{
	//	cout << *i << " ";
	//}
	MySets mysets(graph.node);
	//mysets.union_(graph.node.at(1), graph.node.at(2));
	//cout<<mysets.isSameSet(graph.node.at(1), graph.node.at(2));
	set<int> e = primMST(graph);
	unordered_map<Node*, int>s = dijkstra(graph.node.at(1));
	for (auto& x : s)
	{
		cout << x.first->value << ": "<<x.second<<endl;
	}
	return 0;
}
  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
matrix.h: Simple matrix class dsexceptions.h: Simple exception classes Fig01_02.cpp: A simple recursive routine with a test program Fig01_03.cpp: An example of infinite recursion Fig01_04.cpp: Recursive routine to print numbers, with a test program Fig01_05.cpp: Simplest IntCell class, with a test program Fig01_06.cpp: IntCell class with a few extras, with a test program IntCell.h: IntCell class interface (Fig 1.7) IntCell.cpp: IntCell class implementation (Fig 1.8) TestIntCell.cpp: IntCell test program (Fig 1.9) (need to compile IntCell.cpp also) Fig01_10.cpp: Illustration of using the vector class Fig01_11.cpp: Dynamically allocating an IntCell object (lame) BuggyIntCell.cpp: Buggy IntCell class implementation (Figs 1.16 and 1.17) Fig01_18.cpp: IntCell class with pointers and Big Five FindMax.cpp: Function template FindMax (Figs 1.19 and 1.20) Fig01_21.cpp: MemoryCell class template without separation Fig01_25.cpp: Using function objects: Case insensitive string comparison LambdaExample.cpp: (Not in the book): rewriting Fig 1.25 with lambdas MaxSumTest.cpp: Various maximum subsequence sum algorithms Fig02_09.cpp: Test program for binary search Fig02_10.cpp: Euclid's algorithm, with a test program Fig02_11.cpp: Recursive exponentiation algorithm, with a test program RemoveEveryOtherItem.cpp: Remove every other item in a collection Vector.h: Vector class List.h: List class BinarySearchTree.h: Binary search tree TestBinarySearchTree.cpp: Test program for binary search tree AvlTree.h: AVL tree TestAvlTree.cpp: Test program for AVL trees mapDemo.cpp: Map demos WordLadder.cpp: Word Ladder Program and Word Changing Utilities SeparateChaining.h: Header file for separate chaining SeparateChaining.cpp: Implementation for separate chaining TestSeparateChaining.cpp: Test program for separate chaining hash tables (need to compile SeparateChaining.cpp also) QuadraticProbing.h: Header file for quadratic probing hash table QuadraticProbing.cpp: Implementation for quadratic probing hash table TestQuadraticProbing.cpp: Test program for quadratic probing hash tables (need to compile QuadraticProbing.cpp also) CuckooHashTable.h: Header file for cuckoo hash table CuckooHashTable.cpp: Implementation for cuckoo hash table TestCuckooHashTable.cpp: Test program for cuckoo hash tables (need to compile CuckooHashTable.cpp also) CaseInsensitiveHashTable.cpp: Case insensitive hash table from STL (Figure 5.23) BinaryHeap.h: Binary heap TestBinaryHeap.cpp: Test program for binary heaps LeftistHeap.h: Leftist heap TestLeftistHeap.cpp: Test program for leftist heaps BinomialQueue.h: Binomial queue TestBinomialQueue.cpp: Test program for binomial queues TestPQ.cpp: Priority Queue Demo Sort.h: A collection of sorting and selection routines TestSort.cpp: Test program for sorting and selection routines RadixSort.cpp: Radix sorts DisjSets.h: Header file for disjoint sets algorithms DisjSets.cpp: Efficient implementation of disjoint sets algorithm TestFastDisjSets.cpp: Test program for disjoint sets algorithm WordLadder.cpp: Word Ladder Program and Word Changing Utilities Fig10_38.cpp: Simple matrix multiplication algorithm with a test program Fig10_40.cpp: Algorithms to compute Fibonacci numbers Fig10_43.cpp: Inefficient recursive algorithm (see text) Fig10_45.cpp: Better algorithm to replace fig10_43.c (see text) Fig10_46.cpp: Dynamic programming algorithm for optimal chain matrix multiplication, with a test program Fig10_53.cpp: All-pairs algorithm, with a test program Random.h: Header file for random number class Random.cpp: Implementation for random number class TestRandom.cpp: Test program for random number class UniformRandom.h: Random number class using standard library Fig10_63.cpp: Randomized primality testing algorithm, with a test program SplayTree.h: Top-down splay tree TestSplayTree.cpp: Test program for splay trees RedBlackTree.h: Top-down red black tree TestRedBlackTree.cpp: Test program for red black trees Treap.h: Treap TestTreap.cpp: Test program for treap SuffixArray.cpp: Suffix array KdTree.cpp: Implementation and test program for k-d trees PairingHeap.h: Pairing heap TestPairingHeap.cpp: Test program for pairing heaps MemoryCell.h: MemoryCell class interface (Appendix) MemoryCell.cpp: MemoryCell class implementation (Appendix) MemoryCellExpand.cpp: MemoryCell instantiation file (Appendix) TestMemoryCell.cpp: MemoryCell test program (Appendix)

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值