LOADING

加载过慢请开启缓存 浏览器默认开启

C语言数据结构练习

学习通的作业

学习通的作业已存放在网盘(点击进入)

最好还是不要让太多人知道了,好东西独自享受喵。

实验

实验1 顺序表的基本操作

一、实验内容与要求

https://acm.zjnu.edu.cn/problem/3070/view

二、算法思路与流程

三、程序代码及运行结果

#include <bits/stdc++.h>
using namespace std;
#define OK 1
#define ERROR 0
#define LIST_SIZE 100
#define LISTINCREMENT 10
#define OVERFLOW -2
typedef int ElemType;
typedef int Status;
typedef struct{
    ElemType *elem;
    int length;
    int listsize;
}Sqlist;

Status Initlist_sq(Sqlist &L){
    L.elem = (ElemType *)malloc(LIST_SIZE*sizeof(ElemType));
    if(!L.elem) return OVERFLOW;
    L.length = 0;
    L.listsize = LIST_SIZE;
    return OK;
} 

Status ClearList_sq(Sqlist &L){
    if(L.length==0) return ERROR;
    L.length = 0;
    return OK;
}

int LocateElem_sq(Sqlist L, ElemType e){
    int i =1;
    int *p = L.elem;
    while(i<=L.length && *p++!=e) ++i;
    if(i<=L.length) return i;
    else return 0;
}

ElemType LocateIndex_sq(Sqlist L, int i){
    if(i<1||i>L.length) return ERROR;
    return L.elem[i-1];
}

Status ListInsert_sq(Sqlist &L, int i, ElemType e){
    if(i<1|| i>L.length+1) return ERROR;
    if(L.length+1>L.listsize){
        ElemType *newlist = (ElemType *)realloc(L.elem,(L.listsize +1) * sizeof(ElemType));
        L.elem = newlist;
        L.listsize++;
    }
    ElemType *q = &(L.elem[i-1]);
    for(ElemType *p = &(L.elem[L.length-1]);p>=q;--p) *(p+1) = *p;
    *q = e;
    ++L.length;
    return OK;
}

Status ListDelete_sq(Sqlist &L, int i, ElemType &e){
    if(i<1||i> L.length) return ERROR;
    ElemType *p = &(L.elem[i-1]);
    e = *p;
    for(ElemType *q = p+1;q<=&(L.elem[L.length-1]);++q) *(p++) = *q;
    --L.length;
    return OK;
} 


int main(){
    Sqlist L;
    Initlist_sq(L);
    int n, m, index;
    ElemType e, a, b;
    cin >> n >> m;
    for (int i=1;i<=n;i++){
        cin >> e;
        ListInsert_sq(L, i, e);
    }
    string s;
    for (int i=1;i<=m;i++){
        cin >> s;
        if (s[0]=='I'){
            cin >> a >> b;
            ListInsert_sq(L, a, b);
        }
        else if (s[0]=='D'){
            cin >> index;
            ListDelete_sq(L, index, b);
            cout << b << endl;
        }
        else if (s[0]=='G'){
            cin >> index;
            cout << LocateIndex_sq(L, index) << endl;
        }
        else if (s[0]=='L'){
            cin >> b;
            index = LocateElem_sq(L, b);
            cout << index << endl;
        }
        else {
            ClearList_sq(L);
        }
    }
    return 0;
}

四、收获总结


实验2 链表及其多项式相加

一、实验内容与要求

https://acm.zjnu.edu.cn/problem/3049/view

二、算法思路与流程

三、程序代码及运行结果

/* 链表及其多项式相加 */
#include<stdio.h>
#include<stdlib.h>  

#define OVERFLOW -2
#define OK 1

typedef int status;
typedef struct Lnode {
    int exp, data;
    struct Lnode* next;
} Lnode, * Linklist;

//链表建立函数:建立一个长度为n的链表 
status listcreate_L(Linklist L, int n) {
    Lnode* p = L;
    for (int i = 0; i < n; i++) {
        int val = 0, exp = 0;
        Lnode* n = (Lnode*)malloc(sizeof(Lnode));
        scanf("%d %d", &val, &exp);
        n->data = val;
        n->exp = exp;
        n->next = NULL;
        p->next = n;
        p = p->next;
    }
    return 0;
}

//表达式相加函数:将La指向的表达式与Lb指向的表达式相加,赋给Lc 
Linklist listadd_L(Linklist l1, Linklist l2) {
    Linklist lc = (Linklist)malloc(sizeof(Lnode)); //创建头指针
    lc->next = NULL;

    Lnode *la = l1->next, * lb = l2->next, * ld, * le; //ld表示新链表中的节点,le表示创建的新节点
    ld = lc;

    while (la && lb) {
        if (la->exp < lb->exp) {
            ld->next = la; //la赋值给新节点
            la = la->next;
            ld = ld->next;
        }
        else if (la->exp > lb->exp) {
            ld->next = lb; //lb赋值给新节点
            lb = lb->next;
            ld = ld->next;
        }
        else {
            int sum = la->data + lb->data;
            if (!sum) { la = la->next; lb = lb->next; continue; } //如果相加为0,跳过
            
            le = (Linklist)malloc(sizeof(Lnode)); //相加不为0创建一个新节点,把值赋值给新节点,并指向新节点
            le->next = NULL;
            le->exp = la->exp;
            le->data = sum;
            ld->next = le;

            la = la->next;
            lb = lb->next;
            ld = ld->next;
        }
    }
    ld->next = la ? la : lb; //处理剩下的节点
    return lc;
}
//输出链表 
status listouput_L(Linklist L) {
    Lnode* p = L->next;
    int sum = 0, t = 1;
    while (p != NULL) {
        printf("%d %d\n", p->data, p->exp);
        p = p->next;
    }
    return OK;
}
int main() {
        Lnode* A = (Lnode*)malloc(sizeof(Lnode));
        A->next = NULL;
        int n = 0;
        scanf("%d", &n);
        listcreate_L(A, n);

        Lnode* B = (Lnode*)malloc(sizeof(Lnode));
        B->next = NULL;
        int m = 0;
        scanf("%d", &m);
        listcreate_L(B, m);

        Lnode* C = listadd_L(A, B);
        listouput_L(C);
        return 0;
    return 0;
}

四、收获总结


实验3 实践栈结构-括号匹配算法

一、实验内容与要求

https://acm.zjnu.edu.cn/problem/3050/view

二、算法思路与流程

#include <bits/stdc++.h>
using namespace std;

#define OVERFLOW -2
#define UNDERFLOW -1
#define OK 1

typedef char DataType;
typedef struct snode{
    DataType data;
    struct snode *next;
}StackNode; 

typedef struct {
    StackNode *top;
}LinkStack;

void InitStack(LinkStack &S){
    S.top = NULL;
}

bool StackEmpty(LinkStack &S){
    return S.top == NULL;
}

void Push(LinkStack &S, DataType x){
    StackNode * a=(StackNode*)malloc(sizeof(StackNode));
    if(a==NULL) exit(OVERFLOW);
    a->data=x;
    a->next=S.top;
    S.top = a;
}

DataType Pop(LinkStack &S){
    if(S.top==NULL) return UNDERFLOW;
    DataType p;
    snode * q = S.top;
    p = S.top->data;
    q = S.top;
    S.top = S.top->next;
    free(q);
    return p;
}

DataType GetTop(LinkStack &S){
    if(S.top == NULL) return UNDERFLOW;
    return S.top->data;
}

int Length(string s){
    return s.length();
}

bool match(char a, char b){
    if((a=='('&&b==')')||(a=='['&&b==']')){
        return 1;
    }
    else return 0;
}

bool matching(string exp){
    LinkStack S;
    InitStack(S);
    int state=1,i=0;
    while(i<Length(exp) && state){
        switch (exp[i])
        {
        case '(':
        case '[':
            Push(S,exp[i]);
            i++;
            break;
        case ']':
        case ')':
            if(!StackEmpty(S) && match(GetTop(S), exp[i])) {
                Pop(S);
                i++;
            }
            else state =0;
            break;
        }
    }
    if(state==1 && StackEmpty(S))return OK;
    else return 0;
}

int main(){
    string exp;
    cin >> exp;
    if (matching(exp)) printf("yes\n");
    else printf("no\n");
    return 0;
}

三、程序代码及运行结果

四、收获总结


实验4 实践栈结构-编译器中的表达式求值问题

一、实验内容与要求

