[C++]自己整理考研书上关于树和图的一些简单算法

这些代码和注释都是自己参照书本写的,如有一些注释和代码不对的地方,敬请谅解,仅供参考

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", &gtype);
    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
*/
  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值