这些代码和注释都是自己参照书本写的,如有一些注释和代码不对的地方,敬请谅解,仅供参考
树
1.树的结构体
//二叉树
typedef struct BiLNod
{
ElemType data;
struct BiLNod* rchild;
struct BiLNod* lchild;
}BiTree;
//线索二叉树
typedef struct ThreadNode {
ElemType data;
struct ThreadNode* lchild;
struct ThreadNode* rchild;
int ltag, rtag;
}ThreadTree;
2.二叉树的创建
BiTree* createBTree()
{
int data;
BiTree* T;
scanf_s("%d", &data);
if (data != 0)
{
T = (BiTree*)malloc(sizeof(BiTree));
T->data = data;
T->lchild = createBTree();
T->rchild = createBTree();
}
else
{
T = NULL;
}
return T;
}
3.遍历
3.1 先序遍历
void PreOrder(BiTree *T) {
if (T!=NULL) {
std::cout << T->data;
PreOrder(T->lchild);
PreOrder(T->rchild);
}
}
3.2深度遍历
int DepthOreder(BiTree *T) {
int LD, RD;
if (T) {
LD = DepthOreder(T->lchild)+1;
RD = DepthOreder(T->rchild)+1;
return LD > RD ? LD : RD;
}
else {
return 0;
}
}
3.3层次遍历
//层次遍历 Queue[MaxSize]
void LevelOrder(BiTree* T) {
BiTree* Queue[MaxSize];
int front, rear;
front = rear = 0;
BiTree* p;
if (!T) {
std::cout << "NULL";
return;
}
rear = (rear + 1) % MaxSize;
Queue[rear] = T;
while (front != rear) {
front = (front + 1) % MaxSize;
p = Queue[front];
std::cout << p->data;
if (p->lchild) {
rear = (rear + 1) % MaxSize;
Queue[rear] = p->lchild;
}
if (p->rchild) {
rear = (rear + 1) % MaxSize;
Queue[rear] = p->rchild;
}
}
}
3.4 非递归前序遍历
//天勤
void NonRecursionPreOrder1(BiTree* T) {
BiTree* Stack[MaxSize];
int top = -1;
BiTree* p;
Stack[++top] = T;
while (top!=-1)
{
p = Stack[top--];
std::cout << p->data;
//右子树先入栈,左子树再入栈
if (p->rchild != NULL) {
Stack[++top] = p->rchild;
}
if (p->lchild != NULL) {
Stack[++top] = p->lchild;
}
}
}
//王道
void NonRecursionPreOrder2(BiTree* T) {
BiTree* Stack[MaxSize];
int top = -1;
BiTree* p = T;
while (p || top != -1) {
if (p) {
Stack[++top] = p;
std::cout << p->data;
p = p->lchild;
}
else {
p = Stack[top--];
p = p->rchild;
}
}
}
3.5 非递归中序遍历
void NonRecursionInOrder1(BiTree *T) {
BiTree* Stack[MaxSize];
int top = -1;
BiTree *p = T;
while (top != -1||p!=NULL)
{
while (p != NULL) {
Stack[++top] = p;
p = p->lchild;
}
p = Stack[top--];
std::cout << p->data;
p = p->rchild;
}
}
void NonRecursionInOrder2(BiTree* T) {
BiTree* Stack[MaxSize];
int top = -1;
BiTree* p = T;
while (top!=-1||p) {
if (p) {
Stack[++top] = p;
p = p->lchild;
}
else {
p = Stack[top--];
std::cout << p->data;
p = p->rchild;
}
}
}
3.6 非递归后续遍历
void NonRescursionPostOrder(BiTree* T) {
BiTree* Stack[MaxSize];
int top = -1;
BiTree* p = T;
BiTree* r = NULL;
while (top!=-1||p)
{
if (p) {
Stack[++top] = p;
p = p->lchild;
}
else {
p = Stack[top]; //只读
if (p->rchild && p->rchild != r) { //右子树存在且未被访问过 p->rchild != r 左、右、中 r不是指向p的左子树就是右子树
//这是r一定只想的事p的左子树,指向右子树时,说明右子树已经被访问过了
//入栈
p = p->rchild;
Stack[++top] = p;
p = p->lchild;
}
else {
//出栈 输出
p = Stack[top--];
std::cout << p->data;
r = p; //r记录最新访问的节点
p = NULL; //重置p指针
}
}
}
}
图
1.图的结构体
//邻接矩阵
typedef struct {
char Vex[Maxsize];
int Edge[Maxsize][Maxsize];
int vexnum, arcnum;
}MGraph;
//邻接表
typedef struct ArcNode {
int adjvex;
struct ArcNode* next;
}ArcNode;
typedef struct VNode {
char data;
ArcNode* first;
}AdjList;
typedef struct {
AdjList vertices[Maxsize];
int vexnum, arcnum;
}ALGraph;
//还有十字链表和邻接多重表
2.图的创建输出
//创建邻接矩阵(0.无向图,1.有向图)
void creatMGraph(MGraph& M)
{
int i, j, k, weight, gtype;
std::cout << "请输入图类型 无向图0 有向图1\n";
scanf_s("%d", >ype);
std::cout << "请输入顶点数\n";
scanf_s("%d", &M.vexnum);
std::cout << "请输入边数\n" ;
scanf_s("%d", &M.arcnum);
for (i = 0; i < M.vexnum; ++i)
{
for (j = 0; j < M.vexnum; j++)
{
M.Edge[i][j] = INF;
}
}
std::cout << "请输入边信息a b c\n";
k = 0;
while (k < M.arcnum)
{
weight = 0;
scanf_s("%d%d%d", &i, &j, &weight);
if (i < M.vexnum && j < M.vexnum) //顶点从0开始
{
if (gtype == 0)
{
M.Edge[i][j] = weight;
M.Edge[j][i] = weight;
}
else
{
M.Edge[i][j] = weight;
}
k++;
}
else
{
std::cout << "输入失败,请重输!\n";
}
}
}
void printfMGraph(MGraph M)
{
for (int i = 0; i < M.vexnum; ++i)
{
for (int j = 0; j < M.vexnum; ++j)
{
printf("%d ", M.Edge[i][j]);
}
std::cout << "\n";
}
}
//邻接表
ALGraph creatALGraph()
{
ALGraph AL;
ArcNode* p;
int i, j, k, n, e;
std::cout<<"请输入顶点数\n";
scanf_s("%d", &n);
AL.vexnum = n;
std::cout << "请输入边数\n";
scanf_s("%d", &e);
AL.arcnum = e;
std::cout << "请输入边信息a b\n";
//初始化firstarc
for (k = 0; k < n; ++k)
{
AL.vertices[k].first = (ArcNode*)malloc(sizeof(ArcNode));
AL.vertices[k].first = NULL;
}
k = 0;
while (k < e)
{
scanf_s("%d%d", &i, &j);
if (i < n && j < n)
{
ArcNode* q = AL.vertices[i].first;
if (q == NULL) {
q = (ArcNode*)malloc(sizeof(ArcNode));
//q为空指针
q->adjvex = j;
q->next = NULL;
AL.vertices[i].first = q;
}
else {
while (q->next)
{
q = q->next;
}
p = (ArcNode*)malloc(sizeof(ArcNode));
p->adjvex = j;
p->next = NULL;
q->next = p;
}
//顶点j前驱+1
k++;
}
else
{
std::cout << "输入失败,请重输!\n";
}
}
return AL;
}
void printfALGraph(ALGraph AL)
{
int i;
ArcNode* p;
for (i = 0; i < AL.vexnum; ++i)
{
printf("%d->", i);
p = AL.vertices[i].first;
while (p != NULL)
{
printf("%d->", p->adjvex);
p = p->next;
}
std::cout << "\n";
}
}
3.广度优先遍历
//广度优先遍历 BFS 队列
bool vistited[Maxsize]; //通过数组标记结点是否被访问过
void BFS(ALGraph AL, int v) {
ArcNode* p;
int k;
int queue[Maxsize];
int front, rear;
front = rear = 0;
rear = (++rear) % Maxsize;
queue[rear] = v;
vistited[v] = true;
std::cout << v;
while (rear != front) {
front = (++front) % Maxsize;
k = queue[front];
p = AL.vertices[k].first;
while (p != NULL) {
k = p->adjvex;
if (!vistited[k]) {
std::cout << p->adjvex;
vistited[p->adjvex] = true;
rear = (++rear) % Maxsize;
queue[rear] = p->adjvex;
}
p = p->next;
}
}
}
4.深度优先遍历
void DFS(ALGraph AL,int v) {
ArcNode* p = AL.vertices[v].first;
vistited[v] = true;
std::cout << v;
while (p!=NULL)
{
int k = p->adjvex;
if (!vistited[k]) {
DFS(AL, k);
}
p = p->next;
}
}
5.最小(代价)生成树
int Prim(MGraph M,int v0) {
int lowcast[Maxsize],i,j,v,sum; //还有一个Visited(全局变量)
for ( i = 0; i < M.vexnum; i++)
{
lowcast[i] = M.Edge[v0][i];
}
sum = 0;
v = v0;
vistited[v0] = true;
for (i = 0; i < M.vexnum - 1; ++i) {
int min = INF;
int k = 0;
for (j = 0; j < M.vexnum; ++j) {
if (min > lowcast[j]&&!vistited[j]) {
min = lowcast[j];
k = j;
}
}
vistited[k] = true;
sum += min;
for (j = 0; j < M.vexnum; ++j) {
if (lowcast[j] > M.Edge[k][j]) {
lowcast[j] = M.Edge[k][j];
}
}
}
return sum;
}
//测试数据
/*
lowcast 目前距已访问过的点的最短距离 最短路径是距v0的最短距离
请输入图类型 无向图0 有向图1
0
请输入顶点数
5
请输入边数
8
请输入边信息a b c
0 1 5
0 2 1
0 3 2
1 2 3
2 3 6
1 4 4
2 4 2
3 4 3
8
*/
//克鲁斯卡尔
typedef struct
{
int a, b;
int w;
}Road;
void createRoad(MGraph M, Road (&road)[Maxsize])
{
int i, j, k;
k = 0;
for (i = 0; i < M.n; i++)
{
for (j = i; j < M.n; j++)
{
if (M.edge[i][j] != INF)
{
road[k].a = i;
road[k].b = j;
road[k].w = M.edge[i][j];
//cout <<road[k].a << road[k].b<< road[k].w<< endl;
k++;
}
}
}
}
void sort(Road(&road)[Maxsize],int E)
{
Road r;
for (int i = 0; i < E; ++i)
{
for (int j = i+1; j < E; ++j)
{
if (road[i].w > road[j].w)
{
r = road[i];
road[i] = road[j];
road[j] = r;
}
}
}
}
int v[Maxsize]; //v[i]存放第i点的母节点
int getRoot(int a)
{
while (v[a] != a) a = v[a];
return a;
}
void Kruskal(MGraph M, int& sum, Road road[])
{
int i;
int N, E, a,b;
N = M.n;
E = M.e;
sum = 0;
for (i = 0; i < N; ++i) v[i] = i;
//sort(road,E);
for ( i = 0; i < E; ++i)
{
cout << road[i].a << road[i].b <<endl;
a = getRoot(road[i].a);
b = getRoot(road[i].b);
if (a != b)
{
v[a] = b;
sum += road[i].w;
//cout << sum << endl;
}
}
/*
0 2 1
0 3 2
2 4 2
1 2 3
3 4 3
1 4 4
0 1 5
2 3 6
*/
}
6.最短路径
void printfPath(int path[], int a)
{
int stack[Maxsize], top = -1;
while (path[a] != -1)
{
stack[++top] = a;
a = path[a];
}
while (top != -1)
printf("%d ", stack[top--]);
}
void Dijkstra(MGraph M, int v, int dist[], int path[])
{
int set[Maxsize];
int min, i, j, u;
for ( i = 0; i < M.n; ++i) //初始化
{
dist[i] = M.edge[v][i]; //注意是v
set[i] = 0;
if (M.edge[v][i] != INF)
path[i] = v;
else
path[i] = -1;
}
set[v] = 1; path[v] = -1;
for (i = 0; i < M.n - 1; ++i)
{
min = INF;
for (j = 0; j < M.n; ++j)
{
if (set[j] == 0 && dist[j] < min)
{
min = dist[j];
u = j;
}
}
set[u] = 1;
for (j = 0; j < M.n; ++j)
{
if (set[j] == 0 && dist[j] > dist[u] + M.edge[u][j])
{
dist[j] = dist[u] + M.edge[u][j];
path[j] = u; //这里改path
}
}
}
for (i = 0; i < M.n; ++i)
if (i != v) {
printfPath(path, i);
cout<<""<<endl;
}
}
/*
请输入图类型 无向图0 有向图1
1
请输入顶点数
7
请输入边数
12
请输入边信息a b c
0 1 4
0 2 6
0 3 6
1 2 1
1 4 7
2 4 6
2 5 4
3 2 2
3 5 5
4 6 6
5 4 1
5 6 8
*/
7.拓扑序列
int TopSort(AGraph A)
{
int i, j, n = 0;
int stack[Maxsize], top = -1;
ArcNode* p;
for (i = 0; i < A.n; ++i)
{
if (A.adjlist[i].count == 0)
stack[++top] = i;
}
while (top != -1)
{
i = stack[top--];
++n;
cout<<i<<endl;
p = A.adjlist[i].firstarc;
p = p->nextarc;
while (p!=NULL)
{
j = p->adjvex;
if ((--A.adjlist[j].count) == 0)
{
stack[++top] = j;
}
p = p->nextarc;
}
}
if (n == A.n)
return 1;
else
return 0;
}
/*
请输入顶点数
7
请输入边数
11
请输入边信息a b
0 1
0 2
0 3
1 2
1 4
2 4
2 5
3 5
4 6
5 4
5 6
*/