算法笔记 12-19

1.二叉树的构建、遍历和完全二叉树的判断

#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MaxSize 100

using namespace std;


typedef char ElemType;

typedef struct node {
    ElemType data;
    struct node* lchild;
    struct node* rchild;
}BTNode;

//实例化二叉树
void BT_Create(BTNode*& b, const char* str) {
    BTNode* St[MaxSize], * p=NULL;
    int top = -1 , k , j = 0;
    char ch;
    b = NULL;
    ch = str[j];
    //str未结束时循环
    while (ch != '\0') {
        switch (ch) {
        case '(':top++; St[top] = p; k = 1; break;//处理左子树
        case ')':top--; break;//处理完毕一个子树
        case ',':k = 2; break;//开始处理右子树(括号中‘,’右边的是右子树,左边是左子树)
        default:p = (BTNode*)malloc(sizeof(BTNode));
            p->data = ch;
            p->lchild = p->rchild = NULL;//对该小枝叉进行初始化
            if (b == NULL)
                b = p;//若b树为空,则将p设为b的root节点
            else {
                switch (k) {
                case 1:St[top]->lchild = p; break;
                case 2:St[top]->rchild = p; break;
                }
            
            }
        }
        j++;
        ch = str[j];
    }
}

void BT_Destory(BTNode* &b) {
    if (b != NULL) {
        BT_Destory(b->lchild);
        BT_Destory(b->rchild);
        free(b);
    }
    
}

BTNode* BT_FindNode(BTNode* b, ElemType x) {
    BTNode* p;
    if (b == NULL) {
        return NULL;
    }
    else if (b->data == x)
        return b;
    else {
        p = BT_FindNode(b->lchild, x);
        if (p != NULL)
            return p;
        else 
            return BT_FindNode(b->rchild, x);
    }
}

BTNode* BT_LchildNode(BTNode* b) {

    return b->lchild;
}

BTNode* BT_RchildNode(BTNode* b) {

    return b->rchild;
}

int BT_Height(BTNode* b) {
    int lchildh, rchildh;
    if (b == NULL)
        return 0;
    else {
        lchildh = BT_Height(b->lchild);
        rchildh = BT_Height(b->rchild);
        return 1 + max(rchildh, lchildh);
    }
}

void BT_Display(BTNode* b) {
    
    if (b != NULL) {
        printf("%c", b->data);
        if (b->lchild != NULL || b->rchild != NULL) {
            printf("(");
            BT_Display(b->lchild);
            if (b->rchild != NULL)
                printf(",");
            BT_Display(b->rchild);
            printf(")");
        }
    }
}
//测试
/*
int main()
{
    BTNode* b, * p, * lp, * rp;
    printf("创建二叉树:\n");
    BT_Create(b,"A(B(D,E(H(J,K(L,M(,N))))),C(F,G(,I)))");
    printf("输出二叉树:\n");
    BT_Display(b);
    printf("\n");
    printf("H节点:\n");
    p = BT_FindNode(b, 'H');
    if (p != NULL) {
        lp = BT_LchildNode(p);
        if (lp != NULL)
            printf("lchild:%c", lp->data);
        else printf("lchild is NULL ");
        printf("\n");
        rp = BT_RchildNode(p);
        if (rp != NULL)
            printf("rchild:%c", rp->data);
        else printf("rchild is NULL ");

    }
    printf("\n");
    printf("the BT_Height is :%d\n", BT_Height(b));
    printf("free the BT\n");
    BT_Destory(b);
    return 0;
}


*/

//二叉树的几种遍历算法
//先序遍历递归
void PreOrder(BTNode* b) {

    if (b != NULL) {
        printf("%c", b->data);
        PreOrder(b->lchild);
        PreOrder(b->rchild);
    }
}

