数据结构算法实现及例题

基础数据结构算法实现总结,包括链表:顺序存储及链式存储形式下的单链表,双向链表及循环链表的操作实现

队列:循环队列,简单队列

栈:栈的增删改查操作等

字符串数组:KMP算法及BF算法

图:图在邻接表和邻接矩阵存储形式下的BFS和DFS算法实现,迪杰斯特拉算法等经典算法

简单查找与排序算法实现:快速排序等

注:本人才疏学浅,理解有限,所有分享仅供参考;

数据结构与算法教学视频推荐(青岛大学王卓老师)https://www.bilibili.com/video/BV1nJ411V7bd

顺序表中去除重复元素:

在长度为n(n<1000)的顺序表中可能存在着一些值相同的“多余”数据元素(类型为整型),编写一个程序将“多余”的数据元素从顺序表中删除,使该表由一个“非纯表”(值相同的元素在表中可能有多个)变成一个“纯表”(值相同的元素在表中只能有一个)。

第一行输入表的长度n;

第二行输入顺序表初始存放的元素;

第一行输出删除后的元素个数

第二行输出删除后剩余的元素

代码如下:

#include<iostream>

#include<bits/stdc++.h>

using namespace std;

const int m = 1000;

int n;

struct Data

{

    int num;

    int flag = 0;

};



typedef struct Sqlist   //顺序表结构

{

    Data data[m];

    int n;

}Sqlist;



void Manage(Sqlist &L)   //标记数据中的重复数字

{

    for(int i = 0 ; i < n-1;i++){

        for(int j = i+1;j < n;j++){

            if(L.data[i].num == L.data[j].num) {L.data[j].flag = 1;}

        }

    }

    int num = 0,flag1 = 0;

    for(int i = 0;i < n;i++){

        if(L.data[i].flag == 0) num++;

    }

    cout<<num<<endl;

    for(int i = 0;i < n;i++){

        if(L.data[i].flag == 0 && flag1 == 0) {

            cout<<L.data[i].num;

            flag1 = 1;

        }

        else if(L.data[i].flag == 0 && flag1 == 1) cout<<" "<<L.data[i].num;

    }

    cout<<endl;

}

int main()

{

    while(cin>>n){

        Sqlist L;

        for(int i = 0; i < n;i++){

            cin>>L.data[i].num;

        }

        Manage(L);

    }

    return 0;

}

链表中删除指定元素:

输入n个整数,先按照数据输入的顺序建立一个带头结点的单链表,再输入一个数据m,

将单链表中的值为m的结点全部删除。分别输出建立的初始单链表和完成删除后的单链表。

Input

第一行输入数据个数n;

第二行依次输入n个整数;

第三行输入欲删除数据m。

代码如下:

#include<bits/stdc++.h>

#include<iostream>

using namespace std;

const int N = 1000;

int n,m; //m为要删除的数据值

typedef struct Lnode

{

    int num;

    struct Lnode *next;

}Lnode,*Lklist;



void InputLklist(Lklist &L)//尾插法创建链表

{

    L = new Lnode(); //创建头结点,L指针指向头结点

    L -> next = NULL;

    Lklist s = L;

    for(int i = 0; i < n; i++){

        Lklist p = new Lnode();//创建新结点

        cin >> p->num;

        p -> next = NULL;

        s -> next = p;

        s = p;//指针指向下一节点

    }

}



void ManageLklist(Lklist &L , int &m)

{

    Lklist s = L -> next;//s指向要比较的元素

    Lklist p = L;//p指向前一个元素,控制删除

    int newn = n;//newn记录节点数的变化

    for(int i = 0; i < n; i++){

        if(s->num == m){

            newn--;

            p->next = s->next;

            s = p->next;

        }

        else{

            p = p->next;

            s = s->next;

        }

    }

    n = newn;

}



void OutputLklist(Lklist &L)

{

    Lklist p = L->next;

    int flag =0;

    cout<<n<<endl;

    while(p){

        if(flag == 0) {

            cout<< p->num;

            flag = 1;

            p = p->next;

        }

        else{

            cout<<" "<<p->num;

            p = p->next;

        }

    }

    cout<<endl;

}

int main()

{

    Lklist L;

    while(cin>>n){

        L= NULL;//没进行一次测试就要对对头指针初始化

        InputLklist(L);

        cin>>m; //输入要删除的元素值

        OutputLklist(L);//输出初始数据



        ManageLklist(L,m);

        OutputLklist(L);//输出删除后的数据

    }

    return 0;

}

循环链表:

n个人想玩残酷的死亡游戏,游戏规则如下:

n个人进行编号,分别从1到n,排成一个圈,顺时针从1开始数到m,数到m的人被杀,剩下的人继续游戏,活到最后的一个人是胜利者。

请输出最后一个人的编号。

代码如下:

#include<bits/stdc++.h>

using namespace std;

const int N = 1000;

int n,m;

typedef struct Lnode

{

    int num;

    struct Lnode *next;

}Lnode,*Lklist;



void InputLklist(Lklist &L)

{

    L = new Lnode();//创建头节点

    L->next = NULL;

    Lklist s = L;

    for(int i = 1; i <=n ; i++){

        Lklist p = new Lnode();

        p->next = NULL;

        p->num = i;

        s ->next = p;

        s = p;

    }

    s->next = L->next;//尾节点指针指向头结点后面节点,形成循环链表

}



void ManageLklist(Lklist &L)

{

    cin>>m;//输入要数的数

    Lklist p = L->next;

    for(int i = n;i > 0; i--){

        if(i>1){

            for(int j = 0;j < m-2;j++){//找到要杀的那个人的前一个节点

                p = p->next;

            }

            p->next = p->next->next;

            p = p->next;//执行完一次游戏后轮到下一个人

        }

        else L->next = p;//好有一个人的时候,头结点指向该节点

    }

}



void OutputLklist(Lklist &L)

{

    cout << L->next->num << endl;

}

int main()

{



    Lklist L;

    while(cin>>n){

        InputLklist(L);

        ManageLklist(L);

        OutputLklist(L);

    }

    return 0;

}

字符串括号匹配问题:

给你一串字符,不超过50个字符,可能包括括号、数字、字母、标点符号、空格,你的任务是检查这一串字符中的( ) ,[ ],{ }是否匹配。

如果匹配就输出“yes”,不匹配输出“no”

代码如下:

#include<iostream>

#include<string.h>

using namespace std;

const int N = 100;

int st = 0;

string str;

typedef struct stack

{

    char *top;

    char *base;

    int size;

    int flag;//标志位,如果有多余的右括号直接说明不匹配



}Sqstack;//顺序表



void InsitStack(Sqstack &S)//初始化栈

{

    S.base = new char[N];//开辟字符串数组

    S.top = S.base;

    S.size = 0;

    S.flag = 0;

}



void PushStack(Sqstack &S , char &ch)//压入元素

{

    *S.top = ch;

    S.top++;

    S.size++;

}



void OutStack(Sqstack &S)//弹出元素

{

    if(S.size > 0){

        S.top--;

        S.size--;

    }

}



char GetStack(Sqstack &S)//返回栈顶元素

{

    if(S.size > 0){

        char ch;

        --S.top;

        ch = *S.top;

        S.top++;

        return ch;

    }

}

void JudgeStack(Sqstack &S)

{

    char chTem;

    for(int i = 0;i < st; i++){

        if(str[i] == '(' || str[i] == '[' || str[i] == '{'){

            PushStack(S,str[i]);

           }

        else if(str[i] == ')'){

            chTem = GetStack(S);

            if(chTem == '(' && str[i] == ')') OutStack(S);

            else S.flag = 1;//有一次符号不匹配,直接整个字符中不匹配

        }

        else if(str[i] == ']'){

            chTem = GetStack(S);

            if(chTem == '[' && str[i] == ']') OutStack(S);

            else S.flag = 1;

        }

        else if(str[i] = '}'){

            chTem = GetStack(S);

            if(chTem == '{' && str[i] == '}') OutStack(S);

            else S.flag = 1;

        }

    }

}

void PrintfStack(Sqstack &S)

{

    if(S.top == S.base && S.flag == 0) cout<<"yes"<<endl;

    else cout<<"no"<<endl;

}

int main()

{

    while(cin>>str){//能够直接输入空格

        st = str.length();//获取字符长度

        Sqstack S;

        InsitStack(S);//初始化栈

        JudgeStack(S);//对栈进行判断

        PrintfStack(S);//输出结果

    }

    return 0;

}

栈的出栈顺序判定问题:

给定一个从1开始的连续整数列1、2、3、4......n。

将上述数列按顺序入栈,中途栈顶元素可以出栈。

再给定一个出栈序列,判断此序列是否合法。

例如,将n设为4。即得到数列1、2、3、4。

再给定出栈序列1、3、4、2。 可以看出,此出栈序列合法。 过程如下,

先将数列1、2、3、4中的元素1入栈,再将其出栈。

然后将元素2、3入栈,将元素3出栈。

最后将元素4入栈,再把栈内的仅余元素4、2出栈。

整个过程中,元素按照1、3、4、2的顺序出栈。证明其合法

输入包括多组测试用例。

对于每组测试用例,第一行包含一个整数n<100,代表从1开始的连续整数列长度。

第二行包含一个长度为n的数列,代表出栈序列。出栈序列的各元素在区间[1,n]内且不重复。

代码如下:

#include<iostream>

using namespace std;

const int N =101;

int n = 0;

int sure[N];//保存给定的出栈次序



typedef struct stack

