starfish,you forget?

yhspring 2001-07-19 06:29:25
http://www.csdn.net/expert/topic/175/175410.shtm
i am waiting for your answer
...全文
41 点赞 收藏 3
写回复
3 条回复
切换为时间正序
当前发帖距今超过3年,不再开放新的回复
发表回复
yhspring 2001-07-28
alonefield,你也不妨把你的贴上来。
回复
Alonefield 2001-07-24
我以前还不知道叫十字链表的说,今天做一道题目,邻接表存不下,又不想动态开空间,于是突发奇想,想到一个方法,没想到,被同学辨认为十字链表的说,!@#$%^&
回复
starfish 2001-07-21
Sorry,这两天比较忙,忘记了。下面是我写的代码:

/*================================================
*
* 用邻接表实现图
*
* file name: graph.h
* Author: starfish
* starfish.h@263.net
*
*===============================================*/

#ifndef _ADT_GRAPH
#define _ADT_GRAPH

#include <iostream.h>
#include "exception.h"

// LABEL_TYPE —— 图的节点的标号类型
// WEIGHT_TYPE —— 图的弧的权的类型


template <class LABEL_TYPE, class WEIGHT_TYPE>
class CGraphNode;

template <class LABEL_TYPE, class WEIGHT_TYPE>
class CGraph;

/////////////////////////////////////////////
// 定义图的弧
template <class LABEL_TYPE, class WEIGHT_TYPE>
class CGraphEdge
{
friend CGraphNode<LABEL_TYPE, WEIGHT_TYPE>;
friend CGraph<LABEL_TYPE, WEIGHT_TYPE>;
friend ostream& operator << (ostream& out, const CGraphEdge<LABEL_TYPE,WEIGHT_TYPE>& edge);
private:
CGraphNode<LABEL_TYPE, WEIGHT_TYPE>* m_pHeadNode; // 弧头节点指针
CGraphNode<LABEL_TYPE, WEIGHT_TYPE>* m_pTailNode; // 弧尾节点指针
CGraphEdge<LABEL_TYPE, WEIGHT_TYPE>* m_pNextEdge; // 下一条弧
public:
WEIGHT_TYPE m_Weight; // 弧的权
public:

// 构造器
CGraphEdge(CGraphNode<LABEL_TYPE, WEIGHT_TYPE>* pHeadNode,
CGraphNode<LABEL_TYPE, WEIGHT_TYPE>* pTailNode,
WEIGHT_TYPE weight,
CGraphEdge<LABEL_TYPE, WEIGHT_TYPE>* pNextEdge = NULL)
{
m_pHeadNode = pHeadNode;
m_pTailNode = pTailNode;
m_Weight = weight;
m_pNextEdge = pNextEdge;
}

// 返回弧头节点指针
CGraphNode<LABEL_TYPE, WEIGHT_TYPE>* HeadNode() { return m_pHeadNode; }

// 返回弧尾节点指针
CGraphNode<LABEL_TYPE, WEIGHT_TYPE>* TailNode() { return m_pTailNode; }

// 返回下一条弧的指针
CGraphEdge<LABEL_TYPE, WEIGHT_TYPE>* NextEdge() { return m_pNextEdge; }

// 设置下一条弧的指针
void SetNextEdge(CGraphEdge<LABEL_TYPE, WEIGHT_TYPE>* pNextEdge) { m_pNextEdge = pNextEdge; }
};