https://acm.zjnu.edu.cn/problem/3052/view

二、算法思路与流程

#include <cstdio>
#include <iostream>
#include <cstring>

#define OVERFLOW -2
#define UNDERFLOW -1
#define OK 1

using namespace std;

typedef char Dataoptr;
typedef int Dataopnd;

typedef struct stdacknode_optr{
    Dataoptr data;
    struct stdacknode_optr*next;
} Stacknode_optr;

typedef struct {
    Stacknode_optr *top;
    Stacknode_optr *base;
} Stack_optr;

typedef struct stdacknode_opnd{
    Dataopnd data;
    struct stdacknode_opnd*next;
} Stacknode_opnd;

typedef struct {
    Stacknode_opnd *top;
    Stacknode_opnd *base;
} Stack_opnd;


void InitStack_optr(Stack_optr &S) {
    S.top == NULL;
}

void Push_optr(Stack_optr &S, Dataoptr x) {
    Stacknode_optr *p = (Stacknode_optr *)malloc(sizeof(Stacknode_optr));
    p->data = x;
    p->next = S.top;
    S.top = p;
}

Dataoptr Pop_optr(Stack_optr &S) {
    if (S.top == NULL) {
        return UNDERFLOW;
    }
    Dataoptr x;
    Stacknode_optr *p = S.top;
    x = p->data;
    S.top = p->next;
    free(p);
    return x;
}

Dataoptr GetTopnode_optr(Stack_optr &S){
    return S.top->data;
}

Dataopnd GetTopnode_opnd(Stack_opnd &S){
    return S.top->data;
}

void InitStack_opnd(Stack_opnd &S) {
    S.top == NULL;
}

void Push_opnd(Stack_opnd &S, Dataopnd x) {
    Stacknode_opnd *p = (Stacknode_opnd *)malloc(sizeof(Stacknode_opnd));
    p->data = x;
    p->next = S.top;
    S.top = p;
}

Dataopnd Pop_opnd(Stack_opnd &S) {
    if (S.top == NULL) {
        return UNDERFLOW;
    }
    Dataopnd x;
    Stacknode_opnd *p = S.top;
    x = p->data;
    S.top = p->next;
    free(p);
    return x;
}

bool in (char c) {
    return c<='9'&&c>='0';
}
Dataopnd Operate(Dataopnd a,Dataoptr op, Dataopnd b) {
    switch (op) {
        case '+':return a+b;
        case '-':return a-b;
        case '*':return a*b;
        case '/':return a/b;
    }
    return 0;
}

char Precede(char x1, char x2)
{
    if((x1=='('&&x2==')')|| x1=='#'&&x2=='#') return '=';
    else if((x1=='('||x1=='#'||x2=='(')||(x1=='+'||x1=='-')&&(x2=='*'||x2=='/')) return '<';
    else return '>';
}

int EvaluateExpression(char *s)
 
{
    Stack_optr OPTR;
    Stack_opnd OPND; 
    int idx = 0;
    int a, b;
    char op;
 
    InitStack_optr(OPTR);
    InitStack_opnd(OPND);
 
    Push_optr(OPTR, '#');
 
    while (s[idx] != '#' || GetTopnode_optr(OPTR) != '#')
    {
        if (in(s[idx]))
        {
            Push_opnd(OPND, s[idx] - '0');
            printf("%d ", s[idx] - '0');
            idx++;
        }
        else
        {
            switch (Precede(GetTopnode_optr(OPTR), s[idx]))
            {
            case '>':
                op = Pop_optr(OPTR);
                b = Pop_opnd(OPND);
                a = Pop_opnd(OPND);
                printf("%c ", op);
                Push_opnd(OPND, Operate(a, op ,b));
                break;
            case '=':
                Pop_optr(OPTR);
                idx++;
                break;
            case '<':
                Push_optr(OPTR, s[idx++]);
            }
        }
    }
    return GetTopnode_opnd(OPND);
}

int main() {
    char str[2000] = {0};
 
    scanf("%s", str);
    int num;
    str[strlen(str)] = '#';
    num = EvaluateExpression(str);
    printf("\n%d\n", num);
    return 0;
}

三、程序代码及运行结果

四、收获总结


实验5 字符串的模式匹配(KMP)

一、实验内容与要求

https://acm.zjnu.edu.cn/problem/3053/view

二、算法思路与流程

#include <stdio.h>
#include <string.h>

char s[100005];
char t[100005];
int next[100005];
void get_next(char *t)
{
    int i = 0, j = -1;
    next[0] = -1;
    int tlen = strlen(t);
    while (i < tlen)
    {
        if (j == -1 || t[i] == t[j]){
            ++i;
            ++j;
            next[i] = j;
        }
        else j = next[j];
    }
}
int kmp(char *s, char *t)
{
    int i = 0, j = 0;
    int slen = strlen(s);
    int tlen = strlen(t);
    while (i < slen && j < tlen)
    {
        if (j == -1 || s[i] == t[j])
        {
            ++i;
            ++j;
        }
        else j = next[j];
    }
    if (j >= tlen) return 1;
    else return 0;
}

int main(){

    gets(s);
    int count=0;
    scanf("%d",&count);
    getchar(); //读取后面的换行符防止下次对gets读取造成干扰
    for(int i =0;i<count;i++){
        gets(t);
        get_next(t);
        int flag = kmp(s,t);
        if(flag==1) printf("yes\n");
        else printf("no\n");
    }
    return 0;
}

三、程序代码及运行结果

四、收获总结


实验6 稀疏矩阵的建立与转置

一、实验内容与要求

https://acm.zjnu.edu.cn/problem/3054/view

二、算法思路与流程

#include <cstdio>
using namespace std;

#define MAXSIZE 12500
#define OK 1

typedef int ElemType;
typedef int Status;

typedef struct {
    int i,j;
    ElemType e;
} Triple;

typedef struct {
    Triple data[MAXSIZE+1];
    int mu,nu,tu;
} TSMatrix;

Status TransposeSMatrix(TSMatrix M, TSMatrix &T){
    int p, q, col;
    T.mu = M.nu; T.nu = M.mu; T.tu = M.tu;
    if(T.tu){
        q = 1;
        for (col = 0;col<=M.nu;col++){ // 这里col从0开始
            for (p = 1;p<=M.tu;p++){
                if(M.data[p].j == col){
                    T.data[q].i = M.data[p].j;
                    T.data[q].j = M.data[p].i;
                    T.data[q].e = M.data[p].e;
                    q++;
                }
            }
        }
    }
    return OK;
}

void printMatrix(TSMatrix M){
    int count = 1;
    for (int i =0;i<M.mu;i++){
        for (int j=0;j<M.nu;j++){
            if(M.data[count].i ==i&&M.data[count].j==j){
                printf("%5d", M.data[count].e);
                count++;
            }
            else{
                printf("%5d", 0);
            }
        }
        printf("\n");
    }
}

int main(){
    TSMatrix A;
    TSMatrix B;

    scanf("%d %d %d", &A.mu, &A.nu, &A.tu);
    for (int i =1;i<=A.tu;i++){
        scanf("%d %d %d", &A.data[i].i, &A.data[i].j, &A.data[i].e);
    }

    TransposeSMatrix(A, B);

    printMatrix(A);
    printf("\n");
    printMatrix(B);
    return 0;
} 

三、程序代码及运行结果

四、收获总结


实验7 二叉树的创建及遍历

一、实验内容与要求

https://acm.zjnu.edu.cn/problem/3055/view

二、算法思路与流程

#include <cstdlib>
#include <cstdio>
using namespace std;

#define ERROR 0
#define OK 1
#define OVERFLOW -2
#define MAX 100000000
typedef int status;
typedef struct Binode {
    char data;
    int deep;
    Binode* lchild;
    Binode* rchild;
}Binode, * BiTree;

status depthbitree(BiTree& T);

status prebitree(BiTree T) {
    if (T) {
        depthbitree(T);
        printf("%c(%d)", T->data, T->deep);
        prebitree(T->lchild);
        prebitree(T->rchild);
    }
    return OK;
}

status depthbitree(BiTree& T) {
    if(T)
     {
        if (T->lchild != NULL) T->lchild->deep = T->deep +1;
        if (T->rchild != NULL) T->rchild->deep = T->deep +1;
        depthbitree(T->lchild);
        depthbitree(T->rchild);
    }
    return OK;
}

