【数据结构】严蔚敏代码实现合集 可直接运行 原创

标题前面打*号的为多数考纲范围外的,可以选择性查看
🔗链接:严书代码实现
🔗链接:c/c++语言算法技巧汇总大复习1
🔗链接:c/c++语言算法技巧汇总大复习2

建议收藏关注,与严书代码高度一致且可实现运行。
有没更新的或者希望快点的可以催更哦。

版权声明:本文为CSDN博主「七灵微」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/qq_41775119/article/details/120929128

迷宫求解

//迷宫求解

#include "stdio.h"
#include <stdlib.h>
#include <iostream>
using namespace std;
typedef struct{
    int x;
    int y;
}postype;
typedef struct{
    int ord;//序号
    postype seat;
    int di;//方向
}block;
int map[6][6] = {//1为通路 0为墙
        {0,1,0,0,0,0},
        {0,1,1,1,0,0},
        {0,1,0,1,1,0},
        {1,1,0,0,1,0},
        {0,0,0,0,0,0},
        {0,0,0,0,0,0}
};
int mark[6][6]={0};//0未经过 1经过 2走不通
postype start={0,1};
postype endpoint={3,4};
block stack[36];
int top=-1;
postype curpos;//当前位置
int curstep;//第几步
void inistack(block stack[],int n){
    for(int i=0;i<n;i++){
        stack[i].ord=-1;
    }
}
void print_stack(block stack[])
{
    cout<<"print:"<<endl;
    int i=0;
    while(i<=top){
        printf("%d %d\n",stack[i].seat.x,stack[i].seat.y);
        i++;
    }
}
void pop(block stack[],block &e){
    if(top>-1)
    {
        e=stack[top];
        top--;
    }
}
void push(block stack[],block e){
    if(top<36){
        top++;
        stack[top]=e;
    }
}
int pass(postype curpos){
    if(map[curpos.x][curpos.y]==1&&mark[curpos.x][curpos.y]==0)
        return 1;
    return 0;
}
void footprint(postype curpos){
    cout<<"mark"<<curpos.x<<" "<<curpos.y<<endl;
    mark[curpos.x][curpos.y]=1;
}
int equal(postype a,postype b){
    if(a.x==b.x&&a.y==b.y)
        return 1;
    return 0;
}
postype nextpos(postype curpos,int di){
    postype newpos;
    newpos.x=curpos.x;
    newpos.y=curpos.y;
    switch (di) {
        case 1:
            if(curpos.x<6) {
                newpos.x ++;
                break;
            }
        case 2:
            if(curpos.y<6){
                newpos.y++;
                break;
            }
        case 3:
            if(curpos.x>0) {
                newpos.x --;
                break;
            }
        case 4:
            if(curpos.y>0){
                newpos.y--;
                break;
            }

    }
    return newpos;
}
void markprint(postype seat){
    mark[seat.x][seat.y]=2;
}
int mazepath(int map[6][6],postype start,postype end){//二维数组传参必须指定两个的维度
    block e;
    inistack(stack,36);
    curpos=start;
    curstep =1;
    do{
        if(pass(curpos)){
            footprint(curpos);
            e={curstep,curpos,1};
            push(stack,e);
            if(equal(curpos,end)) return 1;
            curpos=nextpos(curpos,1);
            curstep++;
        }
        else{
            if(top!=-1){
                pop(stack,e);
                while(e.di==4&&top!=-1){
                    markprint(e.seat);
                    pop(stack,e);
                }
                if(e.di<4){
                    e.di++;
                    push(stack,e);
                    curpos =nextpos(e.seat,e.di);
                }
            }
        }
    }while(top!=-1);
    return 0;
}
int main()
{
    mazepath(map,start,endpoint);
    print_stack(stack);
    return 0;
}

八皇后

在8×8格的国际象棋上摆放8个皇后,使其不能互相攻击,即任意两个皇后都不能处于同一行、同一列或同一斜线上,问有多少种摆法。

#include <algorithm>
#include <cstring>
#include <iostream>
#include <vector>
using namespace std;
int n = 8;
int a[100], vis[100], cnt = 0;//a[x]巧妙的将原本二维数组棋盘化简为用一维数组表示二维数组中对应行中皇后放的列值
void nQueen(int index) {//index行 i是index行上放的列 vis标记该列已放
    if (index == n) {
        cnt++;
        return;
    }
    bool flag;//表示可不可以放
    for (int i = 0; i < n; ++i) {
        if (!vis[i]) {
            flag = true;
            for (int pre = 0; pre < index; ++pre) {//pre是该行index之前的行,检查对角线的变量
                if (abs(index - pre) == abs(a[pre] - i)) {//行差值等于列差值是为同个对角线上,不可放皇后
                    flag = false;
                    break;
                }
            }
            if (flag) {
                a[index] = i;
                vis[i] = 1;
                nQueen(index + 1);
                vis[i] = 0;
            }
        }
    }
}