//////////////////////////////////////////////////////
// 定义图的节点
template <class LABEL_TYPE, class WEIGHT_TYPE>
class CGraphNode
{
friend CGraph<LABEL_TYPE, WEIGHT_TYPE>;
friend ostream& operator << (ostream& out, const CGraphNode<LABEL_TYPE,WEIGHT_TYPE>& node);
private:
LABEL_TYPE m_Label; // 节点的标号
CGraphEdge<LABEL_TYPE,WEIGHT_TYPE>* m_pFirstEdge; // 第一条弧的指针
CGraphNode<LABEL_TYPE,WEIGHT_TYPE>* m_pNextNode; // 下一个节点的指针
public:

// 节点构造器
CGraphNode(LABEL_TYPE label, CGraphNode<LABEL_TYPE,WEIGHT_TYPE>* pNextNode = NULL)
{
m_Label = label;
m_pFirstEdge = NULL;
m_pNextNode = pNextNode;
}

// 节点析构器
~CGraphNode() { DeleteAllEdges(); }

// 返回下一个节点的指针
CGraphNode<LABEL_TYPE,WEIGHT_TYPE>* NextNode() { return m_pNextNode; }

// 设置下一个节点的指针
void SetNextNode(CGraphNode<LABEL_TYPE,WEIGHT_TYPE>* pNextNode) { m_pNextNode = pNextNode; }

// 返回第一条边
CGraphEdge<LABEL_TYPE,WEIGHT_TYPE>* FirstEdge() { return m_pFirstEdge; }

// 返回该节点的标号
LABEL_TYPE Label() { return m_Label; }

// 删除从该节点出发的所有弧
void DeleteAllEdges();

// 添加以该节点为弧头,以pNode为弧尾, w为权的弧
CGraphEdge<LABEL_TYPE,WEIGHT_TYPE>* AddEdge(CGraphNode<LABEL_TYPE,WEIGHT_TYPE>* pNode, WEIGHT_TYPE w);

// 返回以该节点为弧头,以标号为v的节点为弧尾的弧
// 如果这样的弧不存在则返回NULL
CGraphEdge<LABEL_TYPE,WEIGHT_TYPE>* FindEdge(LABEL_TYPE v);

// 删除以该节点为弧头,以标号为v的节点为弧尾的弧
bool DeleteEdge(LABEL_TYPE v);

// 重载 [] 操作符以便直接根据下标访问以该节点为弧头,v为弧尾的弧的权
WEIGHT_TYPE& operator[](LABEL_TYPE v);

};

//////////////////////////////////////////////////
// 定义图
template <class LABEL_TYPE, class WEIGHT_TYPE>
class CGraph
{
friend ostream& operator << (ostream& out, const CGraph<LABEL_TYPE,WEIGHT_TYPE>& G);
private:
int m_nNodeCount; // 节点数目
CGraphNode<LABEL_TYPE,WEIGHT_TYPE>* m_pFirstNode; // 第一个节点的指针

public:
CGraph(): m_nNodeCount(0), m_pFirstNode(NULL) { }
~CGraph() { Clear(); }

// 返回图的第一个节点
CGraphNode<LABEL_TYPE,WEIGHT_TYPE>* FirstNode() { return m_pFirstNode; }

// 返回图的节点的数目
int NodeCount() { return m_nNodeCount; }

// 清空整个图
void Clear();

// 加入一个节点
// LABEL_TYPE v, 欲加入的节点的标号
// 成功返回该节点的指针,否则返回NULL
CGraphNode<LABEL_TYPE,WEIGHT_TYPE>* AddNode(LABEL_TYPE v);

// 删除一个节点
// LABEL_TYPE v, 欲删除的节点的标号
// 成功返回true
bool DeleteNode(LABEL_TYPE v);

// 加入一条弧
// LABEL_TYPE u, LABEL_TYPE v 分别为弧的起点和终点
// WEIGHT_TYPE w 为弧的权
// 成功则返回加入的弧,否则返回NULL
CGraphEdge<LABEL_TYPE,WEIGHT_TYPE>* AddEdge(LABEL_TYPE u, LABEL_TYPE v, WEIGHT_TYPE w);

// 删除一条弧
// LABEL_TYPE u, LABEL_TYPE v 分别为弧的起点和终点
// 成功则返回true
bool DeleteEdge(LABEL_TYPE u, LABEL_TYPE v);

// 找到某个节点
// LABEL_TYPE v 该节点的标号
// 成功则返回该节点的指针,否则返回NULL
CGraphNode<LABEL_TYPE,WEIGHT_TYPE>* FindNode(LABEL_TYPE v);

// 找到某条弧
// LABEL_TYPE u, LABEL_TYPE v 分别为弧的起点和终点
// 成功则返回该弧的指针,否则返回NULL
CGraphEdge<LABEL_TYPE,WEIGHT_TYPE>* FindEdge(LABEL_TYPE u, LABEL_TYPE v);

// 重载 [] 操作符以便直接根据下标访问图的节点u
CGraphNode<LABEL_TYPE,WEIGHT_TYPE>& operator[](LABEL_TYPE u);

};


//////////////////////////////////////////////////////
// 删除从该节点出发的所有弧