status creabitree(BiTree& T) {
    char get;
    scanf("%c", &get);
    if (get == '#' || get == '\n') T = NULL;
    else {
        if (!(T = (Binode*)malloc(sizeof(Binode)))) exit(OVERFLOW);
        T->data = get;
        T->deep = 1;
        creabitree(T->lchild);
        creabitree(T->rchild);
    }
    return OK;
}

int main() {

    BiTree T;
    creabitree(T);

    depthbitree(T);

    prebitree(T);
    return 0;
}

三、程序代码及运行结果

四、收获总结


实验8 树的建立与遍历

一、实验内容与要求

https://acm.zjnu.edu.cn/problem/3093/view

二、算法思路与流程

#include<stdio.h>
#include <stdlib.h>
#include<string>

#define ERROR 0
#define OK 1
#define OVERFLOW -2

typedef int Elem;

typedef struct CSNode {
    Elem data;
    struct CSNode* firstchild, * nextsibling;
} CSNode, * CSTree;

typedef CSNode Qelemtype;
typedef int status;

typedef struct QNode {
    Qelemtype* Qdata;
    struct QNode* next;
}Qnode, * QueuePtr;

typedef struct {
    QueuePtr front;
    QueuePtr rear;
} LinkQueue;

status InitQueue(LinkQueue& Q) {
    Q.front = Q.rear = (QueuePtr)malloc(sizeof(Qnode));
    if (!Q.front) exit(EOVERFLOW);
    Q.front->next = NULL;
    return OK;
}

status EnQueue(LinkQueue& Q, Qelemtype *e)
{
    QueuePtr p = (QueuePtr)malloc(sizeof(QNode));
    if (!p) exit(EOVERFLOW);
    p->Qdata = e; p->next = NULL;
    Q.rear->next = p;
    Q.rear = p;
    return OK;
}

Qelemtype* DeQueue(LinkQueue& Q) {
    Qelemtype* e;
    if (Q.front == Q.rear) return(ERROR);
    QueuePtr p = Q.front->next;
    e = p->Qdata;
    Q.front->next = p->next;
    if (Q.rear == p) Q.rear = Q.front;
    free(p);
    return e;
}

Qelemtype* GetHead(LinkQueue& Q) {
    Qelemtype* e;
    if (Q.front == Q.rear) return ERROR;
    e = Q.front->next->Qdata;
    return e;
}

CSTree GetTreeNode(char ch){
    CSTree p = (CSTree)malloc(sizeof(CSNode));
    p->data = ch;
    p->firstchild = NULL;
    p->nextsibling = NULL;
    return p;
}

void CreatTree(CSTree& T){
    T = NULL;
    CSTree r =NULL;
    char ch = NULL, fa = NULL;
    int i = 0;
    LinkQueue Q;

    InitQueue(Q);

    scanf("%d", &i); getchar();
    for (int j =0; j<i; j++)
    {
        CSTree s = NULL, p;

        scanf("%c %c", & fa, &ch); getchar();

        p = GetTreeNode(ch); 
        EnQueue(Q, p); 
        if (fa == '#')  T = p;
        else {
            s = GetHead(Q); 
            while (s->data != fa) {  
                s = DeQueue(Q);  s =GetHead(Q);
            }
            if (!(s->firstchild)){
                s->firstchild = p; r = p;
            }
            else { r->nextsibling = p; r = p; }
        } 
    }
} 

int TreeDepth(CSTree T) {
    int h1, h2;
    if (!T) return 0;
    else {
        h1 = TreeDepth(T->firstchild);
        h2 = TreeDepth(T->nextsibling);
        return(h1 + 1 > h2 ? h1 + 1 : h2);
    }
}

void getin(CSNode* p,int &count){
    if (p){
        if (!p->firstchild) count++;
        getin(p->firstchild,count);
        getin(p->nextsibling,count);
    }
}

status pretraverse(CSTree T) {
    if (T) {
        printf("%c ", T->data);
        pretraverse(T->firstchild);
        pretraverse(T->nextsibling);
    }
    return OK;
}
status intraverse(CSTree T) {
    if (T) {
        intraverse(T->firstchild);
        printf("%c ", T->data);
        intraverse(T->nextsibling);
    }
    return OK;
}

int main() {
    CSTree T;
    CreatTree(T);

    printf("PreOrder: ");
    pretraverse(T);
    printf("\n");

    printf("PostOrder: ");
    intraverse(T);
    printf("\n");

    printf("Depth: %d\n", TreeDepth(T));

    int count = 0;
    getin(T, count);
    printf("Number of leaves: %d\n", count);

    return 0;
}

三、程序代码及运行结果

四、收获总结


实验9 图的建立与遍历(多城市间遍历)

一、实验内容与要求

https://acm.zjnu.edu.cn/problem/1416/view

二、算法思路与流程

三、程序代码及运行结果

#include <stdio.h>
#include <stdlib.h>

#define ERROR 0
#define OK 1
#define OVERFLOW -2
#define MAX_VERTEX_N 80	
typedef int VRType;
typedef int InfoType;
typedef int VerterType;

typedef struct ArcCell {
    VRType adj;
}ArcCell, AdjMatrix[MAX_VERTEX_N][MAX_VERTEX_N];

typedef struct Qnode {
    VerterType data;
    struct Qnode* next;
};

typedef struct Queue{
    Qnode* front;
    Qnode* rear;
} Queue;

typedef struct {
    VerterType vexs[MAX_VERTEX_N];
    AdjMatrix arcx;
    int vexnum, arcnum;
}MGraph;

bool visited[MAX_VERTEX_N] = {false};

int InitQueue(Queue& Q) {
    Q.front = Q.rear = (Qnode*)malloc(sizeof(Qnode));
    if (!Q.front) exit(OVERFLOW);
    Q.front->next = NULL;
    return OK;
}
int InQueue(Queue& Q, VerterType a) {
    Qnode* p = (Qnode*)malloc(sizeof(Qnode));
    if (!p) exit(OVERFLOW);
    p->data = a;
    p->next = NULL;
    Q.rear->next = p;
    Q.rear = p;
    return OK;
}

bool QueueEmpty(Queue& Q) {
    return Q.front == Q.rear;
}

int DeQueue(Queue& Q, VerterType& a) {
    if (Q.front == Q.rear) return ERROR;
    Qnode* p = Q.front->next;
    a = p->data;
    Q.front->next = p->next;
    if (Q.rear == p) Q.rear = Q.front;
    free(p);
    return OK;
}

int InitGraph(MGraph &M) {
    scanf("%d %d", &M.vexnum, &M.arcnum); getchar();
    if (M.vexnum) {
        for (int i = 0; i < M.vexnum; i++) {
            M.vexs[i] = i;
        }
    }
    
    for(int i =0;i<MAX_VERTEX_N;i++){
        for(int j =0;j<MAX_VERTEX_N;j++){
            M.arcx[i][j].adj = 0;
        } 
    }
    
    if (M.arcnum) {
        for (int i = 0; i < M.arcnum; i++) {
            int a, b;
            scanf("%d %d", &a, &b); getchar();
            M.arcx[a][b].adj = 1;
            M.arcx[b][a].adj = 1;
        }
    }
    return OK;
}


void DFS(MGraph M, int v) {
    visited[v] = true;
    printf("%d ", M.vexs[v]);
    for (int i = 0; i < M.vexnum; i++) {
        if (M.arcx[v][i].adj == 1 && !visited[i]) {
            DFS(M, i);
        }
    }
}

void DFSTraverse(MGraph M){
    for(int i =0;i<MAX_VERTEX_N;i++) visited[i] = false;
     for (int i = 0; i < M.vexnum; i++) {
        if (!visited[i]) {
            DFS(M, i);
        }
    }
}

void BFS(MGraph M, Queue& Q) {

    for (int i = 0; i < M.vexnum; i++) {
        if (!visited[i]) {
            visited[i] = true;
            printf("%d ", M.vexs[i]);
            InQueue(Q, i);
            while (!QueueEmpty(Q)) {
                VerterType u;
                DeQueue(Q, u);
                for (int j = 0; j < M.vexnum; j++) {
                    if (M.arcx[u][j].adj && !visited[j]) {
                        visited[j] = true;
                        printf("%d ", M.vexs[j]);
                        InQueue(Q, j);
                    }
                }
            }
        }
    }
}