{

    int *top;

    int *base;

    int size;

}Sqstack;



void InsitStack(Sqstack &S)

{

    S.base = new int[N];//开辟一个int型数组

    S.top = S.base;

    S.size = 0;

}



void PushStack(Sqstack &S , int &tem)

{

     *S.top = tem;//注意赋值的时候的写法

     S.top++;

     S.size++;

}



void OutStack(Sqstack &S)

{

    if(S.size > 0){

        S.top--;

        S.size--;

    }

}



int GetStack(Sqstack &S)

{

    if(S.size > 0){

        int tem;

        S.top--;

        tem = *S.top;

        S.top++;

        return tem;

    }

}



void ManageStack(Sqstack &S)

{

    int j = 0;

    for(int i = 1;i <= n; i++){

        PushStack(S,i);

        while((S.size != 0) && (GetStack(S) == sure[j])){//while循环能够在一次for语句下循环多次,只要条件符合(每次压入后都与出栈顺序进行比较)

            OutStack(S);

            j++;

        }

    }

}

void PrintfStack(Sqstack &S)

{

    if(S.size == 0) cout<<"Yes"<<endl;//栈空时为正确序列

    else cout<<"No"<<endl;

}

int main()

{

    while(cin>>n){

        Sqstack S;

        for(int i = 0; i < n;i++) cin>>sure[i];

        InsitStack(S);

        ManageStack(S);

        PrintfStack(S);

    }

}

给一个十进制数字,输出他的八进制形式

Input

一个十进制数字(int范围内)

再输入一个数字的表示要转换为R进制

Output

输入数字的R进制结果

Sample Input

7 8

8 8

Sample Output

7

10

代码如下:

//十进制数的进制转置

#include<iostream>

#define MAXSIZE 1000

using namespace std;

typedef struct stack

{

    int *top;

    int *base;

    int size;

}Sqstack;

void InsitStack(Sqstack &S)

{

    S.base = new int[MAXSIZE];//开辟数组空间

    if(!S.base){

        //cout<<"开辟空间失败!!!"<<endl;

    }

    else{//初始化栈的头指针,尾指针和长度

        S.top = S.base;

        S.size = 0;

    }

}

void PushStack(Sqstack &S,int &size)

{

    if(S.top - S.base == MAXSIZE){

        //cout<<"栈空间已满。"<<endl;

    }

     else{

        *S.top = size;

        S.top++;

        S.size++;

    }

}

void OutStack(Sqstack &S)

{

    if(S.size != 0){

        S.top--;

        cout<<*S.top;

        S.size--;

    }

}

int main(){

    int num,R;

    while(cin>>num){

        cout<<"请确定要转换为几进制数:";

        cin>>R;

        Sqstack S;

        InsitStack(S);

        int tem;

        do{

            tem = num%R;

            PushStack(S,tem);

            num = num/R;

        }while(num!=0);

        while(S.size != 0){

            OutStack(S);

        }

        cout<<endl;

    }

}

定义一个数字消除游戏的规则,如果相邻两个数的和为0,就把这两个数消除。

比如一个序列为:1, 2, -2, -1。因为2和-2和为0,所以同时删除,删除之后1和-1和为0,又可以删除。所以最后这个序列为空。

又比如一个序列为:1, 2, -1, -2。因为相邻的没有和为0的所以最后的序列为1, 2, -1, -2。

Input

多组测试数据,对于每组测试数据:

第一行是一个整数N,N < 50

第二行是N个有空格分开的实数,绝对值小于20。

Output

如果经过消除,最后这个序列为空,输出"RedHat V5!"

如果不为空输出剩余数字的和。

Sample Input

4

1 2 -2 -1

4

1 2 -1 -2

Sample Output

RedHat V5!

0

代码如下:

#include<iostream>

#include<math.h>

#define MAXSIZE 50

using namespace std;

typedef struct stack

{

    int *top;

    int *base;

    int size;

}Sqstack;

void InsitStack(Sqstack &S)

{

    S.base = new int[MAXSIZE]; //开辟一个MAXSIZE大小的数组空间并将首地址赋给base

    if(!S.base){

        //cout<<"开辟空间失败"<<endl;

    }

    else{

        S.top = S.base;

        S.size = 0;

    }

}

void PushStack(Sqstack &S,int n)

{

    if(S.top-S.base == MAXSIZE){

        //cout<<"数组空间已满,无法存储"<<endl;

    }

    else{

        *S.top = n;

        S.top++;

        S.size++;

    }

}



int GetStack(Sqstack &S)

{

    if(S.top == S.base){

        //cout<<"栈里没有元素"<<endl;

        return 0;

    }

    else{

        int e;

        --S.top;

        e = *S.top;

        S.top++;

        return e;

    }

}



void OutStack(Sqstack &S)

{

    if(S.top != S.base){

        S.top--;

        S.size--;

    }

}

void JudgeStack(Sqstack &S,int a[],int &N)

{

    PushStack(S,a[0]);

    for(int i = 1;i<N;i++){

        if(a[i] + GetStack(S) ==0){

            OutStack(S);

        }

        else{

            PushStack(S,a[i]);

        }

    }

}

void PrintStack(Sqstack &S,int &sum)

{

    if(S.top == S.base){

        cout<<"RedHat V5!"<<endl;

    }

    else{

        cout<<sum<<endl;

    }

}

main()

{

    int N;

    int a[MAXSIZE];

    while(cin>>N){

        int sum = 0;

        for(int i = 0;i<N;i++){

            cin>>a[i];

            sum = sum + a[i];

        }

        Sqstack S;

        InsitStack(S);

        OutStack(S);

        JudgeStack(S,a,N);

        PrintStack(S,sum);

    }

}

顺序表:

//单向链表的增删改查

#include<iostream>

using namespace std;

typedef struct node{

    int data;

    struct node *next;

}Lnode,*Lklist;

void CreateLklist(Lklist &L,int &n)

{

    Lklist Tem = L;

    Lklist p;

    for(int i = 0;i < n;i++){

        p = new Lnode();

        cin >> p->data;

        Tem->next = p;

        Tem = p;

    }

    cout<<"创建完后有"<<n<<"个元素,分别为:"<<endl;

}

void InsertLklist(Lklist &L,int &n,int &ins)

{

    if(ins > n+1 || ins<1){

        cout<<"插入位置错误!!!"<<endl;

    }

    else{

        n++;

        Lklist Tem = L;

        Lklist p = new Lnode();

        cout<<"请输入要插入元素的数据:"<<endl;

        cin>> p->data;

        for(int i = 0;i<ins-1;i++){

            Tem = Tem->next;

        }

        p->next = Tem->next;

        Tem->next = p;

        cout<<"插入后共有"<<n<<"个元素,在第"<<ins<<"个元素之前插入后:"<<endl;

    }

}

void DeleteLklist(Lklist &L,int &n,int &dele)

{

    if(dele>n || dele<1){

        cout<<"删除位置错误!!!"<<endl;

    }

    else if(0<dele && dele<n){

        n--;

        Lklist Tem = L;

        for(int i = 0;i<dele-1;i++){

            Tem = Tem->next;

        }

        Tem->next = Tem->next->next;

        cout<<"删除后共有"<<n<<"个元素,删除之后的元素为:"<<endl;

    }

    else{

        n--;

        Lklist p = L;

        for(int i = 0;i<n-1;i++){

            p = p->next;

        }

        p->next = NULL;

        cout<<"删除后共有"<<n<<"个元素,删除之后的元素为:"<<endl;

    }

}

void LocateLklist(Lklist &L,int &n,int &loc)

{

    if(loc<1 || loc>n){

        cout<<"查找元素位置错误!!!"<<endl;

    }

    else{

        Lklist Tem = L;

        for(int i = 0;i<loc;i++){

            Tem = Tem->next;

        }

        cout<<"你要查找的元素是:"<< Tem->data <<endl;

    }

}

void PrintfLklist(Lklist &L,int &n)

{

    Lklist p = L;

    for(int i = 0;i < n;i++){

        p = p->next;

        cout<<p->data<<" ";

    }

    cout<<endl;

}

main()

{

    int n,ins,loc,dele;

    Lklist L;

    while(1){

        cout<<"请输入此链表里的元素个数:"<<endl;

        cin>>n;

        L = new Lnode();

        CreateLklist(L,n);

        PrintfLklist(L,n);

        cout<<"请输入你要在第几个元素前插入:"<<endl;

        cin>>ins;

        InsertLklist(L,n,ins);

        if(0<ins && ins<n+1){

        PrintfLklist(L,n);

        }

        cout<<"请输入你要删除第几个元素:"<<endl;

        cin>>dele;

        DeleteLklist(L,n,dele);

        if(0<dele && dele<n+1){

             PrintfLklist(L,n);

        }

        cout<<"请确定你要查找第几个元素:(范围为1~"<<n<<")"<<endl;

        cin>>loc;

        LocateLklist(L,n,loc);

        free(L);

        system("pause");

    }

}

栈和队列:

/*链式队列的入队列和出队列操作

1.插入在对位,删除在队首(有头结点)

2.链队的长度不确定

*/

#include<iostream>

using namespace std;

typedef struct node

{

    int data;

    struct node *next;

}Qnode,*QuenePtr;//定义具体的队列内的某一个节点

typedef struct

{

    QuenePtr front;//链队中指向头结点类型的指针

    QuenePtr rear;//链队的尾指针

}LkQuene;//定义一个链队

void InsitLkQuene(LkQuene &Q)