template <class LABEL_TYPE, class WEIGHT_TYPE>
void CGraphNode<LABEL_TYPE, WEIGHT_TYPE>::DeleteAllEdges()
{
CGraphEdge<LABEL_TYPE,WEIGHT_TYPE>* pEdge;
while ( (pEdge = m_pFirstEdge) != NULL) { // 删除该节点为弧头的所有弧
m_pFirstEdge = m_pFirstEdge->NextEdge();
delete pEdge;
}
}

////////////////////////////////////////////////////////////
// 返回以该节点为弧头,以标号为v的节点为弧尾的弧
// 如果这样的弧不存在则返回NULL

template <class LABEL_TYPE, class WEIGHT_TYPE>
CGraphEdge<LABEL_TYPE,WEIGHT_TYPE>*
CGraphNode<LABEL_TYPE, WEIGHT_TYPE>::FindEdge(LABEL_TYPE v)
{
// 遍历所有以该节点为弧头的弧
CGraphEdge<LABEL_TYPE,WEIGHT_TYPE>* pEdge;
for (pEdge = m_pFirstEdge; pEdge != NULL; pEdge = pEdge->m_pNextEdge) {
if (pEdge->m_pTailNode->m_Label == v) {
break;
}
}
return pEdge;
}

////////////////////////////////////////////////////////////
// 删除以该节点为弧头,以标号为v的节点为弧尾的弧

template <class LABEL_TYPE, class WEIGHT_TYPE>
bool CGraphNode<LABEL_TYPE, WEIGHT_TYPE>::DeleteEdge(LABEL_TYPE v)
{
bool find = false;
CGraphEdge<LABEL_TYPE,WEIGHT_TYPE>* pEdge;

// 第一条弧要单独处理
while ((m_pFirstEdge != NULL) &&
(m_pFirstEdge->m_pTailNode->m_Label == v)) {
pEdge = m_pFirstEdge;
m_pFirstEdge = m_pFirstEdge->m_pNextEdge;
delete pEdge;
find = true;
}
if (m_pFirstEdge == NULL) return find;

// 下面将以"标号为EndNodeLabel的节点"为弧尾的弧删除
pEdge = m_pFirstEdge;
while (pEdge->m_pNextEdge != NULL) {
CGraphEdge<LABEL_TYPE, WEIGHT_TYPE>* tmp = pEdge->m_pNextEdge;
if (tmp->m_pTailNode->m_Label == v) { // 如果弧q的弧尾标号为v
pEdge->m_pNextEdge = tmp->m_pNextEdge; // 删除弧tmp
delete tmp;
find = true;
} else {
pEdge = pEdge->m_pNextEdge;
}
}

return find;
}

////////////////////////////////////////////////////////////
// 添加以该节点为弧头,以pNode为弧尾, w为权的弧

template <class LABEL_TYPE, class WEIGHT_TYPE>
CGraphEdge<LABEL_TYPE,WEIGHT_TYPE>*
CGraphNode<LABEL_TYPE, WEIGHT_TYPE>::AddEdge(CGraphNode<LABEL_TYPE,WEIGHT_TYPE>* pNode, WEIGHT_TYPE w)
{
// 插入新弧
CGraphEdge<LABEL_TYPE,WEIGHT_TYPE>* pNewEdge;
pNewEdge = new CGraphEdge<LABEL_TYPE,WEIGHT_TYPE>(this, pNode, w, this->m_pFirstEdge);
this->m_pFirstEdge = pNewEdge;
return pNewEdge;
}

////////////////////////////////////////////////////////////
// 重载 [] 操作符以便直接根据下标访问以该节点为弧头,v为弧尾的弧的权
template <class LABEL_TYPE, class WEIGHT_TYPE>
WEIGHT_TYPE& CGraphNode<LABEL_TYPE, WEIGHT_TYPE>::operator[](LABEL_TYPE v)
{
CGraphEdge<LABEL_TYPE,WEIGHT_TYPE>* pEdge;
pEdge = FindEdge(v);
if (pEdge == NULL) {
throw new EdgeNotExistsException<LABEL_TYPE>(this->m_Label, v);
} else return (pEdge->m_Weight);
}


////////////////////////////////////////////////
// 清空整个图