void BFSTraverse(MGraph M){
    Queue Q;
    InitQueue(Q);
    for(int i =0;i<MAX_VERTEX_N;i++) visited[i] = false;
    BFS(M,Q);
}
int main() {
    MGraph M;
    
    InitGraph(M);
    
    DFSTraverse(M);

    printf("\n");
    BFSTraverse(M);

    return 0;
}

四、收获总结


实验10 最小生成树prim算法

一、实验内容与要求

https://acm.zjnu.edu.cn/problem/1408/view

二、算法思路与流程

三、程序代码及运行结果

#include <stdio.h>
using namespace std;
#define MAX_VERTEX_N 105
#define INF 1000000007
typedef int VRType;
typedef int VertexType;
typedef int status;

typedef struct ArcCell {
    VRType adj;
} ArcCell, AdjMatrix[MAX_VERTEX_N][MAX_VERTEX_N];

typedef struct MGraph {
    VertexType vexs[MAX_VERTEX_N];
    AdjMatrix arcs;
    int vexnum, arcnum;
} MGraph;

struct Closedge {
    VertexType  adjvex;
    VRType     lowcost;
} closedge[MAX_VERTEX_N];

void CreatGraph(MGraph& G) {
    scanf("%d", &G.vexnum);
    for (int i = 0; i < G.vexnum; i++) {
        for (int j = 0; j < G.vexnum; j++) {
            scanf("%d", &G.arcs[i][j].adj);
        }
    }
}

int minimum(Closedge closedge[], MGraph G) {
    int u = 0, min = INF;
    for (int i = 0; i < G.vexnum; i++) {
        if (closedge[i].lowcost != -1 && min > closedge[i].lowcost) {

            min = closedge[i].lowcost;
            u = i;
        }
    }
    return u;
}

int Prim(MGraph G) {
    int u = 0, res = 0;
    for (int i = 0; i < G.vexnum; i++) closedge[i].lowcost = G.arcs[u][i].adj;
    closedge[u].lowcost = -1;

    for (int i = 1; i < G.vexnum; i++) {
        u = minimum(closedge, G);
        res += closedge[u].lowcost;
        closedge[u].lowcost = -1;
        for (int j = 0; j < G.vexnum; j++) {
            if (closedge[j].lowcost > G.arcs[u][j].adj)
                closedge[j].lowcost = G.arcs[u][j].adj;
        }
    }
    return res;
}

int main() {
    MGraph G;
    CreatGraph(G);
    printf("%d\n", Prim(G));
    return 0;
}

四、收获总结


实验11 城市畅通工程的问题

一、实验内容与要求

https://acm.zjnu.edu.cn/problem/1414/view

二、算法思路与流程

三、程序代码及运行结果

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

struct edge
{
    int u, v, w;
} edge[4005];

int father[4005];

int Find(int l)
{
    if (father[l] != l){
        return father[l] = Find(father[l]);
    }
    return l;
}

void Union(int p, int q)
{
    father[q] = p;
}

void swap(int &a, int &b)
{
    int t = a;
    a = b;
    b = t;
}
void Sort(struct edge edge[], int m)
{
    for (int i = m - 1; i > 0; i--){
        for (int j = 0; j < i; j++){
            if (edge[j].w > edge[j + 1].w){
                swap(edge[j].u, edge[j + 1].u);
                swap(edge[j].v, edge[j + 1].v);
                swap(edge[j].w, edge[j + 1].w);
            }
        }
    }
}

void Initialize(int n){
    for (int i = 1; i <= n; i++){
        father[i] = i;
    }
}

int main()
{
    int n, m;
    scanf("%d%d", &n, &m);
    for (int i = 0; i < m; i++){
        scanf("%d%d%d", &edge[i].u, &edge[i].v, &edge[i].w);
    }

    Initialize(n);
    Sort(edge, m);

    int sum = 0, j = 0, k = 0;
    while (k < n - 1){
        int p = Find(edge[j].u);
        int q = Find(edge[j].v);
        if (p != q){
            Union(p, q);
            sum += edge[j].w;
            k++;
        }
        j++;
    }
    printf("%d\n", sum);
    return 0;
}

四、收获总结


实验12 单源最短路径

一、实验内容与要求

https://acm.zjnu.edu.cn/problem/3933/view

二、算法思路与流程

三、程序代码及运行结果

#include <iostream>
using namespace std;
#define MAX_VERTEX_N 3005
#define MAX_EDGE_M 10005
#define INF 1000000007
typedef int VRType;
typedef int VertexType;
typedef int status;
int s, t;
int dist[MAX_VERTEX_N];
bool visited[MAX_VERTEX_N];
typedef struct ArcCell {
    VRType adj;
} ArcCell, AdjMatrix[MAX_VERTEX_N][MAX_VERTEX_N];

typedef struct MGraph {
    VertexType vexs[MAX_VERTEX_N];
    AdjMatrix arcs;
    int vexnum, arcnum;
} MGraph;
MGraph G;

void CreatGraph() {
    int u, v, x;
    cin >> G.vexnum >> G.arcnum >> s >> t;
    for (int i = 0; i < G.vexnum; i++) {
        G.vexs[i] = i;
    }
    for (int i = 0; i <= G.vexnum; i++) {
        for (int j = 0; j <= G.vexnum; j++) {
            G.arcs[i][j].adj = INF;
        }
    }
    for (int i = 0; i < G.arcnum; i++) {
        cin >> u >> v >> x;
        if (G.arcs[u][v].adj > x) {
            G.arcs[v][u].adj = G.arcs[u][v].adj = x;
        }
    }
}

void Dijkstra() {
    for (int i = 1; i <= G.vexnum; i++) {
        dist[i] = G.arcs[s][i].adj;
        visited[i] = false;
    }
    for (int i = 0; i <= G.vexnum; i++) {
        int min = INF, u=0, j;
        for (j = 1; j <= G.vexnum; j++) {
            if (!visited[j] && dist[j] < min) {
                min = dist[j];
                u = j;
            }
        }
        visited[u] = true;
        for (int j = 1; j <= G.vexnum; j++) {
            if (!visited[j] && dist[u] + G.arcs[u][j].adj < dist[j]) {
                dist[j] = dist[u] + G.arcs[u][j].adj;
            }
        }
    }
    cout << dist[t] << endl;
}

int main() {
    CreatGraph();
    Dijkstra();
    return 0;
}

四、收获总结


实验13 拓扑排序

一、实验内容与要求

https://acm.zjnu.edu.cn/problem/1413/view

二、算法思路与流程

三、程序代码及运行结果

#include <stdio.h>
#include <string.h>

#define maxex 200

// 定义图的结构体
typedef struct {
    int vexnum, arcnum;
    int arcs[maxex][maxex];
} MGraph;

MGraph g;
int in[maxex], visit[maxex];

// 统计入度
void countIndegree() {
    memset(in, 0, sizeof(in));
    for (int i = 1; i <= g.vexnum; i++) {
        for (int j = 1; j <= g.vexnum; j++) {
            if (g.arcs[j][i])
                in[i]++;
        }
    }
}

// 拓扑排序
bool topoSort() {
    int base = 0, top = 0;
    int stack[maxex];

    countIndegree();

    // 入度为 0 的顶点入栈(倒序)
    for (int i = g.vexnum; i >= 1; i--) {
        if (!in[i])
            stack[top++] = i;
    }

    int count = 0;

    while (top != base) {
        int v = stack[--top];
        visit[count++] = v;

        for (int u = 1; u <= g.vexnum; u++) {
            if (g.arcs[v][u]) {
                in[u]--;
                if (!in[u])
                    stack[top++] = u;
            }
        }

        // 对栈中元素进行降序排序(每次调整)
        for (int i = 0; i < top; i++) {
            int k = i;
            for (int j = i + 1; j < top; j++) {
                if (stack[k] < stack[j])
                    k = j;
            }
            if (k != i) {
                int t = stack[i];
                stack[i] = stack[k];
                stack[k] = t;
            }
        }
    }

    // 检查是否存在环
    if (count == g.vexnum) {
        printf("%d", visit[0]);
        for (int i = 1; i < g.vexnum; i++)
            printf(" %d", visit[i]);
    }
    else {
        printf("no");
    }

    return true;
}

