小工具知识网

当前位置: 首页 > 行业知识 > C语言 数据结构与算法

行业知识

C语言 数据结构与算法

2026-11-13 09:20:09 来源:互联网转载

文章目录

    • 排序算法
        • 冒泡排序
        • 选择排序
        • 插入排序
        • 希尔排序
        • 快速排序
        • 查找算法
            • 顺序查找
            • 二分查找
            • 顺序表
                • 数组
                • 链表
                  • 链表的初始化(只生成头结点)
                  • 栈(stack)
                  • 队列
                  • 栈的应用
                  • 串
                    • 串的基本操作
                    • 矩阵
                    • 树
                    • 二叉树链式存储
                      • 二叉排序树
                      • 哈夫曼树(最小权值树)
                      • 邻接矩阵
                      • 邻接表
                      • 带权图
                      • 深度优先遍历 DFS
                      • 广度优先遍历算法
                      • 最小生成树
                        • 普利姆算法(Prim)
                        • 克鲁斯卡尔算法(Kruskal)
                        • 最短路径
                          • 迪杰斯特拉(Dijkstra)
                          • 弗洛伊德(Floyd)
                          • 拓扑排序
                            • AOV网

                              排序算法

                              冒泡排序
                              • 冒泡排序

                                ()
                                思想:两数比较 将最大 或 最小 的元素,放到最后。
                                int i, j, temp;// 定义 外层循环变量 i,// i 外层循环变量,j 内层循环变量 ,temp 临时变量for( i=0 ; i// 外层 控制 元素 比较多少躺        for( j=0 ; j//内层 控制 元素 比较次数                if( arr[j]  arr[j+1] ){//从小到大                        temp = arr[j];            arr[j] = arr[j+1];            arr[j+1] = temp;                    }            }    }    KeyType key;}RecType;//单个节点 的 数据类型typedef struct{    Rectype r[10000];    int len;//顺序表长度}Sqlist;//顺序表 的 数据类型int i, j, temp;Sqlist *q;for(i=0 ; ilen-i-1 ;j++){        if( q->r[j].key >q->r[j+1].key ){            temp = q->r[j].key;            q->r[j].key = q->r[j+1].key;            q->r[j+1].key = temp;        }    }}

                                注意:冒泡排序 稳定,最多执行 n(n-1)/2 次。

                                ()
                                选择排序
                                • 简单选择排序

                                  思想:找 最大 或 最小 的元素,往前放,分成 "已排序" 和 "待排序" 序列。
                                  void selectSort(int arr[], int len){    int i, j ,temp, min;    for(i=0 ; i       

                                  选择排序 不稳定,平均比较次数 n(n-1)/2 次。


                                  插入排序
                                  • 直接插入排序

                                    思想:由后向前 查找 确定的位置,并插入元素。
                                    void insertSort(int arr, int len){    int i, j, temp;        for( i=1; i =0 && arr[j]>temp ;j--){                        arr[j+1] = arr[j];// 元素后移,为 待插入元素 腾空位置                            arr[j+1] = temp;// 插入 比较的后一位    }    }

                                    直接插入排序,是在有序基础上,速度最快且最稳定的排序方法,最多执行 n(n-1)/2 次。


                                    希尔排序
                                    • 希尔排序

                                      希尔排序:又称为 "缩小增量排序"。思想:按照 步长 进行分组,然后每一组的 第 几个 元素 进行排序。增量 及 步长。
                                      // dk 是 增量步长void shellInsert(int arr[], int len, int dk){        int i, j, temp;// i 循环变量,j 前面组的位置,temp 临时变量        for( i=dk; i                //判断每组的 第几个元素大小        if( arr[i] temp ; j-=dk ){                //前面的值 给到 后面                arr[j+dk] = arr[j];            }            arr[j+dk] = tmep;                    }            }    }

                                      希尔排序 是 不稳定的。


                                      快速排序
                                      • 快速排序

                                        基准值,i 从前向后找,比基准值大的元素,j 从后向前找,找比基准值小的元素。最后 结束的条件是 i = j ,此时 将 基准值 放到这个位置。
                                        int getPivot(int arr[], int low, int high){        int pivot = arr[low];        while( low = pivot ){            high--;        }                // 找到了 比基准值小的元素,将 元素 给到 i 位置        arr[low] = arr[high];                // i 从前向后找,找比 基准值 大 的元素        while( low next;//指针后移    }        //返回链表长度    return count;    }
                                      • 链表的遍历(数据域)

                                        void foreach(LinkList head){        if(!head){        return;    }        LinkList p = head->next;        while(p){        printf("%d ",p->data);        p = p->next;    }    }
                                      • 链表的清空

                                        void clear(LinkList head){        if(!head){        return;    }        Node *p = head->next;        while(p){                // q 存放的是,p 下一个结点的地址        LinkList q = p->next;                // 释放 p        free(p);                p = q;            }        head->next = NULL;    }
                                      • 链表的销毁

                                        void destory(LinkList head){        if(!head){        return;    }        clear(head);        free(head);// 释放头结点        head = NULL;// 指针变量 设置为 空    }
                                      • 链表的插入(尾插法)

                                        void insert(LinkList head){        if(!head){        return;    }        int num;        printf("请输入要插入的结点数量:");    scanf("%d",&num);        Node *q = head;        for(int i=0; i        LinkList p = (Node *)malloc(sizeof(Node));                printf("请输入数据域的值:");        scanf("%d",&p-data);                q->next = p;        q = q->next;            }        q->next = NULL;    }

                                        尾插法 生成 链表。

                                      • 链表的插入(头插法)

                                        void insert(LinkList head){        if(!head){        return;    }        int num;        printf("请输入要插入的结点数量:");    scanf("%d",&num);        for(int i=0; i                Node *p = (Node *)malloc(sizeof(Node));                printf("请输入数据域的值:");        scanf("%d",&p-data);                p->next = NULL;                // 头插法        p->next = head->next;        head->next = p;            }    }

                                        头插法,经常用 头指针 及逆行元素的插入。

                                      • 链表的删除

                                        // 根据 元素值 去删除 这个结点void delete(LinkList head, int value){        if(!head){        return;    }        Node *p = head;// p 指针 指向 头结点的下一个        Node *q;        while( p->next ){                if( p->next->data == value ){// 若满足条件,则 p 就是待删除元素结点的直接前驱                        q = p->next;// 令 q 指向 待删除结点                        p->next = q->next;// 直接前驱结点 指向 待删除结点的 后一位结点                        free(q);// 此时 释放结点                    } else{                        p = p->next;                    }            }    }

                                        删除一个结点,必须知道这个结点的 直接前驱。


                                        栈(stack)

                                        • 栈的特点:先进后出 / 后进先出

                                          1、栈 分成了 "栈顶" 与 "栈底" (在栈顶进行元素的插入和删除)2、入栈(push)出栈(pop)
                                        • 栈的顺序存储(使用 数组)

                                          数组的首地址 做 "栈顶" 还是 "栈底" 比较好?    答:做  "栈底"  比较好。

                                          因为 栈顶 要进行元素的插入和删除操作,所以数组尾部更适合比较频繁的插入和删除。

                                          • 栈 的 结构体

                                            typedef struct Stack{        int data[MXA];//数据域 (MAX 为 宏定义值)    int size;//栈的大小 (指 栈中的元素个数)    }Stack, * SeqStack;
                                          • 栈 的 初始化

                                            SeqStack create(){        //创建栈,相当于 动态开辟一个数组出来    SeqStack p = (Stack *)malloc(sizeof(Stack));        if(!p){        printf("空间开辟失败!");        return;    }        //初始化 栈 的大小    p->size = 0;        //初始化 栈中的元素    for(int i=0; i        p-data[i] = 0;    }        return p;    }
                                          • 入栈

                                            void push(SeqStack stack, int data){        if(!stack){        return;    }        //入栈 需要判断 栈是否已满    if( stack->size == MAX ){        printf("栈已满!\n");        return;    }        // stack->size 栈的大小 就是 待插入元素 的下一个位置    stack->data[stack->size] = data;        //改变栈的大小    stack->size++;    }

                                            入栈 需要注意 栈是否 不存在 and 已满。

                                          • 出栈

                                            void pop(SeqStack stack){    if(!stack)        return;        if(stack->size == 0){        printf("栈已空\n");        return;    }        //删除一个元素    stack->data[stack->size -1] = 0;        //改变栈的大小    stack->size --;    }

                                            出栈 需要注意 栈是否 不存在 and 已空。

                                          • 遍历 栈中元素

                                            void forerachStack(SeqStack stack){        if(!stack) return;        for(int i=0;isize; i++)        printf("%d ",stack->data[i]);    }

                                            • 栈 的 链式存储(链表)

                                              链表的头结点端 做 “栈顶” 还是 “栈底” 比较好?

                                              答:做 “栈顶” 比较好。

                                              因为 链表的头结点端 可以更方便的进行元素的 插入(头插法) and 删除(头结点做直接前驱)。

                                              • 栈链式存储 结构体

                                                //结点结构体trpedef struct Node{    int data;    struct Node *next;}Node;//栈的结构体trpedef struct Stack{        struct Node header;//头结点    int size;//栈的大小 即元素个数    }Stack, *LinkStack;
                                              • 初始化栈

                                                LinkStack inir_LinkStack(){        // myStack 是指针,指向所申请的空间    LinkStack myStack = (Stack *)malloc(sizeof(Stack));        if(!Stack)        return NULL;        //初始化 长度为0    myStack->size = 0;        //相当于 初始化 链表的头结点 指针域    myStack->header.next = NULL;    }

                                                什么时候使用 " -> " ,什么时候使用 " . " ?

                                                -> 在指针的时候

                                                . 在变量名的时候

                                              • 注意事项

                                                struct Node *list;list->next  list->nextstruct Node a;a.data  a.next
                                              • 入栈

                                                void push(LinkStack stack, int data){        if(!stack)        return;        //创建一个结点    Node *p = (Node *)malloc(sizeof(Node));        //给 结点数据域 赋值    p->data = data;        //头插法 先连后面    p->next= stack->header.next;        stack->header.next = p;        //改变 栈中元素 的个数    stack->size ++;    }
                                              • 出栈

                                                void pop(LinkStack stack){        //判断栈是否存在    if(!stack)        return;        //判断栈空    if(stack->size ==0){        printf("栈中无元素!\n");        return;    }        //定义一个节点类型的指针,用作删除结点    Node *p = stack->header.next;    //头结点 连接到 删除结点 的后边    stack->header.next = p->next;        //释放结点    free(p);        //更新 栈的大小    stack->size --;    }

                                                队列

                                                • 队列:先进先出 后进后出

                                                  1、只允许 从一端 添加元素,从 另一端 删除元素2、队头 出元素,队尾 进元素3、push 入队pop 出队
                                                • 队列的顺序存储

                                                  数组的首地址做 “队头” 好,还是 “队尾” 比较好?

                                                  答:都一样。

                                                  做 队头 和 队尾 差别不大,因为都需要移动大量元素。

                                                  • 队列的结构体

                                                    typedef struct Queue{    int data[MAX];//顺序存储 数组模拟的队列    int size;//队列的大小(队列中元素的个数)}Queue, *SeqQueue;
                                                  • 队列的初始化(数组头做队头,数组尾做队尾)

                                                    SeqQueue init(){    //申请队列空间,即数组空间    SeqQueue p = (Queue *)malloc(sizeof(Queue));        if(!p){        return NULL;    }        //初始化队列大小    p->size = 0;        for(int i=0; i        p-data[i] = 0;    }        reutrn p;    }
                                                  • 入队

                                                    void push(SeqQueue p, int value){        if(!p){//队列不存在        return;    }        if(p->size == MAX){        printf("队列元素已满!\n");        return;    }        //插入元素(进队)    p->data[p->size] = value;        //改变队列元素个数    p->size ++;    }
                                                  • 出队

                                                    void push(SeqQueue p){        if(!p){//队列不存在        return;    }        if(p->size == 0){        printf("队列元素已空!\n");        return;    }        //出队 删除数组首元素    for(int i=0; isize -1 ;i++){        p->data[i] = p->data[i+1];    }        //改变队列元素个数    p->size --;    }

                                                    要记得,看到循环里边有 i+1 的时候,要改变 最终值。

                                                  • 队列的链式存储

                                                    链表的 头结点端 做 “队头” 还是 “队尾” 比较好?

                                                    答:做 “队头” 好。

                                                    因为 头结点端 进行删除方便,尾端 插入元素方便(尾插法)。

                                                    • 队列的结构体

                                                      //队列的结构体typedef struct LQueue{struct Node header; //头结点int size;  //队列大小struct Node* pTail; //尾结点指针}LQueue, *LinkQueue;
                                                    • 循环队列

                                                      //队满front = (rear + 1)%n;// front 头,rear 尾//队空front = rear;// 头指针 指向 尾指针时,队为空

                                                      栈的应用

                                                      • 前 中 后 缀表达式 如何计算?

                                                        首先运算优先级最高的,然后 将 运算符放两个整体之前 就是 前缀,放两个整体之后,就是 后缀。


                                                        串

                                                        • 零个 或者多个任意字符组成的 有限序列 是我们的字符串。

                                                        • 串 是 内容受限的线性表。

                                                        • 子串:一个串中 任意个连续字符组成的子序列(含空串)。

                                                          "*jkj12k0"//它的子串有哪些?    // 单字符6// 双字符7// 三字符6// 四字符5// 五字符4// 六字符3// 七字符2// 八字符1//空串1分别是:    // *// *j// *jk// *jkj// *jkj1// *jkj12// *jkj12k// *jkj12k0// j// jk// jkj// jkj1// jkj12// jkj12k// jkj12k0// k// kj// kj1// kj12// kj12k// kj12k0// j1// j12// j12k// j12k0// 1// 12// 12k// 12k0// 2// 2k// 2k0// k0// 0// 空串
                                                        • 真子串(不包含自身的子串)。

                                                        • 主串:包含子串的串,称之为 主串。

                                                        • 字符位置:字符在数组中的位置。

                                                        • 子串位置:子串第一个字符串 在 主串中的位置。

                                                        • 空格串:一个空格或者多个空格组成的串,称之为空格串。

                                                        • 空串:零个没有任意字符的串,称之为空串。

                                                          " "// 空格串""// 空串
                                                        • 串相等:当两个串长度相等,并且每个位置对应字符完全一样的时候,两个串才相等。

                                                          串的基本操作

                                                          1.  赋值StrAssign(s,t)    将串t的值赋值给串s2.  求串长  StrLength(s)    返回字符串s的长度3.  串比较  StrCompare(s,t) 比较两个串,返回-1、0和1,分别代表st4.  连接 Concat(s,t)  将串t连接在串s的尾部,形成新的字符串5.  求子串 SubString(s,start,len)  返回串s从start开始、长度为len的字符序列6.  串拷贝 StrCopy(t,s)  将串s拷贝到串t上7.  串判空 StrEmpty(s)         判断串s是否为空串8.  清空串ClearString(s)       清空字符串s9.  子串位置 Index(S,T,pos)  字符串S中返回T所出现的位置10.  串替换  Replace(S,T)   串S替换为T
                                                          • 串的顺序存储

                                                            • 结构体

                                                              typedef struct SString{    char ch[MAX +1];// 字符数组空间,MAX 为宏定义值    int length;// 串的长度};
                                                            • BF算法

                                                              // str 是主串subStr 是模式匹配串int BF(char str[], char subStr[]){    int i=0,j=0;//定义 i 主串下表,j 模式串下标        while( i                //如果对应位置相等,则下标后移,比较下一位元素        if(str[i] == subStr[j]){            i++;            j++;        } else{            i = i-j+1;//主串下标进行回溯            j = 0;//子串下标回溯        }            }        if( j == strlen(subStr) ){//子串下标 与 子串长度相等                //返回子串位置        return i - strlen(subStr) + 1;            }        return -1;//未找到子串下标    }
                                                              hr / h3矩阵/h3 ulli p把矩阵当作 二维数组,只不过下标都是从 1 开始。/p /lili p二维数组 以行为主序存储,二维数组 以列为主序存储。/p pre 以行存储,先去计算前 (i-1)行有多少元素以列存储,先去计算前 (j-1)列有多少元素/pre blockquote p前提:数组下标从一开始。/p /blockquote /lili p对称矩阵:以主对角线为对称轴,个元素对应相等的矩阵。/p /lili p对角矩阵:除主对角线意外,全是 0 的矩阵。/p /lili p稀疏矩阵:非零元素个数,远远少于 零元素个数,且零元素分布无规律。/p /lili p三元组 (行,列,值) :/p pre (4,5,8)//第四行,第五列,值为8(前提:行列下标都从1开始)(4,5,8)//第三行,第四行,值为8(前提:行列下标都从0开始)/pre hr / h3树/h3 ulli树 是 非线性结构 。/lili根节点:没有 父节点 的节点 。/lili叶子节点:没有 子节点 的节点 。/lili节点的层次:树一共有几层,节点的层次就是几 。/lili节点的祖先:从 根节点 到 该节点 的 所有节点 。/lili节点的度:该节点 有几个 直接后继,就是几度。/lili树的度:树中,最大的 节点度 就称之为 树的度。/lili树的深度/高度:从 根节点 开始,长度最长的一条路径 有几个节点,深度就是几。hr / ulli p树的性质/p pre 1、树中的节点数 等于 所有节点的度数加1。2、度为 M 的树中,第i层上至多有 M的(i-1) 次方个节点(i=1)。3、高度为 H 的 M 叉树中,之多有 (M的H次方)/(M-1) 个节点。// 二叉树 需要 再减去1:(M的H次方)/(M-1)-1/pre /lili p二叉树:有0个 到 2个节点的树,称为 二叉树。/p /lili p二叉树的性质/p ulli性质一:在二叉树中,在第 i 层上最多有 font color="red"2supi-1/sup /font 个节点 (i>0)。
                                                            • 性质二:深度为 k 的二叉树,最多有 2k-1 个节点 (k>0)。
                                                            • 性质三:树上的节点数为 n ,则边数一定为 n-1 。
                                                            • 性质四:任意一棵二叉树中,度为 0 的节点个数 = 度为 2 的节点个数 + 1。
                                                            • 性质五:具有 n 个节点的 完全二叉树 的深度为 ⌊ log 2 n ⌋ + 1 (向下取整)。
                                                            • 大顶堆,小顶堆

                                                              // 大顶堆 每个根节点(所有的根节点) 都大于 它的子结点ki >= k2ik2 >= k2i +1// 小顶堆 每个根节点(所有的根节点) 都小于 它的子结点ki       char ch;// 数据域    struct TreeNode *lchild;//左孩子 指针    struct TreeNode *rchild;//右孩子 指针    }TreeNode;        //递归结束条件,也就是说当一个节点 某个指针域为 NULL    if(!root){        return;    }        printf("%c ",root-ch);        //递归调用左子树    preOrder(root-lchild);        //递归调用右子树 preOrder(root->rchild);    }
                                                            • 中序遍历

                                                              void inOrder(Node *root){        //递归结束条件,也就是说当一个节点 某个指针域为 NULL    if(!root){        return;    }        //递归调用左子树    preOrder(root->lchild);        printf("%c ",root->ch);        //递归调用右子树 preOrder(root->rchild);    }
                                                            • 后序遍历

                                                              void lastOrder(Node *root){        //递归结束条件,也就是说当一个节点 某个指针域为 NULL    if(!root){        return;    }        //递归调用左子树    preOrder(root->lchild);        //递归调用右子树 preOrder(root->rchild);        printf("%c ",root->ch);    }

                                                              • 根据遍历的序列 确定 二叉树 的形状

                                                                // 1、先序 和 中序 可以确定一棵二叉树答:根据先序 确定 根节点的位置,然后去 中序 找到该节点,该节点左边元素都是左子树,右边元素都是右子树;依次重复上述过程,即可根据序列确定 二叉树形状。(从前找根节点)// 2、后序 和 中序 可以确定一棵二叉树        答:根据先序确定 根节点的位置,然很去中序中找到该节点左边元素都是左子树,右边元素都是右子树,一次重复上述过程,即可根据序列确定 二叉树形状。(从后找根节点)// 3、先序 和 后序 不可以确定一棵二叉树
                                                              • 非递归中序遍历

                                                                void inOrder(Node * root){        //指针p 指向 根节点,并按照某种顺序游走于每一个结点    Node *p = root;        //建立栈,用来实现 递归    LinkStack s = init_LinkStack();   //初始化栈,初始化一个头结点出来        //p 不指向 NULL 并且 栈不空的时候    while(p || ! isEmpty_LinkStack(s)){                //根节点不空,进栈,让其指向左子树        if(p){            push_LinkStack(s , p);                        p = p->lchild;    //指向左子树        }else{                        //定义一个指针 指向 栈顶元素 (就是 子树的根节点)            Node *top = top_LinkStack(s);                        //元素出栈            pop_LinkStack(s);                        printf("%c ",top->data);                        p = top->rchild;        }    }        //销毁栈    destory_LinkStack(s);}
                                                              • 如果有 n 个节点,则有 n+1 个空指针域。

                                                              • 线索:指向其 前驱 和 后继 的指针。

                                                              • 孩子兄弟表示法:左边指针是孩子,右边指针是兄弟。

                                                                二叉排序树

                                                                • 概念:是一颗空树,或者是满足以下性质的二叉树
                                                                  • 左子树非空,左边节点 小于 根节点。
                                                                  • 右子树非空,右边节点 大于 根节点。
                                                                  • 中序遍历,可以实现二叉排序树 从小到大排序。
                                                                    // 定义节点 结构体typedef struct TreeNode{      int data;//数据域    struct TreeNode *lchild;//左指针(指向左孩子)    struct TreeNode *rchild;//右指针(指向右孩子)    }TreeNode;TreeNode* searchTreeNode( TreeNode *root, int key ){        //递归结束条件, root 为 NULL 相当于 没有找到节点    if( (!root) || (key == root->data) ){        return root;    }     else if( key data )// 递归左子树查找    {        retuen searchTreeNode(root->lchild, key);    }    else//递归右子树查找    {        retuen searchTreeNode(root->rchile, key);    }    }

                                                                    哈夫曼树(最小权值树)

                                                                    • 路径:两个节点之间的 线 就是 路径。

                                                                    • 节点的路径:从 根节点 到 该节点,有几根线,路径长度就是几。

                                                                    • 树的路径长度:所有结点的路径长度之和,称之为树的路径长度。

                                                                    • 权值:给这个节点 赋一个数值,这个数值就是 权值。

                                                                    • 节点的带权路径长度:路径长度 * 该节点的权值。

                                                                    • 树的带权路径长度(WPL):所有 叶子节点 的带权路径长度 之和。

                                                                    • 重点:哈夫曼树构造

                                                                      //哈夫曼二叉树构造1、每次从 序列中找出 权值最小的两个节点(一般:从左至右,从小到大)2、生成一个新的节点,将这个节点放入 序列中,删除刚才的两个最小权值节点,再重复此过程。

                                                                      邻接矩阵

                                                                      • 无向图 对应的临界矩阵 是 对称矩阵。
                                                                      • 矩阵的大小 只与 顶点个数有关,是一个 N*N阶矩阵。
                                                                      • 顶点的度:
                                                                        • 入度:邻接矩阵 对应于 列上值的总和。
                                                                        • 出度:邻接矩阵 对应于 行上值的总和。

                                                                          邻接表

                                                                          • 防止浪费空间(稀疏矩阵),但是效率 相对于 邻接矩阵 较低。

                                                                          • 邻接表:顶点用 一维数组存储,后面跟着 单链表 存储邻接点。

                                                                          • 邻接表 中 邻接点的个数 和 图中这个顶点 的出度有关。

                                                                            带权图

                                                                            • 边 给一个值,称之为 边权,对应图 称之为 带权图,也称之为 网。

                                                                              深度优先遍历 DFS

                                                                              • 不撞南墙不回头(遍历不唯一)。

                                                                                广度优先遍历算法

                                                                                • 相当于我们的二叉树层次遍历(用到队列,先进先出)。
                                                                                • 记得保持顺序。

                                                                                  G = (V,E) :G指的图 V指的顶点 E指的边。

                                                                                  • 强连通图:任意顶点都能到达其他顶点,称之为:强连通图。

                                                                                    最小生成树

                                                                                    • 生成树:顶点由边连接在一起,不存回路的图。

                                                                                      • 生成树顶点个数 和 图顶点个数相同。

                                                                                      • 生成树(极小连通图) 去掉一条边,则变成非连通图。

                                                                                      • 连通图有 n 个顶点,则其 生成树 有 n-1条边。

                                                                                      • 生成树 再加一条边,必然形成回路。

                                                                                        含有 n 个顶点 n-1 条边的图,不一定是 生成树。

                                                                                      • 无向图的生成树

                                                                                        • 深度优先生成树
                                                                                        • 广度优先生成树
                                                                                        • 最小生成树:边权值之和最小的树。

                                                                                          普利姆算法(Prim)

                                                                                          • 普利姆算法 和 点 有关。
                                                                                          • 每次去找和点连接的最小权值的边(包括之前的点)。

                                                                                            克鲁斯卡尔算法(Kruskal)

                                                                                            • 克鲁斯卡尔 和 边 有关。

                                                                                            • 每次去找 边权值 最小的边,两个顶相连,依次构成最小生成树。

                                                                                              最短路径

                                                                                              迪杰斯特拉(Dijkstra)

                                                                                              • 两点间最短路径。

                                                                                                弗洛伊德(Floyd)

                                                                                                • 所有顶点间的最短路径。
                                                                                                • 两个矩阵,一个存储 权值,一个存储 路径。
                                                                                                • 把所有的顶点依次加入矩阵中,找最小权值路径。

                                                                                                  拓扑排序

                                                                                                  AOV网

                                                                                                  • 顶点 表示 活动。
                                                                                                  • 弧 表示活动之间的有限制约关系。
                                                                                                  • 拓扑排序:前提 有向无环图。
                                                                                                  • 拓扑排序:找 入度为0(无前驱) 的结点 删除,循环上述过程即可。
                                                                                                  • 逆拓扑排序:找 出度为0(无后继) 的结点 删除,循环上述过程即可。
                                                                                                  • 判断 AOV网 中是否有环。

上一篇:dell服务器盖怎么拆?

下一篇:怎么打开小米的云服务器?