《妙趣横生的算法》(C语言实现)-第1章 数据结构基础

【1-1】创建一个静态的顺序表存放整数,大小为10,完成以下的操作。

// 实例1-1 2023年12月21日15点59分-16点31分
# include <stdio.h>
# define MaxSize 10
// 静态顺序表的各种操作
// 向顺序表插入元素,Sqlist表首地址,*len表的长度,pos插入元素的位置,x待插入的元素值 
void insertElem(int Sqlist[], int * len, int pos, int x) 
{
    if (pos < 1 || pos > *len+1 || *len==MaxSize) { // 非法插入 
        printf("This insert is illegal\n");
        return ;
    }
    for (int i = *len-1; i >= pos-1; --i) // 将第pos个位置及以后的元素顺序后移一个元素的位置 
        Sqlist[i+1] = Sqlist[i];
    Sqlist[pos-1] = x; // 在第pos个位置上插入元素x 
    (*len)++; // 表长加1 
}
// 从顺序表中删除元素,Sqlist表首地址,*len表的长度,pos删除元素的位置 
void deleteElem(int Sqlist[], int *len, int pos)
{
    if (pos < 1 || pos > *len) { // 非法删除 
        printf("This delete is illegal\n");
        return ;
    }
    for (int i = pos; i < *len; ++i) // 将第pos个位置及以后的元素一次前移 
        Sqlist[i-1] = Sqlist[i];
    (*len)--; // 表长减1 
}
int main()
{
    int Sqlist[MaxSize]; // 定义一个静态顺序表
    int len = 0;
    for (int i = 0; i < 6; ++i) { // 从键盘输入6个整数 
        int num;
        printf("Please input %dth number:", i+1);
        scanf("%d", & num);
        insertElem(Sqlist, & len, i+1, num);
    }
    printf("Print the result:"); // 输出顺序表的所有整数 
    for (int i = 0; i < len; ++i)
        printf("%d ", Sqlist[i]);
    printf("\nThe spare length is %d\n", MaxSize - len); // 显示表中的剩余空间
    insertElem(Sqlist, & len, 3, 0); // 在表中第3个位置插入整数0
    printf("Print the result:"); // 输出顺序表的所有整数
    for (int i = 0; i < len; ++i)
        printf("%d ", Sqlist[i]);
    printf("\nThe spare length is %d\n", MaxSize - len); // 显示表中的剩余空间
    insertElem(Sqlist, & len, 11, 0); // 在表中第11个位置插入整数0
    deleteElem(Sqlist, & len, 6); // 删除表中第6个位置元素 
    printf("Print the result:"); // 输出顺序表的所有整数
    for (int i = 0; i < len; ++i)
        printf("%d ", Sqlist[i]);
    printf("\nThe spare length is %d\n", MaxSize - len); // 显示表中的剩余空间
    deleteElem(Sqlist, & len, 16); // 删除表中第16个位置元素 
    return 0;
} 

总结:静态顺序表的插入和删除元素,一方面需要判断是否非法操作,另一方面相应移动元素,表长也相应改变!
【1-2】编写程序,动态地创建一个顺序表。