int main() {
    // 读入顶点数和边数
    scanf("%d%d", &g.vexnum, &g.arcnum);

    // 初始化邻接矩阵
    for (int i = 1; i <= g.vexnum; i++) {
        for (int j = 1; j <= g.vexnum; j++) {
            g.arcs[i][j] = 0;
        }
    }

    // 读入边的信息,并构建邻接矩阵
    for (int i = 1; i <= g.arcnum; i++) {
        int u, v;
        scanf("%d%d", &u, &v);
        g.arcs[u][v] = 1;
    }

    // 进行拓扑排序
    topoSort();
    return 0;
}

四、收获总结


实验14 二叉搜索树的构建与应用

一、实验内容与要求

https://acm.zjnu.edu.cn/problem/3065/view

二、算法思路与流程

三、程序代码及运行结果

#include <bits/stdc++.h>
using namespace std;
#define MAXN 100005
#define TRUE 1
#define FALSE 0

typedef struct BiTNode{
    int data;
    struct BiTNode *lchild, *rchild;
}BiTNode, *BiTree;

int SearchBST(BiTree T, int e, BiTree f, BiTree &p){
    if(T){
        if(e==T->data) {
            p = T;
            return TRUE;
        }
        else if(e>T->data) return SearchBST(T->rchild,e,T,p);
        else return SearchBST(T->lchild,e,T,p);
    }
    else{
        p=f;
        return FALSE;
    }
}
 
int InsertBST(BiTree &T, int e){
    BiTree f=NULL,p=NULL;
    if(!SearchBST(T,e,f,p)){
        BiTree s = new BiTNode;
        s->data = e;
        s->lchild = s->rchild =NULL;
        if(!p){
            T=s;
        }
        else{
            if(e > p->data) p->rchild = s;
            else p->lchild =s;
        }
        return TRUE;
    }
    return FALSE;
}

int CreateBST(BiTree &T){
    int n, x, cnt=0;
    scanf("%d", &n);
    for (int i=0;i<n;i++){
        scanf("%d", &x);
        if (InsertBST(T, x)) cnt++;
    }
    return cnt;
}

void PreOrder(BiTree T){
    if(T){
        cout << T->data << " ";
        PreOrder(T->lchild);
        PreOrder(T->rchild);
    }
}

int main(){
    BiTree T = NULL;
    cout << CreateBST(T) <<endl;
    PreOrder(T);
}

四、收获总结


实验15 对大量数据快速排序

一、实验内容与要求

https://acm.zjnu.edu.cn/problem/1479/view

二、算法思路与流程

三、程序代码及运行结果

四、收获总结


实验16 堆的建立和维护

一、实验内容与要求

https://acm.zjnu.edu.cn/problem/3067/view

二、算法思路与流程

三、程序代码及运行结果

四、收获总结

作业

两个有序链表的合并

#include<stdio.h>
#include<stdlib.h>

typedef int ElemType;
typedef struct Lnode
{
    ElemType data;
    struct Lnode* next;
} Lnode, * linkLnode;

int h_insert_Lnode(Lnode* H, ElemType m) {
    Lnode* p = H;
    for (int i = 0; i < m; i++) {
        ElemType val = 0;
        Lnode* n = (Lnode*)malloc(sizeof(Lnode));
        scanf("%d", &val);
        n->data = val;
        n->next = NULL;
        p->next = n;
        p = p->next;
    }
    return 0;
}

void print_Lnode(Lnode* h) {
    Lnode* p = h->next;
    int sum = 0, t = 1;
    while (p != NULL) {
        printf("%d ", p->data);
        if (t % 2 == 1)sum += p->data;
        t++;
        p = p->next;
    }
    printf("\n");
    printf("%d\n", sum);
}


struct Lnode* mergeTwoLists(struct Lnode* l1, struct Lnode* l2) {
    Lnode* la = l1->next, * lb = l2->next, * lc, * ld;
    lc = (Lnode*)malloc(sizeof(Lnode));
    ld = lc;

    while (la&& lb) {
        if (la->data <= lb->data) {
            lc->next = la;
            la = la->next;
        }
        else {
            lc->next = lb;
            lb = lb->next;
        }
        lc = lc->next;
    }
    lc->next = la ? la : lb;
    return ld;
}


int main() {
    Lnode* A = (Lnode*)malloc(sizeof(Lnode));
    A->next = NULL;
    Lnode* B = (Lnode*)malloc(sizeof(Lnode));
    B->next = NULL;
    int n = 0;
    int m = 0;
    scanf("%d %d", &n, &m);
    h_insert_Lnode(A, n);
    h_insert_Lnode(B, m);
    Lnode* C = mergeTwoLists(A, B);
    print_Lnode(C);
    return 0;
}

链表的删除

#include <stdio.h>
#include <stdlib.h>

#define OK 1
#define ERROR 0
#define LIST_SIZE 100
#define LISTINCREMENT 10
#define OVERFLOW -2
typedef int Status;
typedef int ElemType;
typedef struct Lnode
{
    ElemType data;
    struct Lnode* next;
} Lnode, * LinkList;

int ListLength(LinkList L) {
    Lnode* p = L;
    int k = 0;
    while (p->next) {
        p = p->next;
        k++;
    }
    return k;
}

Status GetElem(Lnode* L, int i, ElemType &e) {
    Lnode* p = L->next;
    int j = 1;
    while (p && j < i) {
        p = p->next;
        j++;
    }
    if (!p || j > i) return ERROR;
    e = p->data;
    return OK;
}

Status ListInsert_L(LinkList L, int i, ElemType& e) {
    Lnode* p = L,*s;
    int j = 0;
    while (!p || j < i - 1) { p = p->next; j++;}
    if (!p || j > i - 1) return ERROR;
    s = (Lnode*)malloc(sizeof(Lnode));
    s->data = e;
    s->next = p->next;
    p->next = s;
    return OK;
}

Status ListDelete_L(LinkList L, int i, ElemType *e) {
    Lnode* p = L, * s;
    int j = 0;
    while (p->next && j < i-1) { p = p->next; j++; }
    if (!p->next || j > i-1) return ERROR;
    s = p->next;
    *e = s->data;
    p->next = s->next;
    free(s);
    return OK;
}

Status CreateList_L(LinkList L, int n) {
    Lnode* p,*m;
    ElemType q;
    m = L;
    for (int i = 0; i < n; i++) {
        p = (LinkList)malloc(sizeof(Lnode));
        p->next = NULL;
        scanf("%d ", &q);
        p->data = q;
        m->next = p;
        m = m->next;
    }
    return OK;
}

void ClearList(LinkList& L) {
    Lnode* p;
    while (L->next) {
        p = L->next;
        L->next = p->next;
        free(p);
    }
}

struct Lnode* mergeTwoLists(struct Lnode* l1, struct Lnode* l2) {
    Lnode* la = l1->next, * lb = l2->next, * lc, * ld;
    lc = (Lnode*)malloc(sizeof(Lnode));
    ld = lc;

    while (la && lb) {
        if (la->data <= lb->data) {
            lc->next = la;
            la = la->next;
        }
        else {
            lc->next = lb;
            lb = lb->next;
        }
        lc = lc->next;
    }
    lc->next = la ? la : lb;
    return ld;
}

int main() {
    int n,count,q;
    ElemType e;
    Lnode *h = NULL;
    h = (LinkList)malloc(sizeof(Lnode));
    h->next = NULL;
    scanf("%d", &n);
    CreateList_L(h,n);
    scanf("%d", &count);
    for (int i = 0; i < count; i++) {
        scanf("%d", &q);
        if (!ListDelete_L(h, q, &e)) printf("-1\n");
        else printf("%d\n", e);
    }
    return 0;
}

链表的操作

//还包括总结的一些其他操作

#include <bits/stdc++.h>
using namespace std;
#define OK 1
#define ERROR 0
#define LIST_SIZE 100
#define LISTINCREMENT 10
#define OVERFLOW -2

typedef int Status;
typedef int ElemType;
typedef struct Lnode
{
    ElemType data;
    struct Lnode* next;
} Lnode, * LinkList;

Status Reverse(LinkList L) {
    Lnode* p = L->next, * q, * s;
    q = p->next;
    if (!q->next) {
        L->next = q;
        q->next = p;
        p->next = NULL;
        return OK;
    }
    p->next = NULL;
    s = q->next;
    do {
        q->next = p;
        p = q;
        q = s;
        s = s->next;
        
    } while (s);
    q->next = p;
    L->next = q;
    return OK;
}

ElemType add_L(LinkList L) {
    Lnode* p = L->next;
    int sum = 0;
    while (p) { sum += p->data; p = p->next; }
    return sum;
}