template <class LABEL_TYPE, class WEIGHT_TYPE>
void CGraph<LABEL_TYPE, WEIGHT_TYPE>::Clear()
{
CGraphNode<LABEL_TYPE,WEIGHT_TYPE>* pNode;
while ((pNode = m_pFirstNode) != NULL) { // 删除每个节点
m_pFirstNode = m_pFirstNode->NextNode();
delete pNode;
}
m_nNodeCount = 0;
}

///////////////////////////////////////////////////
// 加入一个节点
// LABEL_TYPE v, 欲加入的节点的标号
// 成功返回该节点的指针,否则返回NULL

template <class LABEL_TYPE, class WEIGHT_TYPE>
CGraphNode<LABEL_TYPE,WEIGHT_TYPE>* CGraph<LABEL_TYPE, WEIGHT_TYPE>::AddNode(LABEL_TYPE v)
{
if (FindNode(v) != NULL) return NULL; // 如果该节点已经存在则失败返回

// 将pNode插入节点链表的前端
CGraphNode<LABEL_TYPE,WEIGHT_TYPE>* pNode;
pNode = new CGraphNode<LABEL_TYPE,WEIGHT_TYPE>(v, m_pFirstNode);
m_pFirstNode = pNode;
m_nNodeCount++;
return pNode;
}

///////////////////////////////////////////////////
// 删除一个节点
// LABEL_TYPE label, 欲删除的节点的标号
// 成功返回true;

template <class LABEL_TYPE, class WEIGHT_TYPE>
bool CGraph<LABEL_TYPE, WEIGHT_TYPE>::DeleteNode(LABEL_TYPE v)
{
if ((m_nNodeCount==0) || (m_pFirstNode==NULL)) return false;

// 删除标号为v的节点
if (m_pFirstNode->m_Label == v) { // 如果该节点是第一个节点,需要特殊处理
CGraphNode<LABEL_TYPE,WEIGHT_TYPE>* pNode = m_pFirstNode;
m_pFirstNode = m_pFirstNode->m_pNextNode;
delete pNode;
m_nNodeCount--;
} else {
CGraphNode<LABEL_TYPE,WEIGHT_TYPE>* pre = m_pFirstNode;
CGraphNode<LABEL_TYPE,WEIGHT_TYPE>* pNode;

for (pNode = m_pFirstNode->m_pNextNode; pNode != NULL; pNode = pNode->m_pNextNode) {
if (pNode->m_Label == v) break;
pre = pNode;
}
pre->m_pNextNode = pNode->m_pNextNode;
delete pNode;
m_nNodeCount--;
}

// 删除所有以标号为v的节点为弧尾的弧
CGraphNode<LABEL_TYPE,WEIGHT_TYPE>* pNode;
for (pNode = m_pFirstNode; pNode != NULL; pNode = pNode->m_pNextNode) {
pNode->DeleteEdge(v);
}

return true;
}


////////////////////////////////////////////////////
// 加入一条弧
// LABEL_TYPE u, LABEL_TYPE v 分别为弧的起点和终点;
// WEIGHT_TYPE w 为弧的权
// 成功则返回加入的弧,否则返回NULL

template <class LABEL_TYPE, class WEIGHT_TYPE>
CGraphEdge<LABEL_TYPE,WEIGHT_TYPE>*
CGraph<LABEL_TYPE, WEIGHT_TYPE>::AddEdge(LABEL_TYPE u, LABEL_TYPE v, WEIGHT_TYPE w)
{
// 找到标号为u的节点,如果该节点不存在就新建一个标号为u的节点
CGraphNode<LABEL_TYPE,WEIGHT_TYPE>* pNodeU;
pNodeU = FindNode(u);
if (pNodeU == NULL) {
pNodeU = AddNode(u);
}
// 找到标号为v的节点,如果该节点不存在就新建一个标号为v的节点
CGraphNode<LABEL_TYPE,WEIGHT_TYPE>* pNodeV;
pNodeV = FindNode(v);
if (pNodeV == NULL) {
pNodeV = AddNode(v);
}

// 添加一条新弧<u,v>:w
return pNodeU->AddEdge(pNodeV, w);
}

////////////////////////////////////////////////////
// 删除一条弧
// LABEL_TYPE u, LABEL_TYPE v 分别为弧的起点和终点;
// 成功则返回true