// 1-2 2023年12月21日16点42分-17点13分 
# include <stdio.h>
# include <malloc.h>
# include <stdlib.h>
# define MaxSize 10
typedef int ElemType; // 将int定义为ElemType 
typedef struct {
    int *elem; // 顺序表的首地址 
    int length; // 顺序表中表的长度 
    int listsize; // 顺序表的存储空间容量 
}Sqlist;
// 初始化一个顺序表,Sqlist类型的指针 
void initSqlist(Sqlist *L)
{
    L->elem = (int*)malloc(MaxSize * sizeof(ElemType));
    if (!L->elem) 
        exit(0);
    L->length = 0;
    L->listsize = MaxSize;
}
// 向顺序表中插入元素,Sqlist类型的指针,pos插入元素的位置,x插入的元素 
void insertElem(Sqlist *L, int pos, ElemType x)
{
    if (pos < 1 || pos > L->length + 1) { // 非法插入 
        printf("\nThis insert is illegal");
//        exit(0);
        return ;
    }
    if (L->length >= L->listsize) {
        ElemType * base = (ElemType *)realloc(L->elem, (L->listsize+10) * sizeof(ElemType));
        L->elem = base; // 更新内存基址
        L->listsize += 100; // 存储空间增大100个单元 
    }
    for (ElemType * p = &(L->elem[L->length-1]); p >= &(L->elem[pos-1]); --p) // 将第pos个位置及以后的元素后移 
        *(p+1) = *p;
    L->elem[pos - 1] = x; // 在第pos个位置上插入元素x 
    ++L->length; // 表长加1 
}
// 从顺序表删除元素,Sqlist类型的指针,pos删除元素的位置 
void deleteElem(Sqlist *L, int pos)
{
    if (pos < 1 || pos > L->length) {// 非法删除 
        printf("\nThis Delete is illegal");
        exit(0);
    }
    for (ElemType * p = &(L->elem[pos-1]); p <= L->elem+L->length-1; ++p)
        *(p-1) = *p;
    --L->length; // 表长减1 
}
int main()
{
    Sqlist l;
    initSqlist(&l); // 初始化一个顺序表
    for (int i = 0; i < 15; ++i) // 插入元素 
        insertElem(&l, i+1, i+1);
    printf("\nThe content of the list is\n");
    for (int i = 0; i < l.length; ++i) // 打印元素 
        printf("%d ", l.elem[i]);
    deleteElem(&l, 5); // 删除第5个元素
    printf("\nDelete the fifth element\n"); 
    for (int i = 0; i < l.length; ++i)
        printf("%d ", l.elem[i]);
    insertElem(&l, -1, 12);
    deleteElem(&l, -1);
    return 0;
} 

总结:动态顺序表的插入和删除元素,一方面需要判断是否非法操作,另一方面相应移动元素,表长也相应改变!另外,注意动态内存的使用。
【1-3】编写程序实现对链表的操作。要求:从终端输入一组整数,以0作为结束标志,将这一组整数存放在一个链表中(结束标志0不包括在内),打印出该链表中的值。然后删除该链表中的第5个元素,打印出删除后的结果。最后在内存中释放掉该链表。

//1-3 2023年12月30日09点32分-11点32分 
//删除链表结点出错,一点都不认真,书上的for循环后面是;不要想当然的写
//要思考 
# include <stdio.h>
# include <malloc.h>

typedef int ElemType;
typedef struct node{
    ElemType data; //数据域 
    struct node *next; //指针域 
}LNode, *LinkList;

//创建一个链表
LinkList createLinkList(int n)
{
    //建立一个长度为n的链表
    LinkList p, r, list = NULL;
    ElemType e;
    for (int i = 1; i <= n; i++) {
        scanf("%d", &e); //输入结点的内容 
        /*用malloc函数在内存的动态存储区开辟一块大小为sizeof(LNode)的空间,
          并将其地址赋值给LinkList类型的变量p*/ 
        p = (LinkList)malloc(sizeof(LNode));
        p->data = e; //将数据e存入该结点的数据域data 
        p->next = NULL; //指针域存放NULL 
        /*如果指针变量list为空,说明本次生成的结点为第一个结点,所以将p赋值给list,
          list是LinkList类型变量,只用来指向第一个链表结点,因此它是该链表的头指针,最后要返回*/
        if (!list)
            list = p; //赋值链表头指针 
        /*如果指针变量list不为空,则说明本次生成的结点不是第一个结点,因此将p赋值给r->next。
          这里r是一个LinkList类型变量,它永远指向原先链表的最后一个结点,也就是要插入结点的前一个结点*/
        else
            r->next = p; //将结点连入链表 
        /*再将p赋值给r,目的是使r再次指向最后的结点,以便生成链表的下一个结点,即保证r永远指向原先链表的最后一个结点*/
        r = p;
    }
    /*最后将生成的链表的头指针list返回主调函数,通过list就可以访问到该链表的每一个结点,并对该链表进行操作*/
    return list; //返回链表头指针 
}

void insertList(LinkList *list, LinkList q, ElemType e)
{
    //向链表中由指针q指出的结点后面插入结点,结点数据为e
    LinkList p;
    p = (LinkList)malloc(sizeof(LNode)); //生成一个新结点,由p指向它
    p->data = e; //向该结点的数据域赋值e
    if (!*list) {
        *list = p;
        p->next = NULL;
    } else {
        p->next = q->next;
        q->next = p;
    }
}