//先序遍历非递归
void PreOrder1(BTNode* b) {
    BTNode* St[MaxSize], * p;
    int top = -1;
    if (b != NULL) {
        top++;
        St[top] = b;
        while (top > -1) {
            //中
            p = St[top];
            top--;
            printf("%c", p->data);
            //右
            if (p->rchild != NULL) {
                top ++ ;
                St[top] = p->rchild;
            }
            //左
            if (p->lchild != NULL) {
                top++;
                St[top] = p->lchild;

            }
        }
        printf("\n");
    }
    //用数组St[MaxSize]存遍历过的节点
    //因为是按顺序栈来存,因此进栈顺序为中->右->左,出栈后得正常的前序序列
}

//中序遍历递归
void InOrder(BTNode* b) {
    if (b != NULL) {
        //前->中->后
        InOrder(b->lchild);
        printf("%c", b->data);
        InOrder(b->rchild);
    }

}

//中序遍历非递归
void InOrder1(BTNode* b) {
    BTNode* St[MaxSize], * p;
    int top = -1;
    if (b != NULL) {
        p = b;
        while (top > -1 || p != NULL) {
            while (p != NULL) {
                top++;
                St[top] = p;
                p = p->lchild;
            }
            if (top > -1) {
                p = St[top];
                top--;
                printf(" % c", p->data);
                p = p->rchild;
            }
        }
        printf("\n");
    }

}

//后序遍历递归
void PostOrder(BTNode* b) {
    if (b != NULL) {
        PostOrder(b->lchild);
        PostOrder(b->rchild);
        printf("%c", b->data);
    }

}

//后序遍历非递归
void PostOrder1(BTNode* b) {
    BTNode* St[MaxSize],*p;
    int top = -1;
    bool flag;
    if (b != NULL) {
        do {
            while (b != NULL) {
                top++;
                St[top] = b;
                b = b->lchild;
            }
            p = NULL;
            flag = true;
            while (top != -1 && flag) {
                b = St[top];
                if (b->rchild == p) {
                    printf("%c", b->data);
                    top--;
                    p = b;
                }
                else {
                    b = b->rchild;
                    flag = false;

                }
            }
    }while (top != -1);
    printf("\n");
    }

}

//层序遍历

void TravLevel(BTNode* b) {
    BTNode* Qu[MaxSize];
    int front=0, rear=0;
    if (b != NULL)printf("%c", b->data);
    rear++;
    Qu[rear] = b;
    while(rear!=front){
        front = (front + 1) % MaxSize;
        b = Qu[front];
        if(b->lchild!=NULL){
            printf("%c", b->lchild->data);
            rear = (rear + 1) % MaxSize;
            Qu[rear] = b->rchild;
        } 
        if (b->rchild != NULL) {
            printf("%c", b->rchild->data);
            rear = (rear + 1) % MaxSize;
            Qu[rear] = b->rchild;
        }
    }
    printf("\n");
}
//测试
/*
int main()
{
    BTNode* b;
    BT_Create(b,"A(B(D,E(H(J,K(L,M(,N))))),C(F,G(,I)))");
    printf("二叉树b:\n");
    BT_Display(b);
    printf("\n");
    printf("层次遍历:\n");
    printf("先序遍历:\n");
    printf("递归算法:\n"); PreOrder(b); printf("\n");
    printf("非递归:\n"); PreOrder1(b); printf("\n");
    printf("中序遍历:\n"); 
    printf("递归算法:\n");InOrder(b); printf("\n");
    printf("非递归:\n"); InOrder1(b); printf("\n");
    printf("后序遍历:\n");
    printf("递归算法:\n"); PostOrder(b); printf("\n");
    printf("非递归:\n"); PostOrder1(b); printf("\n");
    BT_Destory(b);
    return 0;
}
*/
//判断二叉树是否为完全二叉树
bool Full_TravLevel(BTNode* b) {
    BTNode* Qu[MaxSize];
    int front = 0, rear = 0;
    int t = 0, depth = BT_Height(b);
    bool flag = true;
    if (b != NULL)printf("%c", b->data);
    rear++;
    Qu[rear] = b;
    t++;
    while (rear != front) {
        t++;
        front = (front + 1) % MaxSize;
        b = Qu[front];
        if (b->lchild != NULL) {
            printf("%c", b->lchild->data);
            rear = (rear + 1) % MaxSize;
            Qu[rear] = b->lchild;
            if ((b->rchild == NULL) && t < (int)pow(2, (depth - 1)))
                return false;
        }
        if (b->rchild != NULL) {
            printf("%c", b->rchild->data);
            rear = (rear + 1) % MaxSize;
            Qu[rear] = b->rchild;
        }

        if ((b->lchild == NULL || b->rchild == NULL) && t < depth - 1) {
            return false;
        }
        if (b->lchild == NULL && b->rchild != NULL)
            return false;
        
    }
    printf("\n");
    return flag;
}