template <class LABEL_TYPE, class WEIGHT_TYPE>
bool CGraph<LABEL_TYPE, WEIGHT_TYPE>::DeleteEdge(LABEL_TYPE u, LABEL_TYPE v)
{
// 找到标号为u的节点
CGraphNode<LABEL_TYPE,WEIGHT_TYPE>* pNodeU;
pNodeU = FindNode(u);
if (pNodeU == NULL) return false;

// 删除以u为弧头,v为弧为的弧
return pNodeU->DeleteEdge(v);
}

///////////////////////////////////////////////////
// 找到某个节点
// LABEL_TYPE v 该节点的标号
// 成功则返回该节点的指针,否则返回NULL

template <class LABEL_TYPE, class WEIGHT_TYPE>
CGraphNode<LABEL_TYPE,WEIGHT_TYPE>*
CGraph<LABEL_TYPE, WEIGHT_TYPE>::FindNode(LABEL_TYPE v)
{
CGraphNode<LABEL_TYPE,WEIGHT_TYPE>* pNode;
for (pNode = m_pFirstNode; pNode != NULL; pNode = pNode->m_pNextNode) {
if (pNode->m_Label == v) break;
}
return pNode;
}

///////////////////////////////////////////////////
// 找到某条弧
// LABEL_TYPE u, LABEL_TYPE v 分别为弧的起点和终点
// 成功则返回该弧的指针,否则返回NULL

template <class LABEL_TYPE, class WEIGHT_TYPE>
CGraphEdge<LABEL_TYPE,WEIGHT_TYPE>*
CGraph<LABEL_TYPE, WEIGHT_TYPE>::FindEdge(LABEL_TYPE u, LABEL_TYPE v)
{
// 找到标号为u的节点
CGraphNode<LABEL_TYPE,WEIGHT_TYPE>* pNodeU;
pNodeU = FindNode(u);
if (pNodeU == NULL) return NULL;

// 返回以u为弧头,v为弧尾的弧
return pNodeU->FindEdge(v);
}

///////////////////////////////////////////////////
// 重载 [] 操作符以便直接根据下标访问图的节点u

template <class LABEL_TYPE, class WEIGHT_TYPE>
CGraphNode<LABEL_TYPE,WEIGHT_TYPE>&
CGraph<LABEL_TYPE, WEIGHT_TYPE>::operator[](LABEL_TYPE u)
{
// 找到标号为u的节点
CGraphNode<LABEL_TYPE,WEIGHT_TYPE>* pNodeU;
pNodeU = FindNode(u);
if (pNodeU == NULL) {
throw new NodeNotExistsException<LABEL_TYPE>(u);
} else return (*pNodeU);
}


////////////////////////////////////////////////////
//
// 重载输出运算符
//

template <class LABEL_TYPE, class WEIGHT_TYPE>
ostream& operator << (ostream& out, const CGraphEdge<LABEL_TYPE,WEIGHT_TYPE>& edge)
{
out << "<" << (*edge.m_pHeadNode)
<< "," << (*edge.m_pTailNode)
<< ":" << (edge.m_Weight)
<< ">";
return out;
}

template <class LABEL_TYPE, class WEIGHT_TYPE>
ostream& operator << (ostream& out, const CGraphNode<LABEL_TYPE,WEIGHT_TYPE>& node)
{
out << node.m_Label;
return out;
}

template <class LABEL_TYPE, class WEIGHT_TYPE>
ostream& operator << (ostream& out, const CGraph<LABEL_TYPE,WEIGHT_TYPE>& G)
{
CGraphNode<LABEL_TYPE,WEIGHT_TYPE>* pNode;
CGraphEdge<LABEL_TYPE,WEIGHT_TYPE>* pEdge;

for (pNode = G.m_pFirstNode; pNode != NULL; pNode = pNode->NextNode()) {
for (pEdge = pNode->FirstEdge(); pEdge != NULL; pEdge = pEdge->NextEdge()) {
out << (*pEdge) << endl;
}
}
return out;
}

////////////////////////////////////////////////////////////////
//
// 重载输入运算符
//

template <class LABEL_TYPE, class WEIGHT_TYPE>
istream& operator >> (istream& in, CGraph<LABEL_TYPE,WEIGHT_TYPE>& G)
{
// 输入格式 (u v w) ,三个项之间用空格隔开,左右必须有括号()

LABEL_TYPE u,v;
WEIGHT_TYPE w;
char c;
while ( !in.eof() ) {
in >> c; // 读入左括号
in >> u;
in >> v;
in >> w;
in >> c; // 读入右括号
if (! in.fail() )
G.AddEdge(u, v, w);
}
return in;
}