int main() {
    fill(a, a + 100, 0);#fill(first,last,val)属于头文件algorithm
    fill(vis, vis + 100, 0);
    nQueen(0);
    cout << cnt << endl;
    return 0;
}

还不太理解的同学需要生动形象的讲解可以看这个博主的图解https://blog.csdn.net/chunqiuwei/article/details/90113087

结构体的cmp排序函数

#include<iostream>  
#include<algorithm>  
using namespace std;  
struct E  
{  
    int a;  
    int b;  
}f[10];  
bool cmp(E q,E e)  
{  
    if(q.a!=e.a)  
    	return q.a<e.a;//<为升序,>为降序  
    else  
        return q.b<e.b;  
}  
int main()  
{  
    for(int i=0;i<5;i++)  
    {  
        cin>>f[i].a>>f[i].b;  
    }  
    sort(f,f+5,cmp);  

一元多项式及其操作的实现


#include <iostream>
#include <stdio.h>
using namespace std;
/*
C++从零开始之-文件类型
目前文件类型主要有.c、.h、.cpp、.hpp、.ipp等。
1、.c文件是为了兼容C而存在。
2、.h是用于声明的头文件。
3、.cpp是对各种声明进行定义的文件。
*/

typedef struct{
    int coef;      //系数 coefficient
    int expn;      //指数 exponent
}datatype;

typedef struct l_node{
    datatype data;
    struct l_node *next;
}l_node,*LinkList;

typedef LinkList polynomial;

void InitList(polynomial &p)
{
    p=(l_node*)malloc(sizeof(l_node));
    p->next=NULL;
}

l_node* GetHead(polynomial &p){
    if(p!=NULL)
        return p;
}

void SetCurElem(l_node* &h,int c,int e)
{
    h->data.coef=c;
    h->data.expn=e;
}
int compare(datatype e1,datatype e2){//<-1 =0 >1
    if(e1.expn==e2.expn){
        return 0;
    }else if(e1.expn<e2.expn)
        return -1;
    else return 1;

}
bool LocateElem(LinkList L,datatype e,l_node* &q,int(*compare)(datatype ,datatype))
{
    l_node *p=L->next;
    l_node *pre=L;
    int flag=0;
    q=pre;
    while(p!=NULL){
        if(compare(e,p->data)==0)
        {
            q=p;
            flag=1;
            break;
        }else if(compare(e,p->data)==-1)
        {
            q=pre;
            flag=0;
            break;
        }
        pre=p;
        q=pre;
        p=p->next;
    }
    return flag;
}
void InsFirst(l_node *q,datatype e){
    l_node* new_node=(l_node*)malloc(sizeof(l_node));
    new_node->data=e;
    new_node->next=q->next;
    q->next=new_node;
}

void CreatPolyn(polynomial &p,int m)
{
    InitList(p);
    l_node *h=GetHead(p);
    datatype e;
    e.coef=0;e.expn=-1;SetCurElem(h,e.coef,e.expn);
    l_node *q;
    for(int i=1;i<=m;++i){
        datatype e1;
        scanf("%d%d",&e1.coef,&e1.expn);
        if(!LocateElem(p,e1,q,(*compare))){
            InsFirst(q,e1);
        }
    }
}

void DestroyPolyn(polynomial &p)
{
    while(p!=NULL)
    {
        l_node *next_;
        next_=p->next;
        p->next=NULL;
        free(p);
        p=next_;
    }
}
void PrintPolyn(polynomial p)
{
    l_node *p_=p->next;
    while(p_!=NULL)
    {
        cout<<p_->data.coef<<"x^"<<p_->data.expn<<endl;
        p_=p_->next;
    }
}
int PolynLength(polynomial p)
{
    int c=0;
    l_node *l=p->next;
    while(l!=NULL){
        c++;
        l=l->next;
    }
    return c;
}
datatype GetCurElem(polynomial p){
    return p->data;
}
void DelFirst(polynomial &ha,polynomial qa){
    l_node *l=ha;
    while(l->next){
        if(l->next==qa) {
            l->next = l->next->next;
            break;
        }
        l=l->next;
    }
}
void FreeNode(polynomial qa){
    if(PolynLength(qa)==1)
    {qa->next=NULL;
    if(qa)
        free(qa);}
    else DestroyPolyn(qa);
}
int ListEmpty(polynomial p){
    l_node *l=p;
    if(p->next!=NULL)
        return 0;
    else return 1;
}
void Append(polynomial &pa,polynomial &pb){
    l_node *l=pa->next;
    while(l->next){
        l=l->next;
    }
    l->next=pb;
}
void AddPolyn(polynomial &pa,polynomial &pb){//pa=pa+pb and destroy pb
    l_node* ha= GetHead(pa);l_node* hb=GetHead(pb);//重新设一个指针指向原pa,pb以防用原指针处理使信息丢失
    //ha->next=null 可加可不加,因为后面处理步骤有ha=pa
    l_node* qa=ha->next;l_node* qb=hb->next;//表示当前处理的节点
    while(qa && qb){
        datatype a=GetCurElem(qa);datatype b= GetCurElem(qb);
        switch (compare(a,b)) {
            case -1:
            {ha=qa;qa=qa->next;break;}//不用处理什么 继续
            case 0:
            {
                int sum=a.coef+b.coef;
                if(sum !=0){
                    SetCurElem(qa,sum,a.expn);ha=pa;//其实ha=pa没用,但若ha头节点与之后断链,这里就是必须
                }else{
                    DelFirst(ha,qa);FreeNode(qa);//不断链的话跟从pa删掉qa是一样的
                }
                DelFirst(hb,qb);//跟从pb删掉qb是一样的,而且pb头节点没必要断链
                FreeNode(qb);
                qb=hb->next;qa=ha->next;break;
            }
            case 1:
            {
                DelFirst(hb,qb);
                InsFirst(ha,qb->data);
                qb=hb->next;ha=ha->next;break;
            }

        }

    }
    if(!ListEmpty(pb))Append(pa,qb);
    FreeNode(hb);
}
void SubstractPolyn(polynomial &pa,polynomial &pb){//pa=pa-pb and destroy pb
    //也就是把pb先把里面的data.coef都变成它的相反数再加
    l_node *l=pb;
    while(l->next){
        l->next->data.coef=(l->next->data.coef)*(-1);
        l=l->next;
    }
    AddPolyn(pa,pb);
}
void MultiplyPolyn(polynomial &pa,polynomial &pb){//pa=pa*pb and destroy pb

}
int main(){
    polynomial pa;
    CreatPolyn(pa,2);
    polynomial pb;
    CreatPolyn(pb,2);
    //AddPolyn(pa,pb);
    SubstractPolyn(pa,pb);
    cout<<PolynLength(pa)<<endl;
    PrintPolyn(pa);
    DestroyPolyn(pa);
}

行编辑程序

设立一个输入缓冲区,接受用户输入的一行字符,逐行存入用户数据区。允许用户发现输入错误时更正,输入退格符“#”表示前一个字符无效,输入退行符“@”表示当前行中字符均无效。
思路:设立栈结构作为输入缓冲区,如果是退格符,则栈顶元素出栈,如果是退行符则清空栈,都不是则入栈。


#include <iostream>
#include <stdio.h>
using namespace std;
typedef struct linknode{
    char data;
    struct linknode *next;
} *stack;
void InitStack(stack &s){
    s= (linknode*)malloc(sizeof (linknode));
    s->data='0';
    s->next=NULL;
}
void push(stack &s,char e)//头插法
{
    linknode *p=s->next;
    linknode *x= (linknode*)malloc(sizeof (linknode));
    x->data=e;
    x->next=p;
    s->next=x;
}
void pop(stack &s,char &e)
{
    if(s->next){
        linknode *p=s;
        linknode *pre=p->next;
        e=p->next->data;
        p->next=p->next->next;
        pre->next=NULL;
        free(pre);
    }

}
void clearStack(stack &s){
    if(s->next){
        linknode *p=s->next;
        linknode *p_next=p->next;
        s->next=NULL;
        while(p!=NULL){
            p->next=NULL;
            free(p);
            p=p_next;
            if(p==NULL)break;
            if(p->next)p_next=p->next;
            else p_next=NULL;
        }
    }

}
void DestroyStack(stack &s){
    if(s->next!=NULL)
    {
        clearStack(s);

    }
    free(s);

}
void printStack(stack &s){
    linknode *p=s->next;
    printf("%s\n","当前内容:");
    while(p){
        printf("%c",p->data);
        p=p->next;
    }
    cout<<endl;
}
void send_to_sum(stack &sum,stack &s){
    linknode *p=sum;
    if(s->next){
        linknode *x= (linknode*)malloc(sizeof (linknode));
        x->next=NULL;
        linknode *s_point=s;
        while(s_point->next){
            push(x,s_point->next->data);
            s_point=s_point->next;
        }

        while(p->next){
            p=p->next;
        }
        p->next=x->next;
    }

}
void LineEdit(){
    stack sum,s;
    char c;
    InitStack(sum);
    InitStack(s);
    char ch=getchar();
    while(ch!=EOF){
        while(ch!=EOF &&ch!='\n'){
            switch(ch){
                case '#':pop(s,c);break;
                case '@':clearStack(s);break;
                default:push(s,ch);break;
            }
            ch=getchar();
        }
        send_to_sum(sum,s);
        printStack(sum);
        clearStack(s);
        if(ch!=EOF)ch=getchar();
    }
    DestroyStack(s);
}
int main(){
    LineEdit();
    return 0;
}

汉诺塔

在这里插入图片描述
有一种被称为汉诺塔(Hanoi)的游戏。该游戏是在一块装置上,有三根杆(编号A、B、C),在A杆自下而上、由大到小按顺序放置n个圆盘(如图1)。游戏的目标:把A杆上的盘全部移到C杆上,并仍保持原有顺序叠好。操作规则:每次只能移动一个盘子,并且在移动过程中三根杆上都始终保持大盘在下,小盘在上,操作过程中盘子可以置于A、B、C任一杆上。

#include <iostream>
#include "stdio.h"
using namespace std;
int c=0;
void move(int x,int n,int z){
    printf("%i. move disk %i from %c to %c\n",++c,n,x,z);
}
void hanoi(int n,char x,char y,char z)//搬的个数, 源塔,辅助塔座,目的塔
//塔x上从小到大由上而下放编号1~n,搬到塔z
//塔座y作为辅助塔座
{
    if(n==1)
    {
        move(x,1,z);
    }else
    {
        hanoi(n-1,x,z,y);
        move(x,1,z);
        hanoi(n-1,y,x,z);
    }
}
int main() {
    hanoi(3,'x','y','z');
    return 0;
}

算符优先法求算术表达式

适用于简单计算,数字要求在0~10以内,可包含括号 + - * /计算,输完最后用#结尾
样例输入:(1+5)*6#

#include <iostream>
#include <stdio.h>
using namespace std;

typedef struct linknode{
    char data;
    struct linknode *next;
} *stack;

char OP[]={'+','-','*','/','(',')','#'};
char pre_matrix[6][6]={
     '>','>','<','<','<','>',
     '>','>','<','<','<','>',
     '>','>','>','>','<','>',
     '>','>','>','>','<','>',
     '<','<','<','<','<','=',
     '>','>','>','>',' ','>',
};
void InitStack(stack &s){
    s= (linknode*)malloc(sizeof (linknode));
    s->data='0';
    s->next=NULL;
}
void push(stack &s,int e)//头插法
{
    linknode *p=s->next;
    linknode *x= (linknode*)malloc(sizeof (linknode));
    x->data=e;
    x->next=p;
    s->next=x;
}
char GetTop(stack &s){
    return s->next->data;
}
void pop(stack &s,char &e)
{
    if(s->next){
        linknode *p=s;
        linknode *pre=p->next;
        e=p->next->data;
        p->next=p->next->next;
        pre->next=NULL;
        free(pre);
    }

}
int In(char c,char op[]){
    for(int i=0;i<=6;i++){
        if(op[i]==c)
            return 1;
    }
    return 0;
}
int Operate(char a,char theta,char b){
    int x1=a-'0';
    int x2=b-'0';
    if(theta=='+')
        return x1+x2;
    else if(theta=='-')
        return x1-x2;
    else if(theta=='*')
        return x1*x2;
    else if(theta=='/')
        return x1/x2;
}
int getint(char x){
    if(x=='+')
        return 0;
    else if(x=='-')
        return 1;
    else if(x=='*')
        return 2;
    else if(x=='/')
        return 3;
    else if(x=='(')
        return 4;
    else if(x==')')
        return 5;
    else if(x=='#')
        return 6;
}
char Precede(char a,char b){
    int x=getint(a);
    int y=getint(b);
    if(x==6 &&y==6)
        return '=';
    else if(x==6)
        return '<';
    else if(y==6)
        return '>';
    else return pre_matrix[x][y];
}
int evaluateExpression(){
    stack optr,opnd;
    InitStack(optr);
    InitStack(opnd);
    push(optr,'#');
    char x,theta,a,b;
    char c=getchar();
    while(c!='#' || GetTop(optr)!='#'){
        if(!In(c,OP))
        {
            push(opnd,c);c=getchar();
        }else
        {
            switch (Precede(GetTop(optr),c))
            {
                case '<':
                    push(optr,c);c=getchar();break;
                case '=':
                    pop(optr,x);c=getchar();break;
                case '>':
                    pop(optr,theta);pop(opnd,b);
                    pop(opnd,a);
                    push(opnd,Operate(a,theta,b)+'0');break;

            }
        }
    }
    return GetTop(opnd);
}

int main() {
    char x=evaluateExpression();
    printf("%d",x-'0');
    return 0;
}

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
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值