void delLink(LinkList *list, LinkList q)
{
    //删除链表的某结点 
    LinkList r; 
    printf("打印\n");
    LinkList tmp = *list;
    while (tmp) {
        printf("tmp = %p, tmp->next = %p\n", tmp, tmp->next);
        tmp = tmp->next; 
    }
    if (q == *list) {
        *list = q->next;
        free(q);
    } else {
        //遍历链表,找到q的前驱结点的指针 
        /*r = *list; 
        printf("r = %p, r->data = %d, r->next = %p\n", r, r->data, r->next);
        printf("q = %p, q->data = %d\n", q, q->data);
        if (r->next == q) {
            printf("相等\n");
        } else {
            printf("不相同\n");
        }
        while (r->next != q) {
            r = r->next;
        }
        r->next = q->next;
        free(q);*/
        for (r = *list; r->next != q; r = r->next) {
            /*printf("r = %p, r->next = %p\n", r, r->next);
            if (r->next != NULL) {
                r->next = q->next;
                free(q);
            }*/
        }
        if (r->next != NULL) {
            r->next = q->next;
            free(q);
        }
    }
}

void destroyLinkList(LinkList *list)
{
    //销毁一个链表list 
    LinkList p, q;
    p = *list; //首先将*list的内容赋值给p,这样p也指向链表的第一个结点,成为了链表的表头
    /*判断只要p不为空(NULL),就将p指向的下一个结点的指针(地址)赋值给q,并应用函数free()释放掉p所指向的结点,
      p再指向下一个结点。如此循环,直到链表为空为止*/ 
    while (p) {
        q = p->next;
        free(p);
        p = q;
    }
    /*最后将*list的内容置为NULL,这样主函数中的链表list就为空了,防止了list变为野指针。而且链表在内存中也被完全地释放掉了*/
    *list = NULL;
}
 
int main()
{
    LinkList l, q;
    q = l = createLinkList(1); //创建一个链表结点,q和l指向该结点
    int e;
    scanf("%d", &e); //循环地输入数据,同时插入新生成的结点
    while (e) {
        insertList(&l, q, e);
        q = q->next;
        scanf("%d", &e);
    } 
    q = l;
    printf("The content of the linklist\n");
    while (q) {
        printf("%d ", q->data); //输出链表中的内容
        q = q->next; 
    }
    q = l;
    printf("l = %p\n", l);
    printf("\nDelete the fifth element\n");
    for (int i = 0; i < 4; i++) { //将指针q指向链表第5个元素 
        q = q->next;
        printf("here q = %p, q->next = %p\n", q, q->next);
    }
    printf("q->data = %d, q = %p\n", q->data, q);
    printf("l = %p\n", l);
    delLink(&l, q); // 删除q所指的结点
    q = l;
    while (q) {
        printf("%d ", q->data); //打印删除后的结果 
        q = q->next;
    } 
    destroyLinkList(&l); //释放掉该链表 
    return 0;
} 

🍎总结:链表的创建、插入和删除元素、销毁,要认真思考,能独立写出来。认真细心哦,书上的删除结点代码里面的for循环是空语句,以分号结尾,我却一直没有发现,找了好长时间的错误,要细心啊。在debug过程中,我查看了链表的每个结点的地址,之前没有看到地址,一直想的都是书上描述的内容,现在通过发现链表还真是每个结点链接在一起,还是很有意思的,哈哈哈。动脑子编写程序哦,不要一味的抄袭。
【1-4】利用栈的数据结构,将二进制数转换为十进制数。

//1-4 2023年12月30日15点35分-16点38分 
# include <stdio.h>
# include <malloc.h>
# include <stdlib.h>
# include <math.h>
//# define ElemType int
typedef char ElemType;  //两种方式注意区分哦 

typedef struct {  //定义了一个顺序栈类型 
    ElemType *base;  //base是指向栈底的指针变量 
    ElemType *top;  //top是指向栈顶的指针变量 
    int stacksize;  //stacksize指示栈的当前可使用的最大容量
    /*可以通过base和top对栈进行各种操作,通过stacksize判断栈的空间分配情况*/ 
}sqStack;