2.图的基本算法和遍历(DFS/BFS)

#include <stdio.h>
#include <malloc.h>
#define INF 32767
#define MAXV 100
typedef char InfoType;

typedef struct {
    int no;//顶点编号
    InfoType info;//顶点其他信息
}VertexType;//顶点类型

typedef struct {
    int edges[MAXV][MAXV];//邻接矩阵数组
    int n, e;//顶点数,边数
    VertexType vexs[MAXV];//存放顶点信息
}MatGraph;//完整的图邻接矩阵类型

typedef struct ANode {
    int adjvex;//该边的邻接点编号
    struct ANode* nextarc;//指向下一条边的指针
    int weight;//该边的相关信息,如权值
}ArcNode;//边节点类型

typedef struct Vnode {
    InfoType info;//顶点其他信息
    int count;//存放顶点入度,仅仅用于拓扑排序
    ArcNode* firstarc;//指向第一条边
}VNode;//邻接表头节点类型

typedef struct {
    VNode* adjlist[MAXV];//邻接表头节点数组
    int n, e;//图中顶点数n和边数e
}AdjGraph;//完整的图邻接表类型

void G_CreateMat(MatGraph& g, int A[MAXV][MAXV], int n, int e) {

    int i, j;
    g.n = n; g.e = e;
    for (i = 0; i < g.n; i++)
        for (j = 0; j < g.e; j++)
            g.edges[i][j] = A[i][j];
}

void DispMat(MatGraph g) {
    int i, j;
    for ( i = 0; i < g.n; i++) {
        for (j = 0; j < g.e; j++) 
            if (g.edges[i][j] != INF)
                printf("%4d", g.edges[i][j]);
            else printf("%4s", "INF");
        printf("\n");

    }

}
//邻接表
void CreateAdj(AdjGraph*& G, int A[MAXV][MAXV], int n, int e) {
    int i, j;
    ArcNode* p;
    G = (AdjGraph *)malloc(sizeof(AdjGraph));
    for (i = 0; i < n; i++)
      G->adjlist[i]->firstarc = NULL;
    for (i = 0; i < n; i++) 
        for (j = n - 1; j >= 0; j--) 
            if (A[i][j] != 0 && A[i][j] != INF) {
                p = (ArcNode*)malloc(sizeof(ArcNode));
                p->adjvex = j;
                p->weight = A[i][j];
                p->nextarc = G->adjlist[i]->firstarc;
                G->adjlist[i]->firstarc = p;
            }
    G->n = n;
    G->e = e;
}

void DispAdj(AdjGraph* G) {
    ArcNode* p;
    for (int i = 0; i < G->n; i++) {
        p = G->adjlist[i]->firstarc;
        printf("%3d:", i);
        while (p != NULL) {
            printf("%3d[%d]->",p->adjvex,p->weight);
            p = p->nextarc;
        }
        printf("^\n");
    }

}

void DestoryAdj(AdjGraph*& G) {
    ArcNode* pre, * p;
    for(int i=0;i<G->n;i++){
        pre = G->adjlist[i]->firstarc;
        if (pre != NULL) {
            p = pre->nextarc;
            while (p != NULL) {
                free(pre);
                pre = p;
                p = p->nextarc;
            }
            free(pre);
        }
    }
    free(G);
}

int visited[MAXV];