{

    Q.front = new Qnode();//定义头结点

    Q.rear = Q.front;//初始情况下头指针与尾指针都指向头结点

    Q.front->next = NULL;//初始化时头结点的next域为空

}

void InsertLkQuene(LkQuene &Q)//插入在队尾

{

    QuenePtr p = new Qnode();//定义一个新节点,并把地址赋给p

    if(p){//地址赋值成功再进行插入

        cout<<"请输入插入元素的数据:";

        cin>>p->data;

        p->next = NULL;

        Q.rear->next = p;

        Q.rear = p;

        cout<<"插入成功"<<endl;

        cout<<Q.rear->data<<endl;

    }

    //free(p);//此处不能free(p),p是创建的的节点,如果free掉,会把创建的节点空间一块释放掉,插入的时候不能free操作

}

void  DeleteLkQuene(LkQuene &Q)

{

    if(Q.front != Q.rear){//删除在队首

        QuenePtr p;

        p = Q.front->next;//p指向头结点后一个节点

        Q.front->next = p->next;//front的next域改为删除节点的下一个节点

        if(Q.rear == p){//特殊情况,队列中只有一个头结点和尾节点,在上述步骤进行完之后,rear指向节点被删除

            Q.rear = Q.front;//此时就只有一个头节点,则两者地址相同

        }

        free(p);

        cout<<"删除成功"<<endl;

    }

    else{

        cout<<"队列已经为空!!!"<<endl;

    }

}

void PrintLkQuene(LkQuene &Q)

{

    if(Q.front == Q.rear){

        cout<<"队列为空!!!"<<endl;

    }

    else{

        QuenePtr p = Q.front;

        cout<<"队列内元素为:";

        while(Q.front != Q.rear){

            Q.front = Q.front->next;

            cout<<Q.front->data<<" ";

        }

        cout<<endl;

        Q.front = p;

    }

}

int main()

{

    LkQuene Q;

    int flag;

    InsitLkQuene(Q);

    cout<<"输入1为插入操作,输入2为删除操作,输入3为输出元素操作。请输入:";

    while(cin>>flag){

        if(flag == 1){

            InsertLkQuene(Q);

        }

        else if(flag == 2){

            DeleteLkQuene(Q);

        }

        else if(flag == 3){

            PrintLkQuene(Q);

        }

        cout<<"输入1为插入操作,输入2为删除操作,输入3为输出元素操作。请输入:";

    }

    system("pause");

}

//链式存储形式下出栈和入栈

#include<iostream>

using namespace std;

typedef struct stack

{

    int data;

    struct stack *next;

}StackNode,*LkStack;



void CreateLkstack(LkStack &top,int &len)

{

    cout<<"请输入数据:"<<endl;

    for(int i = 0;i<len;i++){

        LkStack p = new StackNode();

        cin>>p->data;

        p->next = top;//用尾插法把新建立的节点的指针域联系起来(此时节点的指针域为上一个节点地址,若该节点是第一个节点,则该节点的指针域为空)

        top = p;//赋给top指针当前节点地址,以便作为下一节点的指针域(即修改栈顶指针)

    }//n个节点建立之后,top指针指向栈顶位置,链的顺序是自上而下的

    cout<<"此时栈内元素个数为:"<<len<<endl;

}



void PopStack(LkStack &top,int &out,int &len)

{

    if(out>len){

        cout<<"输出的元素大于栈内元素个数!!!"<<endl;

    }

    else{

        LkStack Tem;

        cout<<"出栈元素为:"<<endl;

        for(int i = 0;i<out;i++){//出栈的元素个数

            Tem = top;

            cout<<Tem->data<<" ";

            top = Tem->next;

        }

        cout<<endl;

        free(Tem);

    }

}

main()

{

    int len,out;

    cout<<"请确定链栈的长度:"<<endl;

    while(cin>>len){

        LkStack top = NULL;//链栈没有头结点,直接new一个指针为头指针

        CreateLkstack(top,len);

        cout<<"请确定要出栈几个元素:"<<endl;

        cin>>out;

        PopStack(top,out,len);

        system("pause");

        cout<<"请确定链栈的长度:"<<endl;

    }

}

//循环队列在顺序存储下的表示

#include<iostream>

using namespace std;

typedef struct

{

    int *base;//指向数组的首元素

    int front;//头指针(并非真正的指针变量,用来表示下标的位置)

    int rear;//尾指针(同上)

}SqQuene;

void InsitSqQuene(SqQuene &Q,int &n)

{

    Q.base = new int[n];

    Q.front = Q.rear = 0;

}

/*

1.循环队列在表尾进行插入,在表头进行删除;先进的先出,即插入时rear动,删除时front动

2.循环队列的特点是逻辑上首尾相连,用取模(%n求余数)的方式来表示要插入元素的位置

3.循环队列牺牲一个单位的空间来区别队列的空与满

    (1)如果队列为空,则Q.rear == Q.front

    (2)如果队列为满,则(Q.rear+1)%n == Q.front

4.求队列长度:(Q.rear - Q.front + n)%n

    (1)可能的情况是rear指针已经循环到front指针的下方,所以要加上总长度n

    (2)如果rear正常的在front的上方,加上n也会被%取余给过滤掉

*/

void InsertSqQuene(SqQuene &Q,int &n)

{

    if((Q.rear+1)%n == Q.front){//判断队列是否已经满了,满了就不能继续存放数据了

      

        cout<<"队列已满!!!"<<endl;

    }

    else{

        cout<<"请输入要插入的数据:";

        cin>>Q.base[Q.rear];//先把数据输入

        Q.rear = (Q.rear+1)%n;

    }

    cout<<"此时队列里有元素个数为:"<<(Q.rear-Q.front +n)%n<<endl;

}

void DeleteSqQuene(SqQuene &Q,int &n)

{

    if(Q.rear == Q.front){

        cout<<"队列为空!!!"<<endl;

    }

    else{

        Q.front = (Q.front+1)%n;//删除即把元素位置往前进一个单位,并不是把之前的元素空间释放,同时rear指针不动

    }

    cout<<"此时队列里有元素个数为:"<<(Q.rear-Q.front +n)%n<<endl;

}

void PrintDSqQuene(SqQuene &Q,int &n)

{

    if(Q.rear != Q.front){

        cout<<"队列里的元素为:";

        int Tem = Q.front;//Tem为中间变量,输出完毕后把front的值回复为初始状态

        while(Q.rear != Q.front){

            cout<<Q.base[Q.front]<<" ";

            Q.front = (Q.front +1)%n;

        }

        Q.front = Tem;

    }

    cout<<endl;

}

main(){

    int n,flag;

    cout<<"请确定队列的长度:";

    while(cin>>n){

        SqQuene Q;

        InsitSqQuene(Q,n);

        cout<<"请确定进行插入还是删除,输入1为插入,输入2为删除,输入3为输出队列里现有的元素!"<<endl;

        while(cin>>flag){

            if(flag == 1){

                InsertSqQuene(Q,n);

            }

            else if(flag==2){

                DeleteSqQuene(Q,n);

               

            }

            else if(flag == 3){

                PrintDSqQuene(Q,n);

            }

            cout<<"请确定进行插入还是删除,输入1为插入,输入2为删除,输入3为输出队列里现有的元素!"<<endl;

        }

        //PrintDSqQuene(Q,n);

        system("pause");

        cout<<"请确定队列的长度:";

    }

}

//入栈出栈的顺序存储形式

#include<iostream>

#define MAXSIZE 100

using namespace std;

typedef struct

{

    int *top;

    int *base;

    int size;

}Sqstack;

void InsitStack(Sqstack &S)

{

    S.base = new int[MAXSIZE];//开辟数组空间

    if(!S.base){

        cout<<"开辟空间失败!!!"<<endl;

    }

    else{//初始化栈的头指针,尾指针和长度

        S.top = S.base;

        S.size = 0;

    }

}

void PushStack(Sqstack &S,int &size)

{

    if(S.top - S.base == MAXSIZE){

        cout<<"栈空间已满。"<<endl;

    }

    else{

        cout<<"请输入数据:"<<endl;

        for(int i = 0;i<size;i++){//通过top指针所指地址开对栈空间压入元素

            cin>>*S.top;

            S.top++;

            S.size++;

        }

    }

    cout<<"此时栈中元素个数为:"<<S.size<<endl;

}



void PopStack(Sqstack &S,int &size)

{

    if(S.top <= S.base){

        cout<<"栈中无元素!!!"<<endl;

    }

    else{

        int flag = 0;//flag控制空格输出

        cout<<"栈中的元素如下:"<<endl;

        for(int i = 0;i<size;i++){

            if(flag == 0){

                S.top--;

                cout<<*S.top;

                S.size--;

                flag = 1;

            }

            else{

                S.top--;

                cout<<" "<<*S.top;

                S.size--;

            }

        }

        cout<<endl;

    }

}

main()

{

    int size;

    cout<<"请确定栈的长度(100之内):"<<endl;

    while(cin>>size){

        Sqstack S;

        InsitStack(S);

        PushStack(S,size);

        PopStack(S,size);

        cout<<"请确定栈的长度(100之内):"<<endl;

    }

}

字符串:

//KMP算法

#include <iostream>

using namespace std;

const int N = 100010 , M = 1000010;

char a[N] , b[M];

int n , m;

int ne[N];

int main()