//创建一个栈
/*创建一个栈有两个任务:一是在内存中开辟一段连续的空间,用作栈的物理存储空间;二是将
栈顶、栈底地址赋值给sqStack类型变量(对象)的top和base域,并设置stacksize值,以便通过
这个变量(对象)对栈进行各种操作*/
//sqStack *createsqStack(void)  //这样写有问题,先看书上的答案,一会儿再来改 
//{
//    printf("创建一个栈!\n");
//    sqStack *sq;
//    sq = (sqStack*)malloc(sizeof(sqStack) * 100);
//    if (sq == NULL) {
//        printf("创建失败!\n");
//        exit(0);
//    }
//    sq->stacksize = 100;
//    printf("创建成功!\n");
//    return sq;
//} 

# define STACK_INIT_SIZE 100
void initStack(sqStack *s)
{
    /*在内存中开辟一段连续空间作为栈空间,首地址赋值给s->base*/
    s->base = (ElemType *)malloc(STACK_INIT_SIZE * sizeof(ElemType));
    if (!s->base)  //分配空间失败 
        exit(0);
    s->top = s->base;  //最开始,栈顶就是栈底
    s->stacksize = STACK_INIT_SIZE;  //最大容量为STACK_INIT_SIZE
    printf("空栈时s->base = s->top = %p, s->stacksize = %d\n", s->top, s->stacksize);
}

//入栈操作
# define STACKINCREMENT 10
void push(sqStack *s, ElemType e)
{
    if (s->top - s->base >= s->stacksize) {
        //栈满,追加空间
        s->base = (ElemType *)realloc(s->base, (s->stacksize + 
        STACKINCREMENT)*sizeof(ElemType));
        if (!s->base) exit(0);  //存储分配失败
        s->top = s->base + s->stacksize;
        s->stacksize = s->stacksize + STACKINCREMENT;  //设置栈的最大容量 
    }
    printf("当前s->top = %p,插入元素e = %c,", s->top, e);
    *(s->top) = e;  //放入数据
    s->top++; 
    printf("插入元素后s->top = %p\n", s->top); 
}

//出栈操作
void pop(sqStack *s, ElemType *e)
{
    if (s->top == s->base) {
        printf("空栈,没有元素可以出栈!\n");
        return ;
    }
    printf("当前s->top = %p,", s->top);
    *e = *--(s->top);
     printf("出栈元素e = %c,删除元素后s->top = %p\n", *e, s->top);
} 

//清空一个栈
void clearStack(sqStack *s)
{
    printf("清空栈之前s->top = %p, s->base = %p\n", s->top, s->base);
    s->top = s->base;
    printf("清空栈s->top = s->base = %p\n", s->top);
}

//销毁一个栈
void destroyStack(sqStack *s)
{
//    int len = s->stacksize;  //感觉书上这里有错误诶 
//    printf("len = %d\n", len);
//    for (int i = 0; i < len; i++) {
//        printf("销毁栈s->base = %p,", s->base);
//        free(s->base);
//        s->base++; 
//        printf("此时栈底s->base = %p\n", s->base);
//    }
    free(s->base);
    printf("销毁栈s->base = %p,", s->base);
    s->base = s->top = NULL;
    printf("此时栈底s->base = %p\n", s->base);
    s->stacksize = 0;
}

//计算栈的当前容量
int stackLen(sqStack s)
{
    return (s.top - s.base);
} 


int main()
{
//    sqStack *s = createsqStack();
    sqStack s;
    printf("Please input a binary digit\n");
    initStack(&s);  //创建一个栈,用来存放二进制字符串
    //输入0/1字符表示的二进制数,以#结束
    ElemType c;
    scanf("%c", &c); 
    while (c != '#') {
        push(&s, c);
        scanf("%c", &c);
    }
    getchar();
    int len = stackLen(s);  //得到栈中的元素个数,即二进制数的长度
    int sum = 0;
    for (int i = 0; i < len; i++) {
        pop(&s, &c);
        sum += (c-'0') * pow(2, i);  //转换为十进制 
    } 
    printf("Decimal is %d\n", sum);
//    clearStack(&s);
//    pop(&s, &c);
//    destroyStack(&s);
//    pop(&s, &c);

    return 0;
} 

🍎总结:栈的创建、插入和删除元素、销毁,要认真思考,能独立写出来。
【1-5】实现一个链队列,任意输入一串字符,以@为结束标志,然后将队列中的元素逐一取出,打印在屏幕上。