void DFS(AdjGraph* G, int v) {
    ArcNode* p;
    printf("%3d", v); visited[v] = 1;
    p = G->adjlist[v]->firstarc;
    while (p != NULL) {
        if (visited[p->adjvex] == 0)
            DFS(G, p->adjvex);
        p = p->nextarc;
    }
}
//测试
/*

int main()
{
    MatGraph g;
    AdjGraph* G;
    int A[MAXV][MAXV] = {
        {0,5,INF,7,INF,INF},{INF,0,4,INF,INF,INF},
        {8,INF,0,INF,INF,9},{INF,INF,5,0,INF,6},
        {INF,INF,INF,5,0,INF},{3,INF,INF,INF,1,0}
    };
    int n = 6, e = 10;
    G_CreateMat(g, A, n, e);
    printf("(1)图的邻接矩阵:\n"); DispMat(g);
    CreateAdj(G, A, n, e);
    printf("(2)图的邻接表:\n"); DispAdj(G);
    printf("(3销毁图的邻接表\n)");
    DestoryAdj(G);
    return 1;
}

*/

//DFS和BFS
int visited[MAXV];

void DFS(AdjGraph* G, int v) {
    ArcNode* p;
    printf("%3d", v); visited[v] = 1;
    p = G->adjlist[v]->firstarc;
    while (p != NULL) {
        if (visited[p->adjvex] == 0)
            DFS(G, p->adjvex);
        p = p->nextarc;
    }
}

void DFS1(AdjGraph* G, int v) {
    ArcNode* p;
    int St[MAXV];
    int top = -1,w,x,i;
    for (i = 0; i < G->n; i++)
        visited[i] = 0;
    printf("%3d", v);
    visited[v] = 1;
    top++; St[top] = v;
    while (top > -1) {
        x = St[top];
        p = G->adjlist[x]->firstarc;
        while (p != NULL) {
            w = p->adjvex;
            if(visited[w]==0){
                printf("%3d", w);
                visited[w] = 1;
                top++;
                St[top] = w;
                break;//退出循环处理栈顶的顶点
            }
            p = p->nextarc;
        }
        if (p == NULL)top--;

    }
    printf("\n");
}

void BFS(AdjGraph* G, int v) {
    ArcNode* p;
    int queue[MAXV], front = 0, rear = 0;//定义环形队列并进行初始化
    int visited[MAXV];//定义存放顶点的访问标志的数组
    int w,i;
    for (i = 0; i < G->n; i++) {
        visited[i] = 0;//访问数组标志初始化
    }
    printf(" % 3d", v);//输出被访问顶点的编号
    visited[v] = 1;//置已访问标记
    rear = (rear + 1) % MAXV;
    queue[rear] = v;//v进队
    while (front != rear) {
        front = (front + 1) % MAXV;
        w = queue[front];//出队并赋值给w
        p = G->adjlist[w]->firstarc;//找顶点w的第一个相邻点
        while (p != NULL) {
            if (visited[p->adjvex] == 0) {//若相邻点未被访问
                printf("%3d", p->adjvex);//访问该相邻点
                visited[p->adjvex] = 1;//置已访问标记
                rear = (rear + 1) % MAXV;//该顶点进队
                queue[rear] = p->adjvex;
            }
            p = p->nextarc;//找下一个相邻点
        }
    }
    printf("\n");
}
//测试
/*
int main() {
    AdjGraph* G;
    int A[MAXV][MAXV] = {
        {0,5,INF,7,INF,INF},{INF,0,4,INF,INF,INF},
        {8,INF,0,INF,INF,9},{INF,INF,5,0,INF,6},
        {INF,INF,INF,5,0,INF},{3,INF,INF,INF,1,0}
    };
    int n = 6, e = 10;
    CreateAdj(G, A, n, e);
    printf("图G的邻接表:\n");
    DispAdj(G);
    printf("从顶点0开始的DFS:\n");
    DFS(G, 0); printf("\n");//递归
    printf("从顶点0开始的DFS1:\n");
    DFS1(G, 0); printf("\n");//非递归
    printf("从顶点0开始的BFS:\n");
    BFS(G, 0);
    DestoryAdj(G);
    return 1;
}
*/
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值