Status GetElem(Lnode* L, int i, ElemType& e) {
    Lnode* p = L->next;
    int j = 1;
    while (p && j < i) {
        p = p->next;
        j++;
    }
    if (!p || j > i) return ERROR;
    e = p->data;
    return OK;
}

ElemType LocateElem_L(LinkList L, ElemType *q) {
    Lnode* p = L->next;
    int k = 1;
    while (p) {
        if (*q == p->data) return k;
        k++;
        p = p->next;
    }
    return ERROR;
}

Status ListInsert_L(LinkList L, int i, ElemType& e) {
    Lnode* p = L, * s;
    int j = 0;
    while (!p || j < i - 1) { p = p->next; j++; }
    if (!p || j > i - 1) return ERROR;
    s = (Lnode*)malloc(sizeof(Lnode));
    s->data = e;
    s->next = p->next;
    p->next = s;
    return OK;
}

Status ListDelete_L(LinkList L, int i, ElemType* e) {
    Lnode* p = L, * s;
    int j = 0;
    while (p->next && j < i - 1) { p = p->next; j++; }
    if (!p->next || j > i - 1) return ERROR;
    s = p->next;
    *e = s->data;
    p->next = s->next;
    free(s);
    return OK;
}

Status CreateList_L(LinkList L, int n) {
    Lnode* p, * m;
    ElemType q;
    m = L;
    for (int i = 0; i < n; i++) {
        p = (LinkList)malloc(sizeof(Lnode));
        p->next = NULL;
        scanf("%d ", &q);
        p->data = q;
        m->next = p;
        m = m->next;
    }
    return OK;
}

void ClearList(LinkList& L) {
    Lnode* p;
    while (L->next) {
        p = L->next;
        L->next = p->next;
        free(p);
    }
}

struct Lnode* mergeTwoLists(struct Lnode* l1, struct Lnode* l2) {
    Lnode* la = l1->next, * lb = l2->next, * lc, * ld;
    lc = (Lnode*)malloc(sizeof(Lnode));
    ld = lc;

    while (la && lb) {
        if (la->data <= lb->data) {
            lc->next = la;
            la = la->next;
        }
        else {
            lc->next = lb;
            lb = lb->next;
        }
        lc = lc->next;
    }
    lc->next = la ? la : lb;
    return ld;
}
Status print_L(LinkList L) {
    Lnode* p = L->next;
    while (p) { printf("%d ",p->data); p = p->next; }
    return 0;
}

int main() {
    Lnode* h = (LinkList)malloc(sizeof(Lnode));
    h->next = NULL;
    int n, m, index;
    ElemType e, a, b;
    cin >> n >> m;
    CreateList_L(h, n);
    string s;
    for (int i = 1; i <= m; i++) {
        cin >> s;
        if (s[0] == 'I') {
            cin >> a >> b;
            ListInsert_L(h, a, b);
        }
        else if (s[0] == 'D') {
            cin >> index;
            ListDelete_L(h, index, &b);
            cout << b << endl;
        }
        else if (s[0] == 'G') {
            cin >> index;
            GetElem(h, index, e);
            cout << e << endl;
        }
        else if (s[0] == 'L') {
            cin >> b;
            index = LocateElem_L(h, &b);
            cout << index << endl;
        }
        else {
            ClearList(h);
        }
    }
    return 0;
}

单链表的逆转求和

#include <bits/stdc++.h>
using namespace std;
#define OK 1
#define ERROR 0
#define LIST_SIZE 100
#define LISTINCREMENT 10
#define OVERFLOW -2

typedef int Status;
typedef int ElemType;
typedef struct Lnode
{
    ElemType data;
    struct Lnode* next;
} Lnode, * LinkList;

Status CreateList_L(LinkList L, int n) {
    Lnode* p, * m;
    ElemType q;
    m = L;
    for (int i = 0; i < n; i++) {
        p = (LinkList)malloc(sizeof(Lnode));
        p->next = NULL;
        cin >> q;
        p->data = q;
        m->next = p;
        m = m->next;
    }
    return OK;
}

Status Reverse(LinkList L) {
    Lnode* p = L->next, * q, * s;
    q = p->next;
    if (!q->next) { //只有两个元素时直接交换
        L->next = q;
        q->next = p;
        p->next = NULL;
        return OK;
    }
    p->next = NULL;
    s = q->next;
    do {
        q->next = p;
        p = q;
        q = s;
        s = s->next;
        
    } while (s);
    q->next = p;
    L->next = q;
    return OK;
}

ElemType add_L(LinkList L) {
    Lnode* p = L->next;
    int sum = 0;
    while (p) { sum += p->data; p = p->next; }
    return sum;
}

Status print_L(LinkList L) {
    Lnode* p = L->next;
    while (p) { printf("%d ",p->data); p = p->next; }
    return OK;
}


int main() {
    Lnode* h = (LinkList)malloc(sizeof(Lnode));
    h->next = NULL;
    int n;
    cin >> n;
    CreateList_L(h, n);
    if(n>1) Reverse(h); //考虑n=1或n=2的情况
    print_L(h);
    printf("\n");
    printf("%d",add_L(h));
    
    return 0;
}

汉诺塔问题

#include <stdio.h>

void move(char A,int n,char C){
    printf("%c->%d->%c\n",A,n,C);
}
void hanoi (int n,char A,char B,char C){
    if(n==1){
        move(A,1,C);
    }
    else {
        hanoi(n-1,A,C,B);
        move(A,n,C);
        hanoi(n-1,B,A,C);
    }
}
int main(){
    int n;
    char a,b,c;
    scanf("%d %c %c %c",&n,&a,&c,&b);
    hanoi(n,a,b,c);
}

循环队列插入与删除操作

#include<cstdio>
#include<cstdlib>
#include<cstring>
#define QUEUE_INIT_SIZE 31000
#define OK 1
#define OVERFLOW -2
#define error -1

typedef int DataType;
typedef int Status;
typedef struct duilie{
    int f;
    int r;
    DataType *base;
}queue;
int dlength(&s){
    return (s.r - s.f + QUEUE_INIT_SIZE) % QUEUE_INIT_SIZE;
}
Status init(queue &s){
    s.base = (DataType*)malloc(QUEUE_INIT_SIZE*sizeof(DataType));
    if(s.f==NULL)return -1;
    s.f = s.r = 0;
    return OK;
}
Status in(queue &s,DataType e){
    if(s.f == (s.r +1)%QUEUE_INIT_SIZE) exit(OVERFLOW);
    s.base[s.r]=e;
    s.r = (s.r +1)%QUEUE_INIT_SIZE;
    return OK;
}
int del(queue &s){
    if(s.f ==s.r) return -1;
    DataType q = s.base[s.f];
    s.f =(s.f+1) %QUEUE_INIT_SIZE;
    return q;
}
int main(){
    queue d;
    init(d);
    int n,i;
    scanf("%d",&n);getchar(); 
    for(i=0;i<n;i++){
        char a[100];
        int x,t;
        scanf("%s", a);
        if(strcmp(a,"enqueue")==0){
            scanf("%d",&x);
            in(d,x);
        }
        if(strcmp(a,"dequeue")==0){
            t=del(d);
            printf("%d\n",t);
        }
    }
    return 0;
}

二叉树

由先序遍历和中序遍历序列建立二叉树

#include <stdio.h>
#include <cstdlib>
#include <cstring>

using namespace std;

#define ERROR 0
#define OK 1
#define OVERFLOW -2

typedef int status;
typedef struct Binode {
    char data;
    Binode* lchild;
    Binode* rchild;
}Binode, * BiTree;

int getindex(char* inod, char data,int iright) {
    for (int i = 0; i <= iright; i++) {
        if (inod[i] == data) {
            return i;
        }
    }
    return -1;
}

void PreInOd(char preod[], int pleft, int pright, char inod[], int ileft, int iright, BiTree& t)
{
    if (pleft > pright) {
        t = NULL;
        return;
    }

    t = (Binode*)malloc(sizeof(Binode));
    if (!t) exit(OVERFLOW);
    t->data = preod[pleft];
    int mid = getindex(inod, t->data, iright);

    if (mid == ileft) t->lchild = NULL;
    else  PreInOd(preod, pleft + 1, pleft + mid - ileft, inod, ileft, mid - 1, t->lchild);

    if (mid == iright) t->rchild = NULL;
    else PreInOd(preod, pleft + mid - ileft + 1, pright, inod, mid + 1, iright, t->rchild);
}