#endif




/*================================================
*
* 一些异常声明
*
* file name: exception.h
* Author: starfish
* starfish.h@263.net
*
*===============================================*/
#ifndef _ADT_EXCEPTION
#define _ADT_EXCEPTION

#include <iostream.h>

// LABEL_TYPE —— 图的节点的标号类型

// 节点不存在发生的异常
template <class LABEL_TYPE>
class NodeNotExistsException
{
private:
LABEL_TYPE m_NodeLabel;
public:
NodeNotExistsException(LABEL_TYPE v) {
m_NodeLabel = v;
}
friend ostream& operator << (ostream& out, const NodeNotExistsException<LABEL_TYPE>& e);
};

// 重载输出运算符
template <class LABEL_TYPE>
ostream& operator << (ostream& out, const NodeNotExistsException<LABEL_TYPE>& e)
{
out << "An Exception occurs. "
<< endl
<< "The node "
<< e.m_NodeLabel
<< " does not exist."
<< endl;
return out;
}


// 弧不存在时发生的异常
template <class LABEL_TYPE>
class EdgeNotExistsException
{
private:
LABEL_TYPE m_HeadNodeLabel, m_TailNodeLabel;
public:
EdgeNotExistsException(LABEL_TYPE HeadNodeLabel, LABEL_TYPE TailNodeLabel) {
m_HeadNodeLabel = HeadNodeLabel;
m_TailNodeLabel = TailNodeLabel;
}
friend ostream& operator << (ostream& out, const EdgeNotExistsException<LABEL_TYPE>& e);
};


// 重载输出运算符
template <class LABEL_TYPE>
ostream& operator << (ostream& out, const EdgeNotExistsException<LABEL_TYPE>& e)
{
out << "An Exception occurs. "
<< endl
<< "The edge <"
<< e.m_HeadNodeLabel
<< ","
<< e.m_TailNodeLabel
<< "> does not exist."
<< endl;
return out;
}

#endif




/*
用来测试邻接表实现图
testgraph.cpp
*/
#include <iostream.h>
#include <iomanip.h>
#include <fstream.h>
#include <assert.h>
#include "graph.h"

#define INPUT_FILE_1 "graph.in1"
#define INPUT_FILE_2 "graph.in2"

void main()
{
ifstream fin(INPUT_FILE_1,ios::nocreate );
assert(! fin.fail());
CGraph<int, int> G1;
fin >> G1;
cout << "Here is the graph1: "
<< endl
<< G1;

int i, j;
cout << "used [] to access graph metrix:" << endl;
for (i=0; i<6; i++) {
for (j=0; j<6; j++) {
try {
cout << setw(4) << G1[i][j];
} catch (EdgeNotExistsException<int>* pE) {
cout << setw(4) << "∞";
delete pE;
} catch (NodeNotExistsException<int>* pE) {
cout << (*pE);
delete pE;
}
}
cout << endl;
}

cout << "test the exception. " << endl;
for (i = 0; i<6; i++) {
for (j=4; j<6; j++) {
try {
cout << setw(4) << G1[i][j];
} catch (EdgeNotExistsException<int>* pE) {
cout << (*pE);
delete pE;
} catch (NodeNotExistsException<int>* pE) {
cout << (*pE);
delete pE;
}
}
cout << endl;
}


fin.close();

fin.open(INPUT_FILE_2,ios::nocreate );
assert(! fin.fail());
CGraph<char, float> G2;
fin >> G2;
cout << "Here is the graph2: "
<< endl
<< G2;
fin.close();
}


下面是两个测试用的数据文件:
graph.in1 文件的内容:
(0 5 1)
(5 1 5) (5 2 0) (1 2 9) (3 4 2) (4 2 3) (5 3 3)
(5 4 8) (2 4 1) (3 2 6)
(0 0 5)
graph.in2 文件的内容
(a b 1.0)
(c d 5.5) (c e 0) (a c .9)
(c f 8.789) (b e 1.82) (d f 6.00)
回复
相关推荐
发帖
数据结构与算法
创建于2007-08-27

3.2w+

社区成员

数据结构与算法相关内容讨论专区
申请成为版主
帖子事件
创建了帖子
2001-07-19 06:29
社区公告
暂无公告