{

    //此时将字符串从下标为1开始进行输入

    cin >> n >> a + 1 >> m >> b + 1;

    //求ne[]数组

    for (int i = 2 , j = 0 ; i <= n ; i ++)

    {

        while (j && a[j + 1] != a[i]) j = ne[j];

        if (a[j + 1] == a[i]) j ++;

        ne[i] = j;

    }

    //进行kmp

    for (int i = 1 , j = 0 ; i <= m ; i ++)

    {//此时i表示的是b数组的下标

        while (j && a[j + 1] != b[i]) j = ne[j];

        if (a[j + 1] == b[i]) j ++;

        if (j == n)

        {

            cout << i - j << ' ';

            j = ne[j];

        }
    cout << endl;

    return 0;

}

//BF算法:

#include<iostream>

#include<String.h>

#define MAX 100

using namespace std;

void CompareChar(char ma[],char ch[])

{

    int len1 = strlen(ma);

    int len2 = strlen(ch);

    //cout<<len1<<" "<<len2;

    int i = 0,j = 0;

    while(i<len1 && j<len2){

        if(ma[i] == ch[j]){//主串和字符串依次匹配下一个字符

            i++;

            j++;

        }

        else{//主串,子串指针回溯重新开始下一次匹配

            i = i-j+1;//主串从上次比对的地方重新开始匹配(因为字符从0开始进行比较,所以当不满足条件的时候,i减去已经比较的j个字符个数,再加1往前一个)

            j = 0;//子串从第一个字符重新开始匹配

        }

    }

    if(j == len2){//如果匹配成功,则子串全部对比完成

        cout<<"匹配成功,从主串中第"<<i-len2+1<<"个字符开始为匹配子串!"<<endl;

    }

    else{

        cout<<"匹配不成功!"<<endl;

    }
}

main()

{  

    while(1){

        char ma[MAX],ch[MAX];//一个主串,一个子串

        cout<<"请输入主串:";

        gets(ma);

        cout<<"请输入子串:";

        gets(ch);

        CompareChar(ma,ch);

    }

    system("pause");

}

图:

//法1 Dijkstra算法

求起始点1到N的最短路径.

Input

多组测试数据,对于每组数据

第一行是两个整数N, M。分别代表定点的数个和边的关系的个数。

从第二行至M+1行,每行三个整数,start, end, value。代表,节点start,节点end之间有一条长度为value的无向边。求1到N的最短路径。

(M, N, start, end, value < 100)

Output

对于每组测试数据,输出一个整数result,代表1至N的最短路径。

代码如下:

#include<iostream>

#define MAX 101

using namespace std;

const int N = 80;

int dist[N];

bool st[N];

typedef struct

{

    int arcs[N][N];

    int vexnum,arcnum;

}AMGrap;

void CreateGrap(AMGrap &G,int &m,int &n)

{

    int v1,v2,w,i,j;

    G.vexnum = m;

    G.arcnum = n;

    for(i = 1; i <= G.vexnum; i++){//初始化邻接矩阵

        for(j = 1; j <= G.vexnum; j++){

            if(i == j) {G.arcs[i][j] = 0;}

            else {G.arcs[i][j] = MAX;}

        }

    }

    for(i = 0; i < G.arcnum; i++){//构建无向网

        cin>>v1>>v2>>w;

        G.arcs[v1][v2] = w;

        G.arcs[v2][v1] = w;

    }

}

bool Judge(int &n)

{

    for(int i = 1; i <= n; i++){//只要st集合中不等于顶点全集,就返回true

        if(!st[i]) return true;

    }

    return false;

}

void DjsGrap(AMGrap &G)

{

    int v = 1,i,j,min;

    for(i = 1; i <= G.vexnum; i++) dist[i] = G.arcs[v][i];

    dist[v] = 0;

    for(i = 1; i <= G.vexnum; i++) st[i]  = false;

    st[v] = true;



    while(Judge(G.vexnum)){

        j = 1,min = MAX;

        for(i = 1; i <= G.vexnum; i++){

            if(!st[i]){

                if(min >= dist[i]) {min = dist[i]; j = i;}

            }

        }

        st[j] = true;//j加入st集合

        for(i = 1; i <= G.vexnum; i++){

            if(!st[i]){

                if(dist[i] >= dist[j] + G.arcs[j][i]) dist[i] = dist[j] + G.arcs[j][i];

            }

        }

    }

}

int main()

{

    AMGrap G;

    int m,n;

    while(cin>>m>>n){

        CreateGrap(G,m,n);

        DjsGrap(G);

        cout<<dist[G.vexnum]<<endl;

    }

}

//法2:

//Floyd算法 找最短路径,同时记录了最短路径

//邻接矩阵

#include<iostream>

#include<stack>

using namespace std;

#define MaxVnum 100 //顶点数最大值

const int INF = 1e7; //无穷大

int dist[MaxVnum][MaxVnum]; //某个点最短路径数组

int p[MaxVnum][MaxVnum]; //某个点的前驱数组

bool flag[MaxVnum]; //某个顶点已经加入S集合中

typedef struct {

    int Vex[MaxVnum];

    int Edge[MaxVnum][MaxVnum];

    int vennum,edgenum; //真实的顶点个数和边个数

}AMGraph;

void CreateGraph(AMGraph &G, int n, int m)

{

    G.vennum = n;

    G.edgenum = m;

    for(int i = 0; i < G.vennum; i++){

        G.Vex[i] = i + 1;

    }

    //初始化过程

    for(int i = 0; i < G.vennum; i++){

        for(int j = 0; j < G.vennum; j++){

            if(i != j){

                G.Edge[i][j] = INF;

            } else{

                G.Edge[i][j] = 0;

            }

        }

    }

    int w;

    // cout<<"请输入哪两点和其权值"<<endl;

    int u,v;

    while(G.edgenum--){

        cin>>u>>v>>w; //a b 权值

        int i = u - 1; //获取顶点下标

        int j = v - 1; //获取顶点下标

        if(i != -1 && j != -1){ //i j找到了位置

            G.Edge[i][j] = w;

        } else{

            cout<<"请重新输入边的顶点信息"<<endl;

            G.edgenum++; //当输入错误后把while条件加回来否则死循环 本次输入不算

        }

    }

}

void Floyd(AMGraph G) //找到i和j之间的最短路径

{

    for(int i = 0; i < G.vennum; i++){

        for(int j = 0; j < G.vennum; j++){

            dist[i][j] = G.Edge[i][j]; //初始化

            if(dist[i][j] < INF && i != j){

                p[i][j] = i; //如果i和j之间有弧 则为i

            } else{

                p[i][j] = -1; //如果i和j之间无弧 则为-1

            }

        }

    }

    for(int k = 0; k < G.vennum; k++){

        for(int i = 0; i < G.vennum; i++){

            for(int j = 0; j < G.vennum; j++){

                if(dist[i][k] + dist[k][j] < dist[i][j]){ //从i经k到j的一条路径更短

                    dist[i][j] = dist[i][k] + dist[k][j]; //更新dist[i][j]

                    p[i][j] = p[k][j]; //更新前驱

                }

            }

        }

    }

}

int main()

{

    AMGraph G;

    int n,m;

    while(cin>>n>>m){

        CreateGraph(G,n,m);

        Floyd(G);

        cout<<dist[0][G.vennum - 1]<<endl;

    }

    return 0;

}

图的邻接矩阵形式下的DFS和BFS:

//邻接矩阵存储下的无向网的创建及DFS遍历(深度优先算法)BFS遍历(广度优先算法)

#include<iostream>

#define MaxNum 100//最大顶点数

#define MaxInt -1//表示极大值∞

using namespace std;

typedef struct

{

    int vexs[MaxNum];                           //顶点表

    int arcs[MaxNum][MaxNum];                   //邻接矩阵表

    int vexnum,arcnum;                          //图的顶点数和边数

}AMGrap;



void CreateGrap(AMGrap &G)//创建无向网图

{

    int v1,v2,w,i,j;

    cout<<"请输入图的顶点数和边数:";

    cin>>G.vexnum>>G.arcnum;                    //输入图的顶点数和边数



    for(i = 0; i < G.vexnum; i++) G.vexs[i] = i;//输入各个顶点的信息



    for(i = 0; i < G.vexnum; i++){//初始化邻接矩阵

        for(j = 0; j < G.vexnum; j++){

            G.arcs[i][j] = MaxInt;             //每个边的权值都为无穷大

        }

    }

    cout<<"请输入边的信息及权值:"<<endl;

    for(i = 0; i<G.arcnum; i++){

        cin>>v1>>v2>>w;                        //输入边所依附的顶点和边对应的权值

        G.arcs[v1][v2] = w;                    //<v1,v2> = w

        G.arcs[v2][v1] = G.arcs[v1][v2];       //邻接矩阵中<v1,v2>的对称边<v2,v1>的权值为w

    }

}

void PrintfGrap(AMGrap &G)

{

    cout<<"邻接矩阵为:"<<endl;

    for(int i = 0; i < G.vexnum; i++){

        for(int j = 0; j < G.vexnum; j++){

            cout<<G.arcs[i][j]<<" ";

        }

        cout<<endl;

    }

}



void InsitVisited(AMGrap &G,int visited[])

{

    for(int i = 0; i < G.vexnum; i++) visited[i] = 0;//初始化辅助数组都为0,表示都初始时未被访问

}

void DFSGrap(AMGrap &G,int &v,int visited[])

{

    cout<<v<<" ";

    visited[v] = 1;                           //在辅助数组中标记该顶点已经访问过



    for(int  i = 0; i < G.vexnum; i++){       //依次检查邻接矩阵中v行中未曾访问的邻接点

        if((G.arcs[v][i] != -1) && (visited[i] == 0)){//i是v的邻接点,若未曾访问,则调用递归

            DFSGrap(G,i,visited);

        }

    }

}

int main()

{

    AMGrap G;

    CreateGrap(G);

    PrintfGrap(G);



    int v,visited[G.vexnum];

    InsitVisited(G,visited);

    cout<<"请输入要从哪个顶点开始遍历:";

    cin>>v;

    cout<<"DFS序列为:";

    DFSGrap(G,v,visited);



    system("pause");

}

/*邻接表的输入输出示例:

请输入顶点数和边数:4 4

请输入边的信息及权值:

0 1 1

0 2 4

0 3 5

1 3 1

创建成功!

邻接表为:

0 -> 3 -> 2 -> 1

1 -> 3 -> 0

2 -> 0

3 -> 1 -> 0

请输入要从哪个顶点开始遍历:2

DFS序列为:2 0 3 1

BFS序列为:2 0 3 1

*/

//邻接表存储下的无向网的创建及DFS遍历(深度优先算法)BFS遍历(广度优先算法)

#include<iostream>

#define MaxNum 100            //最大顶点数

using namespace std;



typedef struct ArcNode//边结点

{

    int adjvex;               //顶点的邻接点在顶点数组中的下标位置

    struct ArcNode * nextarc; //指向下一个与数组中元素是邻接点的指针

    int info;                 //节点信息,比如权值等

}ArcNode,*PNode;



typedef struct//顶点结构

{

    int data;                 //顶点信息,通常没有用;除非用字符等表示顶点而不是下标时,用来存储符号等

    PNode firstarc;

}VNode,AdjList[MaxNum];      //创建顶点数组,AdjList表示邻接表类型



typedef struct//图的结构

{

    AdjList vertices;       //定义一个结构体数组实体,来存储顶点信息

    int vexnum,arcnum;      //顶点数和边数

}ALGrap;



typedef struct

{

    int *base,front,rear,size;

}SqQuene;//循环队列结构类型定义



void CreateGrap(ALGrap &G)

{

    int v1,v2,w,i;

    cout<<"请输入顶点数和边数:";

    cin>>G.vexnum>>G.arcnum;

    for(i = 0; i < G.vexnum; i++){

        G.vertices[i].data = i; //初始表结点,用0,1,2,3...表示

        G.vertices[i].firstarc = NULL;//将表中顶点的firstarc初始为空

    }



    cout<<"请输入边的信息及权值:"<<endl;

    for(i = 0; i < G.arcnum; i++){

        cin>>v1>>v2>>w;    //输入边的两个点及边的权值



        PNode p1 = new ArcNode();//创建一个边结点,头插法

        p1->adjvex = v2;

        p1->nextarc = G.vertices[v1].firstarc;//将新结点p用头插法插入vi的边表中,如果输入边时从小到大,输出会是从大到小

        G.vertices[v1].firstarc = p1;



        PNode p2 = new ArcNode();//无向网中有对称的边结点,在有向网或有向图中不用进行以下步骤

        p2->adjvex = v1;

        p2->nextarc = G.vertices[v2].firstarc;

        G.vertices[v2].firstarc = p2;

    }

    cout<<"创建成功!"<<endl;

    return;

}



void PrintfGrap(ALGrap &G)

{

    cout<<"邻接表为:"<<endl;

    for(int i = 0; i < G.vexnum; i++){

        PNode p = G.vertices[i].firstarc;//定义辅助结点指针初始指向该行链表的头结点

        cout<<i;

        while(p){

            cout<<" -> "<<p->adjvex;

            p = p->nextarc;

        }

        cout<<endl;

    }

}



void InsitVisited(int visited[],ALGrap &G)

{

    for(int i = 0; i < G.vexnum; i++) visited[i] = 0;//初始化辅助数组

}



void DFSGrap(ALGrap &G,int v,int visited[])

{

    cout<<v<<" ";

    visited[v] = 1;

    PNode p = G.vertices[v].firstarc;          //定义新的结点指针,对第v行链表进行从头开始的检查

    while(p){

        if((p != NULL) && (visited[p->adjvex] == 0)) DFSGrap(G,p->adjvex,visited);//如果该结点不为空并且该结点对应的邻接顶点未被访问过,进行递归

        p = p->nextarc;

    }

}



void InsitSqQuene(SqQuene &Q,ALGrap &G)//循环队列初始化

{

    Q.base = new int[G.vexnum];

    Q.front = Q.rear = Q.size = 0;

}

void InsertSqQuene(SqQuene &Q,int &v,ALGrap G)//入队

{

    if((Q.rear + 1) % G.vexnum == Q.front) return;

    //cout<<"("<<v<<")"<<endl;

    Q.base[Q.rear] = v;//插入队列中元素时用rear指针来控制插入

    Q.rear = (Q.rear + 1) % G.vexnum;

    Q.size++;

}

int DeleteSqQuene(SqQuene &Q,ALGrap G)//队头元素出队并作为返回值返回

{

    int tem = Q.base[Q.front];

    //cout<<"["<<tem<<"]"<<endl;

    Q.front = (Q.front + 1) % G.vexnum;

    Q.size--;

    return tem;

}



void BFSGrap(ALGrap &G,int v,int visited[],SqQuene &Q)

{

    cout<<v<<" ";

    visited[v] = 1;

    InsitSqQuene(Q,G);   //辅助循环队列初始化置空

    InsertSqQuene(Q,v,G);//v进队

    while(Q.size != 0){

        int u = DeleteSqQuene(Q,G);//队头元素出队并置为u

        PNode p = new ArcNode();

        p = G.vertices[u].firstarc;

        while(p){//在第u行依次找到未访问结点,while语句是用来控制循环,if循环控制是否进行该操作

            int w = p->adjvex;

            if(!visited[w]){

                cout<<p->adjvex<<" ";

                visited[p->adjvex] = 1;

                InsertSqQuene(Q,p->adjvex,G);

            }

            p = p->nextarc;

        }

        free(p);

    }

}



int main()

{

    ALGrap G;

    SqQuene Q;

    CreateGrap(G);

    PrintfGrap(G);



    int v,visited[G.vexnum];

    cout<<"请输入要从哪个顶点开始遍历:";

    cin>>v;

    InsitVisited(visited,G);

    cout<<"DFS序列为:";

    DFSGrap(G,v,visited);

    cout<<endl;



    InsitVisited(visited,G);

    cout<<"BFS序列为:";

    BFSGrap(G,v,visited,Q);

    cout<<endl;

    system("pause");

}

二叉树:

//链式存储之下的二叉树的先序建立方式和遍历方式(先序,中序,后序)计算数的深度,叶子结点,节点数。

#include<iostream>

#include<string.h>

using namespace std;

int n;

typedef struct Node

{

    char data;

    Node *lchild,*rchild;

}LkNode,*BiTree;

void CreateBiTree(BiTree &T)//手动建立一个二叉树,再根据节点顺序输入(先序建立以个二叉树)

{

    char ch;

    cin>>ch;

    if(ch == '0'){

        T = NULL;

        return;

    }

    else{

        T = new LkNode();

        T->data = ch;

        CreateBiTree(T->lchild);

        CreateBiTree(T->rchild);

    }

}



void PreOrderTraverse(BiTree &T)//先序遍历(先根遍历)

{

    if(T != NULL){

        cout<<T->data<<" ";

        PreOrderTraverse(T->lchild);

        PreOrderTraverse(T->rchild);

    }

    else return;

}



void MidOrderTraverse(BiTree &T)

{

    if(T != NULL){

        PreOrderTraverse(T->lchild);

        cout<<T->data<<" ";

        PreOrderTraverse(T->rchild);

    }

    else return;

}



void LastOrderTraverse(BiTree &T)

{

    if(T != NULL){

        PreOrderTraverse(T->lchild);

        PreOrderTraverse(T->rchild);

        cout<<T->data<<" ";

    }

    else  return;

}



int Depth(BiTree T)//左右子树本身的深度加1

{

    if(!T) return 0;

    else{

        int m,n;

        m = Depth(T->lchild);//左子树深度

        n = Depth(T->rchild);//右子树深度

        if(m > n) return m+1;

        else return n+1;

    }

}



int LeafCount(BiTree T)

{

    if(!T) return 0;

    else{

        if(!T->lchild && !T->rchild) return 1;//叶子即为根

        else return LeafCount(T->lchild) + LeafCount(T->rchild);

            //计算左子树和右子树的叶子节点之和

    }

}



int NodeCount(BiTree T)

{

    if(!T) return 0;

    else return NodeCount(T->lchild) + NodeCount(T->rchild) + 1;

}



//交换左右子树的所有节点2

void SwapBiTree(BiTree T){

    BiTree tem = new LkNode();

    if(T){

        tem = T->rchild;

        T->rchild = T->lchild;

        T->lchild = tem;

        SwapBiTree(T->lchild);

        SwapBiTree(T->rchild);

    }

    else return;

}



//实现复制二叉树

void CopyBiTree(BiTree T,BiTree &T2)

{

    T2 = new LkNode();

    if(T){

        T2->data = T->data;

        CopyBiTree(T->lchild , T2->lchild);

        CopyBiTree(T->rchild , T2->rchild);

    }

    else{

        T2 = NULL;

        return;

    }

}

main()

{

   

    while(1){

        cout<<"请输入节点:";

        BiTree root = NULL;//创建一个根节点开始二叉树的建立

        CreateBiTree(root);

        cout<<"按照先序次序输入的二叉树创建成功!"<<endl;



        cout<<"先序遍历的顺序为:";

        PreOrderTraverse(root);

        cout<<endl;



        cout<<"中序遍历的顺序为:";

        MidOrderTraverse(root);

        cout<<endl;



        cout<<"后序遍历的顺序为:";

        LastOrderTraverse(root);

        cout<<endl;

        cout<<"此二叉树的深度为:"<<Depth(root)<<endl;

        cout<<"此二叉树的叶子结点为:"<<LeafCount(root)<<endl;

        cout<<"此二叉树的节点数为:"<<NodeCount(root)<<endl;

    }

}

//完全二叉树的创建

#include<iostream>

#define MAX 1025

using namespace std;

int n;

void PreOrderTraverse(int Tree[],int i)

{

    if(i>n){//共n个节点,递归的条件是不会超过数组最大节点数

        return;

    }

    else{

        cout<<Tree[i-1]<<" ";

        PreOrderTraverse(Tree,2*i);

        PreOrderTraverse(Tree,(2*i)+1);

    }

}

main()

{

    int Tree[MAX];

    while(cin>>n){

        for(int i = 0;i<n;i++){

            Tree[i] = i+1;

        }

        PreOrderTraverse(Tree,1);

        cout<<endl;

    }

}

//最小生成树(基本都对应的无向图)--普利姆(Prim)算法--朴素版(对应为稠密图)

/*

步骤:

1.初始化邻接矩阵和dist数组

2.找到集合外距离集合最近的点并把它赋值给t,用t更新其余顶点到集合的距离

3.把t加到集合当中去,表明t成为最小生成树的一个顶点;继续迭代进行2

*/

#include<iostream>

#include<algorithm>

#include<cstring>

#define MAX  0x3f3f3f3f

using namespace std;

const int N = 100 ;

int n,m;

int g[N][N];

int dist[N];

bool st[N];//st数组定义后数组元素默认都为0,相当于false



//核心模板

int prim()

{

    memset(dist , 0x3f , sizeof dist);//初始化dist数组为无穷大

    int res  = 0;//rest记录最小生成树的权值之和

    for(int i = 0;i < n; i++){//n次循环,加入n个顶点

        int t = -1;

        for(int  j = 1;j <= n; j++){//从顶点1开始构造最小生成树

            if(!st[j] && (t == -1 || dist[t] > dist[j])) t = j;//找出每次更新后的最小权值边

        }



        if(i && dist[t] == MAX) return MAX;//此时说明图为非连通图,无法生成最小生成树

        if(i) res += dist[t];



        for(int j = 1; j <= n; j++) dist[j] = min(dist[j],g[t][j]);//找到一条生成树的边后更新其他店到集合内顶点的距离,为累积更新



        st[t] = true;

    }

    return res;

}

int main()

{

    cout<<"请输入边数和节点数:";

    cin>>n>>m;



    memset(g,0x37,sizeof g);//初始化邻接矩阵中所有元素为最大值

    cout<<"请输入边的邻接点及权值:"<<endl;

    while(m--){

        int v1,v2,w;

        cin>>v1>>v2>>w;

        g[v1][v2] = g[v2][v1] = min(g[v1][v2] , w);//边的权值要么是输入边中最小的,要么是无穷大

    }

   

    int t = prim();

    if(t == MAX) cout<<"impossible!"<<endl;

    else cout<<t<<endl;

    system("pause");

}

//二叉排序树:

#include <iostream>

using namespace std;

typedef struct tree

{

         int count;

         struct tree* pleft;//定义一个左指针

         struct tree* pright;//定义一个右指针

}Tree , *TreeNode;

void SetTree(TreeNode& pTree, int num)

{

         if (pTree == NULL)

         {

                  pTree = (TreeNode)malloc(sizeof (Tree));

                  pTree->count = num;

                  pTree->pleft = NULL;

                  pTree->pright = NULL;

         }



         else

         {

                  TreeNode pTemp = pTree;

                  while (1)

                  {

                          if (pTemp->count > num)

                          {

                                   if (pTemp->pleft != NULL)

                                            pTemp = pTemp->pleft;

                                   else

                                   {

                                            TreeNode pTemp1 = (TreeNode)malloc(sizeof (Tree));

                                            pTemp1->count = num;

                                            pTemp1->pleft = NULL;

                                            pTemp1->pright = NULL;

                                            pTemp->pleft = pTemp1;

                                            return;

                                   }

                          }



                          else if (pTemp->count < num)

                          {

                                   if (pTemp->pright != NULL)

                                   {

                                            pTemp = pTemp->pright;

                                   }

                                   else

                                   {

                                            TreeNode pTemp1 = (TreeNode)malloc(sizeof (Tree));//开辟一个结点

                                            pTemp1->count = num;

                                            pTemp1->pleft = NULL;

                                            pTemp1->pright = NULL;

                                            pTemp->pright = pTemp1;

                                            return;

                                   }

                          }



                          else if (pTemp->count == num)

                          {

                                   cout << "产生重复数字" << endl;

                                   return;

                          }

                  }

         }

}



void FindDel(TreeNode pTree, int num, TreeNode& pTemp, TreeNode& pfather)

{

         pTemp = pTree;

         while (pTemp){

                  if (pTemp->count == num){//此时表示当前根节点就是num

                          cout << "找到当前要找的数所对应的结点" << endl;

                          return;

                  }

                  else if (pTemp->count > num){

                          pfather = pTemp;

                                   pTemp = pTemp->pleft;

                  }

                  else if (pTemp->count < num){

                          pfather = pTemp;

                          pTemp = pTemp->pright;//将pTemp指向其右子树

                  }

         }

         cout << "该数值在当前的二叉搜索树中查找失败" << endl;

         return;

}

void FindMin(TreeNode& pTree, int num)

{

         if (pTree == NULL) return;

         TreeNode pTemp = NULL;

         TreeNode pfather = NULL;

         FindDel(pTree, num, pTemp, pfather);



         if (pTemp == NULL) return;

         TreeNode pMark = NULL;

         if (pTemp->pleft != NULL && pTemp->pright != NULL)

         {//此时找到的结点的左右子树都不是空的情况

                  pMark = pTemp;



                  pfather = pTemp;

                  pTemp = pTemp->pleft;



                  while (pTemp->pright){

                          pfather = pTemp;

                          pTemp = pTemp->pright;

                  }

                  pMark->count = pTemp->count;

         }

         if (pfather == NULL){

                  if (pTemp->pleft)

                  {

                          pTree = pTemp->pleft;//此时将根节点的指针指向根节点的左子树

                          //也就是将根节点删除了

                  }

                  else if (pTemp->pright){

                          pTree = pTemp->pright;

                  }

                  else{//此时表示这个根节点的左子树和右子树都是空的

                          pTree = NULL;//将根节点指针置空

                          free(pTemp);//将pTemp结点开辟的空间删除

                          pTemp = NULL;//将pTemp指针置空

                          return;

                  }

         }

         if (pfather->pleft == pTemp){

                  if (pTemp->pleft)

                          pfather->pleft = pTemp->pleft;

                  else

                          pfather->pleft = pTemp->pright;

         }

         else{

                  if (pTemp->pleft)

                          pfather->pright = pTemp->pleft;

                  else

                          pfather->pright = pTemp->pright;

         }



         free(pTemp);

         pTemp = NULL;

         return;

}

void GetTree(TreeNode pTree)

{

         if (pTree == NULL)

                  return;

         GetTree(pTree->pleft);

         cout << pTree->count << ' ';

         GetTree(pTree->pright);

}

int main()

{

         TreeNode pTree = NULL;

         int n, num;

         cin >> n;

         for (int i = 0; i < n; i++)

         {

                  cin >> num;

                  SetTree(pTree, num);

         }

         GetTree(pTree);

         cout << endl;

         cin >> num;

         cout<<"删除该节点后中序遍历序列为:";

         FindMin(pTree, num);

         GetTree(pTree);

         cout << endl;

         system("pause");

         return 0;

}

二叉平衡树的删除:

//右旋

 void RightTurn(Tree **pTree)

 {

     if(*pTree == NULL||(*pTree)->pLeft == NULL) return;



     Tree *pNode = *pTree; //A

     Tree *pMark = (*pTree)->pLeft; //B



     //三个孩子

     pNode->pLeft = pMark->pRight;

     pMark->pRight = pNode;



     if(pNode->pFather != NULL)

     {

         if(pNode == pNode->pFather->pLeft)

         {  

             pNode->pFather->pLeft = pMark;

         }

         else

             pNode->pFather->pRight = pMark;

     }

     else

     {

         //B成为新根

         *pTree = pMark;

     }

/三个父亲关系

     if(pNode->pLeft != NULL)

     {

         pNode->pLeft->pFather = pNode;

     }

     pMark->pFather = pNode->pFather;

     pNode->pFather = pMark;

 }



 //左旋

 void LeftTurn(Tree **pTree)

 {

     if(*pTree == NULL||(*pTree)->pRight == NULL) return;



     Tree *pNode = *pTree; //A

     Tree *pMark = (*pTree)->pRight; //C



     //三个孩子

     pNode->pRight = pMark->pLeft;

     pMark->pLeft = pNode;



     if(pNode->pFather != NULL)

     {

         if(pNode == pNode->pFather->pLeft)

            pNode->pFather->pLeft = pMark;

         else

             pNode->pFather->pRight = pMark;

     }      

     else

     {

         //C成为新根

         *pTree = pMark;

     }

     //三个父亲

     if(pNode->pRight != NULL)

         pNode->pRight->pFather = pNode;

     pMark->pFather = pNode->pFather;

     pNode->pFather = pMark;

 }

查找算法:

//基本查找算法

#include<iostream>

using namespace std;

const int N = 101;//数据个数最多为100

int n,key,a[N];//定义数据数组,n是数据个数,key是要查找的值,a[N]是顺序表

void SearchSeq()//顺序查找,数组次序无要求

{

    for(int i = n;i > 0 ; i--) {

        if(a[i] == key) {cout<<"该元素的位置为:"<<i<<endl; return ;}

    }

    cout<<"无该记录"<<endl;

    return;

}

void Search0()//哨兵查找,数组次序无要求

{

    a[0] = key;

    int i;//记录查找到的元素位置

    for(i = n ; a[i] != key ; --i);//当for循环没有循环语句时,结尾要加; ,锁定循环结束之后i的值

    if(i == 0) cout<<"无该记录"<<endl;

    else cout<<"该记录的位置为:"<<i<<endl;

}

void SearchHalf()//折半查找(二分查找),要求数列必须是有序的

{

    int low = 1,high = n,mid;

    while(low <= high){

        mid = (low + high) / 2;//每次查找跟mid比较,mid就是中间值

        if(a[mid] == key) {cout<<"该元素的位置为:"<<mid<<endl; return;}

        else if(key < a[mid]) high = mid - 1;

        else low = mid + 1;

    }

    cout<<"无该记录"<<endl;

}

int main()

{

    cout<<"请输入元素个数及数据记录:";

    cin>>n;

    for(int i = 1; i <= n;i++) cin>>a[i];//从1开始输入数据

    cout<<"请输入要查找的值:";

    cin>>key;

    SearchSeq();

    Search0();

    SearchHalf();

    system("pause");

}

/* i--是先赋值再--

--i是先--后赋值

*/

排序:

//归并排序--分治(双指针算法)由小到大进行排序

基本思想:

1.确定中间的分界点:mid = (l+r)/2

2.把数组从中间分成两部分,递归排序左右两部分

3.归并--合二为一

*/

#include<iostream>

using namespace std;

const int N = 1000010;

int n;

int q[N],tem[N];



void merge_sort(int q[],int l,int r)

{

    if(l >= r) return;

    int mid = l + r >> 1;//相当于int mid = (l+r)/2



    merge_sort(q,l,mid), merge_sort(q,mid + 1,r);



    int  k = 0,i = l,j = mid + 1;

    while(i <= mid && j <= r){

        if (q[i] <= q[j]) tem[k++] = q[i++];

        else tem[k++] = q[j++];

    }

    while(i <= mid) tem[k++] = q[i++];

    while(j <= r) tem[k++] = q[j++];



    for(i = l,j = 0;i <= r;i++,j++) q[i] = tem[j];

}

int main()

{

    scanf("%d",&n);

    for(int i = 0;i < n;i++ ) scanf("%d" , &q[i]);

    merge_sort(q,0,n-1);

    for(int  i = 0;i < n;i++ ) printf("%d " , q[i]);

    system("pause");

    return 0;

}

//插入排序

#include<iostream>

#include<math.h>

using namespace std;

const int N = 1e6 + 10;

int n;

int q[N];

//核心代码模板

void quick_sort(int q[], int l, int r)//l和r分别是指向左右的移动指针,当l>=r时,说明已经区间调整完毕

{

    if(l >= r) return;//判断当前区间只有一个数的时候就不用排序了

    int x = q[l], i = l-1, j = r+1;//

    while(i < j){//两个指针没有相遇或穿过

        do i++; while(q[i] < x);//左指针向右移,++(若想从大到小排序,只需改变这两句的比较符号)

        do j--; while(q[j] > x);//右指针向左移,--

        if(i<j) swap(q[i],q[j]);//当两个指针都停止时,进行两个指针所指元素的值得对换,对换之后判断i<j,继续调整区间

    }

    quick_sort(q, l, j);

    quick_sort(q, j+1, r);

}

int main()

{

    scanf("%d",&n);

    for(int i = 0; i < n; i ++ ){

        scanf("%d",&q[i]);

    }

    quick_sort(q,0,n-1);

    for(int i = 0; i < n; i++ ){

        printf("%d ",q[i]);

    }

    system("pause");

    return 0;

}

  • 3
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
1.1 数组和字符串 2 1.1.1 一维数组的倒置 2 范例1-1 一维数组的倒置 2 ∷相关函数:fun函数 1.1.2 一维数组应用 3 范例1-2 一维数组应用 3 1.1.3 一维数组的高级应用 5 范例1-3 一维数组的高级应用 5 1.1.4 显示杨辉三角 7 范例1-4 显示杨辉三角 7 ∷相关函数:c函数 8 1.1.5 魔方阵 9 范例1-5 魔方阵 9 1.1.6 三维数组的表示 14 范例1-6 三维数组的表示 14 ∷相关函数:InitArray函数 1.1.7 多项式的数组表示 17 范例1-7 多项式数组的表示 17 1.1.8 查找矩阵的马鞍点 19 范例1-8 查找矩阵的马鞍点 19 ∷相关函数:Get_Saddle函数 1.1.9 对角矩阵建立 21 范例1-9 对角矩阵建立 21 ∷相关函数:Store函数 1.1.10 三对角矩阵的建立 22 范例1-10 三对角矩阵的建立 22 ∷相关函数:Store函数 1.1.11 三角矩阵建立 24 范例1-11 三角矩阵建立 24 ∷相关函数:Store函数 1.1.12 对称矩阵的建立 25 范例1-12 对称矩阵的建立 25 ∷相关函数:store函数 1.1.13 字符串长度的计算 28 范例1-13 字符串长度的计算 28 ∷相关函数:strlen函数 1.1.14 字符串的复制 29 范例1-14 字符串的复制 29 ∷相关函数:strcpy函数 1.1.15 字符串的替换 31 范例1-15 字符串的替换 31 ∷相关函数:strrep函数 1.1.16 字符串的删除 33 范例1-16 字符串的删除 33 ∷相关函数:strdel函数 1.1.17 字符串的比较 35 范例1-17 字符串的比较 35 ∷相关函数:strcmp函数 1.1.18 字符串的抽取 36 范例1-18 字符串的抽取 36 ∷相关函数:substr函数 1.1.19 字符串的分割 38 范例1-19 字符串的分割 38 ∷相关函数:partition函数 1.1.20 字符串的插入 40 范例1-20 字符串的插入 40 ∷相关函数:insert函数 1.1.21 字符串的匹配 42 范例1-21 字符串的匹配 42 ∷相关函数:nfind函数 1.1.22 字符串的合并 43 范例1-22 字符串的合并 43 ∷相关函数:catstr函数 1.1.23 文本编辑 45 范例1-23 文本编辑 45 ∷相关函数:StrAssign函数 1.2 栈和队列 54 1.2.1 用数组仿真堆栈 54 范例1-24 用数组仿真堆栈 54 ∷相关函数:push函数 pop函数 1.2.2 用链表仿真堆栈 57 范例1-25 用链表仿真堆栈 57 ∷相关函数:push函数 pop函数 1.2.3 顺序栈公用 59 范例1-26 顺序栈公用 59 ∷相关函数:push函数 pop函数 1.2.4 进制转换问题 61 范例1-27 进制转换问题 61 ∷相关函数:MultiBaseOutput函数 1.2.5 顺序队列操作 64 范例1-28 顺序队列操作 64 ∷相关函数:push函数 pop函数 1.2.6 循环队列 66 范例1-29 循环队列 66 ∷相关函数:EnQueue函数 DeQueue函数 1.2.7 链队列的入队、出队 69 范例1-30 链队列入队、出队 69 ∷相关函数:push函数 pop函数 1.2.8 舞伴问题 71 范例1-31 舞伴问题 71 ∷相关函数:EnQueue函数 DeQueue函数 DancePartner函数 1.3 链表 75 1.3.1 头插法建立单链表 75 范例1-32 头插法建立单链表 75 ∷相关函数:createlist函数 1.3.2 限制链表长度建立单链表 77 范例1-33 限制链表长度建立长单链表 77 ∷相关函数:createlist函数 1.3.3 尾插法建立单链表 79 范例1-34 尾插法建立单链表 79 ∷相关函数:createlist函数 1.3.4 按序号查找单链表 80 范例1-35 按序号查找单链表 80 ∷相关函数:getnode函数 1.3.5 按值查找单链表 82 范例1-36 按值查找单链表 82 ∷相关函数:locatenode函数 1.3.6 链表的插入 84 范例1-37 链表的插入 84 ∷相关函数:insertnode函数 1.3.7 链表的删除 86 范例1-38 链表的删除 86 ∷相关函数:deletelist函数 1.3.8 归并两个单链表 88 范例1-39 归并两个单链表 88 ∷相关函数:concatenate函数 1.3.9 动态堆栈 90 范例1-40 动态堆栈 90 ∷相关函数:push函数 Pop函数 1.3.10 动态队列 93 范例1-41 动态队列 93 ∷相关函数:Enqueue函数 1.3.11 初始化单循环链表 95 范例1-42 初始化单循环链表 95 ∷相关函数:ListLength_CL函数 1.3.12 查询元素的前驱和后继 98 范例1-43 查询元素的前驱和后继 98 ∷相关函数:PriorElem_CL函数 NextElem_CL函数 1.3.13 单循环链表中元素的删除 101 范例1-44 单循环链表中元素的删除 101 ∷相关函数:ListDelete_CL函数 1.3.14 单循环链表的清除和销毁 107 范例1-45 单循环链表的清除和销毁 107 ∷相关函数:DestroyList函数 1.3.15 仅设表尾指针循环链表的合并 110 范例1-46 仅设表尾指针循环链表的合并 110 ∷相关函数:MergeList_CL函数 1.3.16 正序输出双向链表 113 范例1-47 正序输出双向链表 113 ∷相关函数:ListInsert函数 ListTraverse函数 1.3.17 逆向输出双向链表 116 范例1-48 三角矩阵建立 116 ∷相关函数:ListTraverseBack函数 1.3.18 删除双向链表中的节点 121 范例1-49 删除双向链表中的节点 121 ∷相关函数:ListDelete函数 1.3.19 双向链表的元素个数 124 范例1-50 双向链表的元素个数 124 ∷相关函数:ListLength函数 1.3.20 判断双向链表是否为空 126 范例1-51 判断双向链表是否为空 126 ∷相关函数:ListEmpty函数 1.3.21 双向链表元素值的查询 129 范例1-52 双向链表元素值的查询 129 ∷相关函数:GetElemP函数 1.3.22 稀疏矩阵的建立 136 范例1-53 稀疏矩阵的建立 136 ∷相关函数:Create函数 1.3.23 稀疏矩阵的删除 138 范例1-54 稀疏矩阵的删除 138 ∷相关函数:erase函数 1.4 树和二叉树 141 1.4.1 获得二叉树的深度和根(顺序结构) 141 范例1-55 获得二叉树的深度和根 141 ∷相关函数:BiTreeDepth函数 Root函数 1.4.2 获得二叉树的深度和根(链表结构) 144 范例1-56 获得二叉树的深度和根 144 ∷相关函数:BiTreeDepth函数 Root函数 1.4.3 树的插入(顺序结构) 147 范例1-57 树的插入 147 ∷相关函数:InsertChild函数 1.4.4 节点的修改(顺序结构) 150 范例1-58 节点的修改 150 ∷相关函数:Assign函数 1.4.5 节点的修改(链式结构) 154 范例1-59 节点的修改 154 ∷相关函数:Assign函数 1.4.6 双亲、孩子和兄弟节点的查询(顺序结构) 158 范例1-60 双亲、孩子和兄弟节点的查询 158 ∷相关函数:Parent函数 LeftChild函数 RightChild函数 LeftSibling函数 RightSibling函数 1.4.7 双亲、孩子和兄弟节点的查询(链式结构) 162 范例1-61 双亲、孩子和兄弟节点的查询 162 ∷相关函数:Parent函数 LeftChild函数 RightChild函数 LeftSibling函数 RightSibling函数 1.4.8 中序遍历二叉树(顺序结构) 169 范例1-62 中序遍历二叉树 169 ∷相关函数:InOrderTraverse函数 1.4.9 中序遍历二叉树(链式结构) 171 范例1-63 中序遍历二叉树 171 ∷相关函数:InOrderTraverse函数 1.4.10 中序非递归遍历二叉树(链式结构)(1) 174 范例1-64 中序非递归遍历二叉树 174 ∷相关函数:InOrderTraverse函数 1.4.11 中序非递归遍历二叉树(链式结构)(2) 177 范例1-65 中序非递归遍历二叉树 177 ∷相关函数:InOrderTraverse2函数 1.4.12 后序遍历二叉树(顺序结构) 180 范例1-66 后序遍历二叉树 180 ∷相关函数:PostOrderTraverse函数 1.4.13 后序遍历二叉树(链式结构) 183 范例1-67 后序遍历二叉树 183 ∷相关函数:PostOrderTraverse函数 1.4.14 层次遍历二叉树(顺序结构) 186 范例1-68 层次遍历二叉树 186 ∷相关函数:LevelOrderTraverse函数 1.4.15 层次遍历二叉树(链式结构) 188 范例1-68 层次遍历二叉树 188 ∷相关函数:LevelOrderTraverse函数 1.4.16 树的合并 191 范例1-70 树的合并 191 ∷相关函数:Find函数 Union函数 1.4.17 树的二叉链表存储的基本操作 193 范例1-71 树的二叉链表存储的基本操作 193 ∷相关函数:LevelOrderTraverse函数 1.4.18 二叉树的三叉链表存储的基本操作 201 范例1-72 二叉树的三叉链表存储表示 201 ∷相关函数:CreateBiTree函数 1.4.19 二叉树的二叉线索存储的基本操作 212 范例1-73 二叉树的二叉线索存储 212 ∷相关函数:CreateBiThrTree函数 1.4.20 树的双亲表存储的基本操作 215 范例1-74 树的双亲表存储的基本操作 215 ∷相关函数:CreateTree函数 1.4.21 哈夫曼编码(1) 223 范例1-75 哈夫曼编码(1) 223 ∷相关函数:HuffmanCoding函数 1.4.22 哈夫曼编码(2) 226 范例1-76 哈夫曼编码(2) 226 ∷相关函数:HuffmanCoding函数 1.5 排序 229 1.5.1 直接插入排序 229 范例1-77 直接插入排序 229 ∷相关函数:InsertSort函数 1.5.2 折半插入排序(顺序结构) 231 范例1-78 折半插入排序(顺序结构) 231 ∷相关函数:BInsertSort函数 1.5.3 2—路插入排序(顺序结构) 233 范例1-79 2—路插入排序(顺序结构) 233 ∷相关函数:P2_InsertSort函数 1.5.4 折半插入排序(链式结构) 235 范例1-80 折半插入排序(链式结构) 235 ∷相关函数:Arrange函数 1.5.5 2—路插入排序(链式结构) 238 范例1-81 2—路插入排序(链式结构) 238 ∷相关函数:Rearrange函数 1.5.6 希尔排序 241 范例1-82 希尔排序 241 ∷相关函数:ShellSort函数 1.5.7 冒泡排序 243 范例1-83 冒泡排序 243 ∷相关函数:bubble_sort函数 1.5.8 一趟快速排序 246 范例1-84 一趟快速排序 246 ∷相关函数:QSort函数 1.5.9 一趟快速排序的改进算法 248 范例1-85 一趟快速排序的改进算法 248 ∷相关函数:QuickSort函数 1.5.10 简单选择排序 250 范例1-86 简单选择排序 250 ∷相关函数:SelectSort函数 1.5.11 箱子排序 252 范例1-87 箱子排序 252 ∷相关函数:sort函数 1.5.12 树型选择排序 254 范例1-88 树型选择排序 254 ∷相关函数:TreeSort函数 1.5.13 堆排序 256 范例1-89 堆排序 256 ∷相关函数:HeapSort函数 1.5.14 归并排序 258 范例1-90 归并排序 258 ∷相关函数:MergeSort函数 1.5.15 多路平衡归并排序 260 范例1-91 多路平衡归并排序 260 ∷相关函数:K_Merge函数 1.5.16 置换—选择排序 265 范例1-92 置换—选择排序 265 ∷相关函数:Replace_Selection函数 1.5.17 文件的归并 269 范例1-93 文件的归并 269 ∷相关函数:K_Merge函数 1.6 查找 272 1.6.1 顺序表的查找 273 范例1-94 顺序表的查找 273 ∷相关函数:Search_Seq函数 1.6.2 静态树表的查找 276 范例1-95 静态树表的查找 276 ∷相关函数:Search_SOSTree函数 1.6.3 二叉排序树的基本操作 280 范例1-96 二叉排序树的基本操作 280 ∷相关函数:InsertBST函数 1.6.4 平衡二叉树的基本操作 285 范例1-97 平衡二叉树的基本操作 285 ∷相关函数:SearchBST函数 1.6.5 B树的基本操作 290 范例1-98 B树的基本操作 290 ∷相关函数:SearchBTree函数 1.6.6 按关键字符串的遍历双链键树 295 范例1-99 按关键字符串遍历双链键树 295 ∷相关函数:SearchDLTree函数 1.6.7 按关键字符串的遍历Trie树 301 范例1-100 按关键字符串遍历Trie树 301 ∷相关函数:SearchTrie函数 1.6.8 哈希表的基本操作 306 范例1-101 哈希表的基本操作 306 ∷相关函数:SearchHash函数 1.7 图 311 1.7.1 图的邻接矩阵存储表示 311 范例1-102 图的邻接矩阵存储表示 ∷相关函数:CreateFAG函数 CreateDG函数 1.7.2 图的邻接表存储表示 324 范例1-103 图的邻接表存储表示 324 ∷相关函数:CreateFAG函数 1.7.3 有向图的十字链表存储表示 335 范例1-104 有向图的十字链表存储表示 335 ∷相关函数:CreateDG函数 1.7.4 无向图的邻接多重表存储表示 344 范例1-105 无向图的邻接多重表存储表示 344 ∷相关函数:CreateGraph函数 1.7.5 最小生成树 355 范例1-106 最小生成树 355 ∷相关函数:MiniSpanTree_PRIM函数 1.7.6 关节点和重连通分量 359 范例1-107 关节点和重连通分量 359 ∷相关函数:FindArticul函数 1.7.7 拓扑排序 366 范例1-108 拓扑排序 366 ∷相关函数:TopologicalSort函数 1.7.8 关键路径 374 范例1-109 关键路径 374 ∷相关函数:CriticalPath函数 1.7.9 最短路径 383 范例1-110 最短路径 383 ∷相关函数:ShortestPath_DIJ函数 1.7.10 每一对顶点之间的最短路径 387 范例1-111 每一对顶点之间的最短路径 387 ∷相关函数:ShortestPath_FLOYD函数
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值