int PostOrderTraversal(BiTree T)
{
    if (T)
    {
        PostOrderTraversal(T->lchild);
        PostOrderTraversal(T->rchild);
        printf("%c",T->data);
    }
    return OK;
}

int main() {
    char preod[100];
    char inod[100];
    BiTree t;

    scanf("%s", preod);
    scanf("%s", inod);
    int n1 = strlen(preod);
    int n2 = strlen(inod);
    PreInOd(preod, 0, n1-1, inod, 0, n2-1, t);
    PostOrderTraversal(t);
    printf("\n");
    return 0;
}

二叉树建立、中序遍历、叶子结点及深度

#include <cstdlib>
#include <cstdio>
using namespace std;

#define ERROR 0
#define OK 1
#define OVERFLOW -2

typedef int status;
typedef struct Binode {
    char data;
    int deep;
    Binode* lchild;
    Binode* rchild;
}Binode, * BiTree;


status exchange(BiTree& T) {
    if (T) {
        BiTree temp = T->lchild;
        T->lchild = T->rchild;
        T->rchild = temp;
        exchange(T->lchild);
        exchange(T->rchild);
    }
    return OK;
}

void CountLeaf(BiTree T, int& count) {
    if (T) {
        if ((!T->lchild) && (!T->rchild))
            count++;    
        CountLeaf(T->lchild, count);
        CountLeaf(T->rchild, count);
    } 
}

status InTraversal(BiTree T) {
    if (T) {
        InTraversal(T->lchild);
        printf("%c ", T->data);
        InTraversal(T->rchild);
    }
    return OK;
}

int  BitreeDepth(BiTree T)
{
    int depth = 0;
    if (T == NULL) depth = 0;
    else {
        int ldepth = BitreeDepth(T->lchild);
        int rdepth = BitreeDepth(T->rchild);
        depth = 1 + (ldepth > rdepth ? ldepth : rdepth);
    }
    return depth;
}


status creabitree(BiTree& T) {
    char get;
    scanf("%c", &get);
    if (get == '#' || get == '\n') T = NULL;
    else {
        if (!(T = (Binode*)malloc(sizeof(Binode)))) exit(OVERFLOW);
        T->data = get;
        T->deep = 1;
        creabitree(T->lchild);
        creabitree(T->rchild);
    }
    return OK;
}

int main() {
    int count = 0,deep=0;
    BiTree T;
    creabitree(T);

    exchange(T);
    InTraversal(T);

    printf("\n");
    CountLeaf(T, count);
    printf("%d\n", count);

    printf("%d\n", BitreeDepth(T) );
    return 0;
}

建二叉树并输出所找结点的祖先

注意这里的代码建议使用pop和push合用的形式,使用我下面的这个代码在过大情况下会导致内存超出的错误。不过因为oj测试数据范围较小,下面的代码也可以通过。(懒得改了)

#include <cstdlib>
#include <cstdio>
using namespace std;

#define ERROR 0
#define OK 1
#define OVERFLOW -2

typedef struct Stacknode{
    int data;
    struct Stacknode* next;
}Stacknode;

typedef struct stack {
    Stacknode* top;
}stack;

typedef int status;
typedef struct Binode {
    int data;
    Binode* lchild;
    Binode* rchild;
}Binode, * BiTree;

status push(stack& t,int data) {
    Stacknode* p = (Stacknode*)malloc(sizeof(Stacknode));
    if (p == NULL) exit(OVERFLOW);
    p->data = data;
    p->next = t.top;
    t.top = p;
    return OK;
}
status initstack(stack& t) {
    t.top = NULL;
    return OK;
}

status printstack(stack t) {
    Stacknode* p = t.top;
    while (p != NULL) {
        printf("%d ", p->data);
        p = p->next;
    }
    return OK;
}

status getfather(BiTree& T, int node,stack t) {
    if (T) {
        push(t, T->data);
        if (T->data == node) printstack(t);
        getfather(T->lchild, node,t);
        getfather(T->rchild, node, t);
    }
    return OK;
}

status creabitree(BiTree& T) {
    int get;
    scanf("%d", &get);
    if (get == 0) T = NULL;
    else {
        if (!(T = (Binode*)malloc(sizeof(Binode)))) exit(OVERFLOW);
        T->data = get;
        creabitree(T->lchild);
        creabitree(T->rchild);
    }
    return OK;
}

int main() {
    int count = 0,deep=0;
    BiTree T;
    creabitree(T);
    scanf("%d", &count);
    for (int i = 0; i < count; i++) {
        int node;
        scanf("%d", &node);
        stack t;
        initstack(t);
        getfather(T, node, t);
        printf("\n");
    }
    return 0;
}

二元组建树并求其叶子结点和深度

#include<stdio.h>
#include <stdlib.h>

#define ERROR 0
#define OK 1
#define OVERFLOW -2

typedef int Elem;

typedef struct CSNode {
    Elem data;
    struct CSNode* firstchild, * nextsibling;
} CSNode, * CSTree;

typedef CSNode Qelemtype;
typedef int status;

typedef struct QNode {
    Qelemtype* Qdata;
    struct QNode* next;
}Qnode, * QueuePtr;

typedef struct {
    QueuePtr front;
    QueuePtr rear;
} LinkQueue;

status InitQueue(LinkQueue& Q) {
    Q.front = Q.rear = (QueuePtr)malloc(sizeof(Qnode));
    if (!Q.front) exit(OVERFLOW);
    Q.front->next = NULL;
    return OK;
}

status EnQueue(LinkQueue& Q, Qelemtype *e)
{
    QueuePtr p = (QueuePtr)malloc(sizeof(QNode));
    if (!p) exit(OVERFLOW);
    p->Qdata = e; p->next = NULL;
    Q.rear->next = p;
    Q.rear = p;
    return OK;
}

Qelemtype* DeQueue(LinkQueue& Q) {
    Qelemtype* e;
    if (Q.front == Q.rear) return(ERROR);
    QueuePtr p = Q.front->next;
    e = p->Qdata;
    Q.front->next = p->next;
    if (Q.rear == p) Q.rear = Q.front;
    free(p);
    return e;
}

Qelemtype* GetHead(LinkQueue& Q) {
    Qelemtype* e;
    if (Q.front == Q.rear) return ERROR;
    e = Q.front->next->Qdata;
    return e;
}

CSTree GetTreeNode(int ch){
    CSTree p = (CSTree)malloc(sizeof(CSNode));
    p->data = ch;
    p->firstchild = NULL;
    p->nextsibling = NULL;
    return p;
}

void CreatTree(CSTree& T){
    T = NULL;
    CSTree r =NULL;
    int ch = NULL, fa = NULL;
    int i = 0;
    LinkQueue Q;

    InitQueue(Q);

    scanf("%d", &i); getchar();
    for (int j =0; j<i; j++)
    {
        CSTree s = NULL, p;

        scanf("%d %d", & fa, &ch); getchar();

        p = GetTreeNode(ch); 
        EnQueue(Q, p); 
        if (fa == -1)  T = p;
        else {
            s = GetHead(Q); 
            while (s->data != fa) {  
                s = DeQueue(Q);  s =GetHead(Q);
            }
            if (!(s->firstchild)){
                s->firstchild = p; r = p;
            }
            else { r->nextsibling = p; r = p; }
        } 
    }
} 

int TreeDepth(CSTree T) {
    int h1, h2;
    if (!T) return 0;
    else {
        h1 = TreeDepth(T->firstchild);
        h2 = TreeDepth(T->nextsibling);
        return(h1 + 1 > h2 ? h1 + 1 : h2);
    }
}

status pretraverse(CSTree T) {
    if (T) {
        if(!T->firstchild) printf("%d ",T->data);
        pretraverse(T->firstchild);
        pretraverse(T->nextsibling);
    }
    return OK;
}

int main() {
    CSTree T;
    CreatTree(T);

    pretraverse(T);
    printf("\n");
    printf("%d",TreeDepth(T));

    return 0;
}

数据压缩中的编码问题

不会,用ai辅助写的。。。

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define MAX_CHAR 127


typedef struct Node {
    int freq;
    struct Node* next;
} Node;