//1-5 2023年12月31日11点01分-11点37分 
//队列中每个元素的类型
# include <malloc.h> 
# include <stdlib.h>
# include <stdio.h>
typedef char ElemType;
typedef struct QNode{
    ElemType data;
    struct QNode* next;
}QNode, *QueuePtr;
//队列类型 
typedef struct{
    QueuePtr front;  //队头指针
    QueuePtr rear;  //队尾指针 
}LinkQueue;

//创建一个队列
void initQueue(LinkQueue *q)
{
    //初始化一个空队列 
    q->front = q->rear = (QueuePtr)malloc(sizeof(QNode));
    //创建一个头结点,队头队尾指针指向该结点
    if (!q->front) exit(0);  //创建头结点失败
    q->front->next = NULL;  //头结点指针域置NULL 
    printf("初始化一个空队列:\nq->front = q->rear = %p\n", q->front);
    printf("q->front->next = %p, q->front->data = %d, "
    "(*(q->front)).data = %d\n", q->front->next, q->front->data, (*(q->front)).data);
}

//入队列
void enQueue(LinkQueue *q, ElemType e)
{
    QueuePtr p = (QueuePtr)malloc(sizeof(QNode));  //创建一个队列元素的结点
    if (!q->front) exit(0);  //创建头结点失败
    p->data = e;
    p->next = NULL;
    printf("插入元素%c, p = %p, p->data = %c, p->next = %p, q->rear = %p\n", e, p, p->data, p->next, q->rear);
    q->rear->next = p;
    printf("           q->rear->next = %p, ", q->rear->next);
    q->rear = p; 
    printf("q->rear = %p\n", q->rear);
} 

//出队列
void deQueue(LinkQueue *q, ElemType *e)
{  //如果队列q不为空,删除q的队头元素,用e返回其值 
    if (q->front == q->rear)  return ;  //队列为空,返回 
    QueuePtr p = q->front->next;
    *e = p->data;
    q->front->next = p->next;
    if (q->rear == p) q->rear = q->front;  //如果队头就是队尾,则修改队尾指针 
    free(p);
}

//销毁队列
void destroyQueue(LinkQueue *q)
{
    while (q->front) {
        q->rear - q->front->next;
        free(q->front);
        q->front = q->rear;
    }
} 

int main()
{
    ElemType e;
    LinkQueue q;
    initQueue(&q);  //初始化一个队列q 
    printf("Please input a string into a queue\n");
    scanf("%c", &e);
    while (e != '@') {
        enQueue(&q, e);  //向队列中输入字符串,以@表示结束
        scanf("%c", &e); 
    }
    printf("The string into the queue is\n");
    while (q.front != q.rear) {  //将队列中的元素出队列,并打印在屏幕上 
        deQueue(&q, &e);
        printf("%c", e);
    }
    return 0;
}
 

【1-6】用先序序列创建一棵二叉树,并输出字符D位于二叉树的层数。

//1-6 2023年12月31日15点07分-15点51分
# include <stdio.h>
# include <stdlib.h>
//# include <malloc.h>
typedef char ElemType;
typedef struct BiTNode{  //二叉树的结点 
    ElemType data;  //结点的数据域 
    struct BiTNode *lchild, *rchild;  //指向左孩子和右孩子 
}BiTNode, *BiTree;

//访问二叉树结点,输出包含D字符结点位于二叉树中的层数 
void visit(char c, int level)
{
    if (c == 'D') {
        printf("%c is at %d level of BiTree\n", c, level);
    }
}
//遍历二叉树
void PreOrderTraverse(BiTree T, int level)
{
    if (T) {  //递归结束条件,T为空 
        visit(T->data, level);  //访问根结点 
        PreOrderTraverse(T->lchild, level+1);  //先序遍历T的左子树 
        PreOrderTraverse(T->rchild, level+1);  //先序遍历T的右子树 
    }
} 

/*void visit(ElemType e)
{
    printf("%c", e);
}*/

//先序遍历
/*void PreOrderTraverse(BiTree T)
{
    if (T) {  //递归结束条件,T为空 
        visit(T->data);  //访问根结点 
        PreOrderTraverse(T->lchild);  //先序遍历T的左子树 
        PreOrderTraverse(T->rchild);  //先序遍历T的右子树 
    }
}*/

//中序遍历
/*void InOrderTraverse(BiTree T)
{
    if (T) {  //递归结束条件,T为空 
        InOrderTraverse(T->lchild);  //中序遍历T的左子树
        visit(T->data);  //访问根结点 
        InOrderTraverse(T->rchild);  //中序遍历T的右子树 
    }
}*/