void insertSorted(Node** head, int freq) {
    Node* newNode = (Node*)malloc(sizeof(Node));
    newNode->freq = freq;
    newNode->next = NULL;

    if (*head == NULL || (*head)->freq >= freq) {
        newNode->next = *head;
        *head = newNode;
    }
    else {
        Node* curr = *head;
        while (curr->next != NULL && curr->next->freq < freq) {
            curr = curr->next;
        }
        newNode->next = curr->next;
        curr->next = newNode;
    }
}

int popMin(Node** head) {
    if (*head == NULL) return 0;
    Node* temp = *head;
    int val = temp->freq;
    *head = (*head)->next;
    free(temp);
    return val;
}

int huffmanEncodedLength(const char* str) {
    int freq[MAX_CHAR] = { 0 };

    for (int i = 0; str[i]; i++) {
        freq[(unsigned char)str[i]]++;
    }

    Node* head = NULL;
    for (int i = 0; i < MAX_CHAR; i++) {
        if (freq[i] > 0) {
            insertSorted(&head, freq[i]);
        }
    }

    int totalLength = 0;

    while (head && head->next) {
        int f1 = popMin(&head);
        int f2 = popMin(&head);
        int merged = f1 + f2;
        totalLength += merged;
        insertSorted(&head, merged);
    }

    return totalLength;
}

int main() {
    char input[101];
    int count = 0;
    scanf("%d", &count); getchar(); 
    for (int i = 0; i < count; i++) {
        fgets(input, 101, stdin);
        input[strcspn(input, "\n")] = '\0';

        int encodedLength = huffmanEncodedLength(input);
        printf("%d\n", encodedLength);
    }

    return 0;
}

任两点间最短路径Floyd算法

#include <iostream>
using namespace std;
#define MAX_VERTEX_N 105
#define MAX_EDGE_M 10005
#define INF 1000000007
typedef int VRType;
typedef int VertexType;
typedef int status;

typedef struct ArcCell {
    VRType adj;
} ArcCell, AdjMatrix[MAX_VERTEX_N][MAX_VERTEX_N];

typedef struct MGraph {
    VertexType vexs[MAX_VERTEX_N];
    AdjMatrix arcs;
    int vexnum, arcnum;
} MGraph;
int m;
int dist[MAX_VERTEX_N][MAX_VERTEX_N];

void CreatGraph(MGraph& G) {
    int u, v, t;
    cin >> G.vexnum >> m;
    for (int i = 0; i < G.vexnum; i++) {
        for (int j = 0; j < G.vexnum; j++) {
            G.arcs[i][j].adj = INF;
        }
    }
    for (int i = 0; i < G.vexnum; i++) {
        for (int j = 0; j < G.vexnum; j++) {
            cin >> G.arcs[i][j].adj;
        }
    }
}
void Floyd(MGraph G) {
    for (int i = 0; i < G.vexnum; i++) {
        for (int j = 0; j < G.vexnum; j++) {
            dist[i][j] = G.arcs[i][j].adj;
        }
    }
    for (int k = 0; k < G.vexnum; k++) {
        for (int i = 0; i < G.vexnum; i++) {
            for (int j = 0; j < G.vexnum; j++) {
                if(dist[i][j] > dist[i][k]+dist[k][j]){
                    dist[i][j] = dist[i][k]+dist[k][j];
                }
                            
            }
        }
    }

    int u,v;
    for(int i =0;i<m;i++){
        cin >> u >>v;
        cout << dist[u][v] <<endl;
    }
}

int main() {
    MGraph G;
    CreatGraph(G);
    Floyd(G);

    return 0;
}

关键路径

#include <bits/stdc++.h>
using namespace std;
#define MAX_VERTEX_N 250
#define MAX_EDGE_M 10005
#define INF 1000000007
typedef int VRType;
typedef int VertexType;
typedef int status;

typedef struct ArcNode {
    int adjvex;
    VRType cost;
    struct ArcNode *nextarc;
} ArcNode; 

typedef struct VNode { 
    VertexType data;
    ArcNode *firstarc;
} VNode, AdjList[MAX_VERTEX_N];

typedef struct {  
    AdjList vertices;
    int vexnum, arcnum; 
} ALGraph;

typedef struct Queue{ 
    int data[MAX_VERTEX_N];
    int rear, front; 
} Queue;

typedef struct Edge { 
    int v, w;
} Edge;

bool cmp(Edge a, Edge b) {
    return a.v == b.v? a.w < b.w :a.v < b.v;
}

void InitQueue(Queue &Q){
    Q.rear = Q.front = 0;
}
int EmptyQueue(Queue Q){
    return Q.rear == Q.front;
}
void Push(Queue &Q, int x){
    Q.data[Q.rear++] = x;
}
void Pop(Queue &Q, int &x){
    int minn = Q.data[Q.front], j = Q.front;
    for (int i=Q.front;i<Q.rear;i++)
        if (Q.data[i] < minn) minn = Q.data[i], j=i;
    int temp = Q.data[j];
    Q.data[j] = Q.data[Q.front];
    Q.data[Q.front] = temp;
    x = Q.data[Q.front++];
}

void CreatGraph(ALGraph &G){
    int v, w, x;
    scanf("%d%d", &G.vexnum, &G.arcnum);	
    
    for (int i=1;i<=G.vexnum;i++) {
        G.vertices[i].data = i;
        G.vertices[i].firstarc = NULL;
    }
    for (int i=1;i<=G.arcnum;i++){
        scanf("%d%d%d", &v, &w, &x);
        ArcNode *p = (ArcNode*)malloc(sizeof(ArcNode));
        p->adjvex = w; p->cost = x; p->nextarc = G.vertices[v].firstarc;
        G.vertices[v].firstarc = p;
    }
}

void CountInDegree(ALGraph G, int indegree[]){
    for (int v=1;v<=G.vexnum;v++) indegree[v] = 0;
    for (int v=1;v<=G.vexnum;v++){
        for (ArcNode* w=G.vertices[v].firstarc; w; w=w->nextarc)
            indegree[w->adjvex]++;
    }
}

void TopoLogicalSort(ALGraph G){
    //拓扑排序 
    Queue Q;
    int v, indegree[MAX_VERTEX_N];
    int topo[MAX_VERTEX_N], ve[MAX_VERTEX_N], vl[MAX_VERTEX_N];
    CountInDegree(G,indegree);
    InitQueue(Q);
    for (int v=1;v<=G.vexnum;v++)
        if (!indegree[v]) {
            Push(Q, v); indegree[v] = INF;
        }			
    while (!EmptyQueue(Q)) {
        Pop(Q, v);
        for (ArcNode* w=G.vertices[v].firstarc; w; w=w->nextarc)  {
            indegree[w->adjvex]--; 
            if (!indegree[w->adjvex]) {
                Push(Q, w->adjvex); indegree[w->adjvex] = INF;
            }			
        } 
    } 
    if (Q.rear<G.vexnum) {
        printf("unworkable project\n");	
        return ;
    }	
    for (int i=1;i<=G.vexnum;i++) topo[i] = Q.data[i-1];
        
    int max =0;	
    for(int i=1;i<=G.vexnum;i++)ve[i] =0;
    for(int i=1;i<=G.vexnum;i++){
        int v =topo[i];
        if(ve[v]>max)max=ve[v];
        for(ArcNode * p=G.vertices[v].firstarc;p;p=p->nextarc){
            if(ve[p->adjvex]<ve[v] + p->cost) ve[p->adjvex] = ve[v] + p->cost;
        }
    }

    printf("%d\n", max);
    for(int i =1;i<=G.vexnum;i++) vl[i] =max;
    for(int i =G.vexnum;i>0;i--){
        int v = topo[i];
        for(ArcNode * p=G.vertices[v].firstarc;p;p=p->nextarc){
            if(vl[v] > vl[p->adjvex]- p->cost) vl[v] = vl[p->adjvex] - p->cost;
        }
        
    }
    int t =0;
    Edge edge[MAX_EDGE_M];
    for(int v=1;v<=G.vexnum;v++){
        for(ArcNode * p=G.vertices[v].firstarc;p;p=p->nextarc){
            int e =ve[v];
            int l =vl[p->adjvex] - p->cost;
            if(e==l){
                edge[t].v = v;
                edge[t++].w =p->adjvex;
            } 
        }
    }
    sort(edge, edge+t, cmp);
    for (int i=0;i<t;i++) printf("%d->%d\n", edge[i].v, edge[i].w);
} 

int main() {
    ALGraph G; 
    CreatGraph(G);
    TopoLogicalSort(G); 
    return 0;
}