//后序遍历
/*void PostOrderTraverse(BiTree T)
{
    if (T) {  //递归结束条件,T为空 
        PostOrderTraverse(T->lchild);  //后序遍历T的左子树 
        PostOrderTraverse(T->rchild);  //后序遍历T的右子树
        visit(T->data);  //访问根结点
    }
}*/

//先序序列创建一棵二叉树
void CreateBiTree(BiTree *T)
{
    char c;
    scanf("%c", &c);
    if (c == ' ') *T = NULL;
    else {
        *T = (BiTree)malloc(sizeof(BiTNode));  //创建根结点
        (*T)->data = c;  //向根结点中输入数据
        CreateBiTree(&((*T)->lchild));  //递归地创建左子树
        CreateBiTree(&((*T)->rchild));  //递归地创建右子树 
    }
} 

int main()
{
    int level = 1;
    BiTree T = NULL;  //最开始T指向空
    CreateBiTree(&T);  //创建二叉树
    PreOrderTraverse(T, level);  //遍历二叉树,找到包含D字符结点位于二叉树中的层数 
    return 0;
} 

【1-7】用邻接表存储的形式创建无向图,并应用深度优先搜索的方法遍历该图中的每个顶点,打印出每个顶点中包含的数据。

//1-7 2023年12月31日16点02分-16点37分 
# include <stdio.h>
# include <malloc.h>
//邻接表
# define MAX_VERTEX_NUM 20 
typedef struct ArcNode{  //单链表中的结点的类型 
    int adjvex;  //该边指向的顶点在顺序表中的位置
    struct ArcNode *next;  //下一条边
//    infoType *weight;  //边上的权重,可省略 
}ArcNode;
typedef struct VNode{  //顶点类型 
//    VertexType data;  //顶点中的数据信息
    int data;  //顶点中的数据信息
    ArcNode *firstarc;  //指向单链表,即指向第一条边 
}VNode;
//VNode G[MAX_VERTEX_NUM];  //VNode类型的数组G,它是图的存储容器
int visited[5] = {0, 0, 0, 0, 0};

//图的创建
void CreateGraph(int n, VNode G[])
{
    printf("Input the information of the vertex\n");
    for (int i = 0; i < n; i++) {
//        Getdata(G[i]);  //得到每个顶点中的数据
        scanf("%d", &G[i]);
        G[i].firstarc = NULL;  //初始化第一条边为空 
    }
    int e;
    ArcNode *q;
    for (int i = 0; i < n; i++) {
        printf("Create the edges for the %dth vertex\n", i);
        scanf("%d", &e);
        while (e != -1) {
            ArcNode *p = (ArcNode *)malloc(sizeof(ArcNode));  //创建一条边
            p->next = NULL;
            p->adjvex = e;
            if (G[i].firstarc == NULL) G[i].firstarc = p;  //i结点的第一条边
            else q->next = p;  //下一条边
            q = p;
            scanf("%d", &e); 
        }
    }
} 

int FirstAdj(VNode G[], int v)
{
    if (G[v].firstarc != NULL)
        return (G[v].firstarc)->adjvex;
    return -1;
}

int NextAdj(VNode G[], int v)
{
    ArcNode *p;
    p = G[v].firstarc;
    while (p != NULL) {
        if (visited[p->adjvex])
            p = p->next;
        else
            return p->adjvex;
    }
    return -1;
}

//深度优先搜索一个连通图
void DFS(VNode G[], int v)
{
    int w;
//    visit(v);  //访问当前顶点
    printf("%d ", G[v].data);  //访问当前顶点,打印出该顶点中的数据信息 
    visited[v] = 1;  //将顶点v对应的访问标记置1
    w = FirstAdj(G, v);  //找到顶点v的第一个邻接点,如果无邻接点,返回-1
    while (w != -1) {
        if (visited[w] == 0)  //该顶点未被访问
            DFS(G, w);  //递归地进行深度优先搜素
        w = NextAdj(G, v);  //找到顶点v的下一个邻接点,如果无邻接点,返回-1 
    } 
} 
 
int main()
{
    VNode G[5];
    CreateGraph(5, G);
    printf("DFS Travel this undirected graph\n");
    DFS(G, 0);
    return 0;
} 

总结:要加油啊!!!

  • 8
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值