算法与程序设计综合实验

实验一

  • 实验名称。

用链式存储结构实现将m个有序表合并成一个有序表。

  • 相关理论

单链表的合并,链表的定义和链表初始化和输出。

  • 关键代码。

#include <iostream>

#include <algorithm>

#include <vector>

#include <stdio.h>

using namespace std;

typedef struct LinkList {

    int data;

    struct LinkList* next;

}Data;

void print_list(Data* head) {

    while (head) {

        printf("%d ", head->data);

        head = head->next;

    }

    printf("\n");

}

Data* insert_tail(Data* head, int n) {

    head = (Data*)malloc(sizeof(Data));

    head->next = NULL;

    Data* r = head;

    while (n--) {

        Data* p = (Data*)malloc(sizeof(Data));

        int data;

        scanf_s("%d", &data);

        p->data = data;

        r->next = p;

        r = p;

        p->next = NULL;

    }

    return head->next;

}

Data* merge_two_list(Data* headA, Data* headB) {

    Data p;

    p.data = 0;

    p.next = NULL;

    Data* result = &p;

    while (headA && headB) {

        if (headA->data < headB->data) {

            result->next = headA;

            headA = headA->next;

        }

        else {

            result->next = headB;

            headB = headB->next;

        }

        result = result->next;

    }

    if (headA == NULL) {

        result->next = headB;

    }

    if (headB == NULL) {

        result->next = headA;

    }

    return p.next;

}

Data* merge_list(vector<Data*>& list) {

    if (list.size() == 0) {

        return NULL;

    }

    if (list.size() == 1) {

        return list[0];

    }

    int mid = list.size() / 2;

    int i;

    vector <Data*> sub_list1, sub_list2;

    for (i = 0; i < mid; ++i) {

        sub_list1.push_back(list[i]);

    }

    for (i = mid; i < list.size(); ++i) {

        sub_list2.push_back(list[i]);

    }

    Data* list1 = merge_list(sub_list1);

    Data* list2 = merge_list(sub_list2);

    return merge_two_list(list1, list2);

}

bool cmp(Data* A, Data* B) {

    return A->data < B->data;

}

Data* merge_list2(vector<Data*>& list) {

    if (list.size() == 0) {

        return NULL;

    }

    if (list.size() == 1) {

        return list[0];

    }

    vector<Data*> result;

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

        while (list[i]) {

            result.push_back(list[i]);

            list[i] = list[i]->next;

        }

    }

    sort(result.begin(), result.end(), cmp);

    return result[0];

}

int main() {

    vector<Data*> list;

    printf("input the num of the construct list \n");

    int num;

    scanf_s("%d", &num);

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

        Data* p{};

        printf("construct the %d list:\n", i + 1);

        list.push_back(insert_tail(p, 3));

    }

    printf("merget the mulity list with method 1 is \n");

    Data* result = merge_list(list);

    print_list(result);

    printf("merge the mulity list with method 2 is \n");

    Data* result2 = merge_list2(list);

    print_list(result2);

    return 0;

}

  • 实验结果与分析。

实验二

  • 实验目的。

已知线性表中的元素是无序的,并以带头结点的单链表作为存储结构。删除表中所有值大于min小于max的元素(若表中存在这样的元素)。

  • 相关理论

单链表的遍历,排序,以及单链表的查找。

  • 关键代码。

#include<stdio.h>

#include<stdlib.h>

typedef int ElemType;

typedef int Status;

typedef struct LNode

{

ElemType data;

LNode* next;

}LNode, * LinkList;

Status InitList(LinkList& L)

{

L = (LNode*)malloc(sizeof(LNode));

L->next = NULL;

return true;

}

Status CreateList(LinkList& L, int e)

{

LinkList p = L;

while (p->next)

p = p->next;

LinkList temp = (LinkList)malloc(sizeof(LNode));

temp->data = e;

temp->next = NULL;

p->next = temp;

return true;

}

Status DispList(LinkList& L)

{

LinkList p = L->next;

int i = 0;

while (p)

{

printf("%d\t", p->data);

i++;

p = p->next;

}

return true;

}

Status DeleteMiddleElem(LinkList& L, int mink, int maxk)

{

LinkList p, q, prev = L;

if (mink > maxk)return false;

p = L->next;

while (p != NULL)

{

if (p->data > mink && p->data < maxk)

{

prev->next = p->next;

q = p;

p = p->next;

free(q);

}

else

{

prev = p;

p = p->next;

}

}

return true;

}

int main()

{

int a[50], length = 0, min, max;

char flag = ' ';

printf("请输入一个线性表:");

for (int i = 0; flag == ' '; i++)

{

scanf_s("%d", &a[i]);

flag = getchar();

length++;

}

LinkList L;

InitList(L);

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

CreateList(L, a[i]);

printf("请输入裁剪区间:min max\n");

scanf_s("%d %d", &min, &max);

DeleteMiddleElem(L, min, max);

printf("裁剪后的结果为:\n");

DispList(L);

getchar();

system("pause");

return true;

}

  • 实验结果与分析。

实验三

  • 实验目的。

设计在无头结点的单链表中删除第i个节点的程序。

  • 相关理论

单链表的遍历;无头结点单链表的定位;单链表的删除相关操作

  • 关键代码。

#include<stdio.h>

#include<stdlib.h>

#define OK 1

typedef int Status;

typedef int ElemType;

typedef struct LNode

{

    ElemType data;

    LNode* next;

}LNode, * LinkList;

Status InitList(LinkList& L)

{

    L = (LNode*)malloc(sizeof(LNode));

    L->next = NULL;

    return OK;

}//InitList

Status CreateList(LinkList& L, int e)

{

    LinkList p = L;

    while (p->next)

        p = p->next;

    LinkList temp = (LinkList)malloc(sizeof(LNode));

    temp->data = e;

    temp->next = NULL;

    p->next = temp;

    return OK;

}//CreateList

Status DispList(LinkList& L)

{

    LinkList p = L->next;

    int i = 0;

    while (p)

    {

        printf("%d\t", p->data);

        i++;

        p = p->next;

    }

    return OK;

}//DispList

Status Delete(LinkList& L, int i)

{

    LinkList p{};

    if (i == 0)

    {

        L = p->next;

    }

    else

    {

        p = L;

        while (i > 0)

        {

            p = p->next;

            i--;

        }

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

    }

    return OK;

}// Delete

int main()

{

    int j, k;

    LinkList L;

    InitList(L);

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

    {

        scanf_s("%d", &k);

        CreateList(L, k);

    }

    printf("链表ha的元素有:\n");

    DispList(L);

    printf("\n删除表 L 的第 i个数据元素:\n");

    scanf_s("%d", &j);

    Delete(L, j - 1);

    DispList(L);

    return OK;

}

三、实验结果与分析。

实验四

  • 实验目的。

实现在单链表中删除相同的多余结点的程序。

  • 相关理论

单链表的遍历,单链表的定位与删除。

  • 关键代码。

#include<stdio.h>

#include<stdlib.h>

#include<assert.h>

#define  LEN  10

typedef  int  Elemtype;

typedef struct LNode {

Elemtype data;

struct LNode* next;

}LNode, * Linklist;

void Init_Linklist(Linklist* L)

{

*L = (Linklist)malloc(sizeof(LNode));

assert(*L != NULL);

(*L)->next = NULL;

}

void Create_Linklist(Linklist* L)

{

LNode* p, * q;

p = *L;

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

{

q = (Linklist)malloc(sizeof(LNode));

assert(q != NULL);

scanf_s("%d", &q->data);

p->next = q;

p = q;

}

p->next = NULL;

}

void DeleteSame(Linklist* L)

{

LNode* p, * q, * s;

p = (*L)->next;

for (p; p != NULL; p = p->next)

{

s = p;

for (q = p->next; q != NULL;)

{

if (q->data == p->data)

{

s->next = q->next;

free(q);

q = s->next;

}

else

{

s = q;

q = q->next;

}

}

}

}

void Print_Linklist(Linklist* L)

{

LNode* p;

p = *L;

while (p->next)

{

p = p->next;

printf("%d ", p->data);

}

printf("\n");

}

int main()

{

Linklist L;

Init_Linklist(&L);

Create_Linklist(&L);

printf("初始化链表为:\n");

Print_Linklist(&L);

DeleteSame(&L);

printf("删除后链表为:\n");

Print_Linklist(&L);

return 0;

}

  • 实验结果与分析。

实验五

  • 实验目的。

给定一颗二叉树用链表表示,用非递归算法求出二叉树叶子节点的数目。

  • 相关理论

二叉树的遍历;叶子节点的定义与查找;二叉树的初始化和输入;

  • 关键代码。

#include <iostream>

#include <stack>

#include <string>

#include<queue>

#include<stdio.h>

#include<stdlib.h>

#define MaxSize 1000

typedef struct BiTNode

{

    char data;

    struct BiTNode* lchild;

    struct BiTNode* rchild;

}BiTNode, * BiTree;

using namespace std;

void Initial(BiTree& T) {

    T = new BiTNode;

    T = NULL;

}

void CreateBiTree(BiTree& T)

{

    stack<BiTNode*> s;

    BiTNode* p = NULL;

    int i = 0;

    bool child_Direct;

    string TreeStr;

    cin >> TreeStr;

    while (TreeStr[i] != '\0') {

        switch (TreeStr[i])

        {

        case'(':

            s.push(p);

            child_Direct = false;

            break;

        case')':

            s.pop();

        case',':

            child_Direct = true;

            break;

        default:

            p = new BiTNode;

            p->data = TreeStr[i];

            p->lchild = p->rchild = NULL;

            if (T == NULL)

                T = p;

            else {

                if (!child_Direct)

                    s.top()->lchild = p;

                else

                    s.top()->rchild = p;

            }

            break;

        }

        i++;

    }

}

void DispBTNode(BiTNode*& b)

{

    if (b != NULL)

    {

        cout << b->data;

        if (b->lchild != NULL || b->rchild != NULL)

        {

            cout << "(";

            DispBTNode(b->lchild);

            if (b->rchild != NULL) cout << (",");

            DispBTNode(b->rchild);

            cout << ")";

        }

    }

}

int Count_BiTree0(BiTree T)

{

    int top = -1;     

    int count = 0;

    BiTree S[MaxSize];

    while (T != NULL || top != -1)

    {

        while (T != NULL)

        {

            if (T->lchild == NULL && T->rchild == NULL)

            {

                count++;

            }

            S[++top] = T;   

            T = T->lchild;  

        }

        if (top != -1)

        {

            T = S[top--];   

            T = T->rchild;  

        }

    }

    return count;

}

int main()

{

    BiTree T;

    Initial(T);

    CreateBiTree(T);

    printf("叶子节点数目:%d\n", Count_BiTree0(T));

    return 0;

}

  • 实验结果与分析。

实验六

  1. 实验目的

给定一颗二叉树用链表表示,用非递归算法求出二叉树的深度。

  1. 相关理论

二叉树的定义与初始化;二叉树的遍历;

  1. 关键代码

#include <iostream>

#include <stack>

#include <string>

#include<queue>

#define Maxsize  1000;

using namespace std;

typedef struct BiTNode {

    char data;

    struct BiTNode* lchild, * rchild;

}*BiTree;

void Initial(BiTree& T) {

    T = new BiTNode;

    T = NULL;

}

void CreateBiTree(BiTree& T)

{

    stack<BiTNode*> s;

    BiTNode* p = NULL;

    int i = 0;

    bool child_Direct;

    string TreeStr;

    cin >> TreeStr;

    while (TreeStr[i] != '\0') {

        switch (TreeStr[i])

        {

        case'(':

            s.push(p);

            child_Direct = false;

            break;

        case')':

            s.pop();

        case',':

            child_Direct = true;

            break;

        default:

            p = new BiTNode;

            p->data = TreeStr[i];

            p->lchild = p->rchild = NULL;

            if (T == NULL)

                T = p;

            else {

                if (!child_Direct)

                    s.top()->lchild = p;

                else

                    s.top()->rchild = p;

            }

            break;

        }

        i++;

    }

}

void DispBTNode(BiTNode*& b)

{

    if (b != NULL)

    {

        cout << b->data;

        if (b->lchild != NULL || b->rchild != NULL)

        {

            cout << "(";

            DispBTNode(b->lchild);

            if (b->rchild != NULL) cout << (",");

            DispBTNode(b->rchild);

            cout << ")";

        }

    }

}

int depth(BiTNode* pRoot) {

    if (!pRoot) {

        return 0;

    }

    queue<BiTNode*> q;

    q.push(pRoot);

    int level = 0;

    while (!q.empty()) {

        int len = q.size();

        level++;

        while (len--) {

            BiTNode* top = q.front();

            q.pop();

            if (top->lchild) {

                q.push(top->lchild);

            }

            if (top->rchild) {

                q.push(top->rchild);

            }

        }

    }

    return level;

}

int main()

{

    cout << "请输入树:";

    BiTree b;

    Initial(b);

    CreateBiTree(b);

    cout << "深度为:" << depth(b);

}

  1. 实验结果与分析

实验七

  1. 实验目的。

给定一颗二叉树用链表表示,用非递归算法求出二叉树结点的数目。

  1. 相关理论

二叉树的定义、初始化、遍历;

  1. 关键代码。

#include <iostream>

#include <stack>

#include <string>

#include<queue>

#define Maxsize  1000;

using namespace std;

typedef struct BiTNode {

    char data;

    struct BiTNode* lchild, * rchild;

}*BiTree;

void Initial(BiTree& T) {

    T = new BiTNode;

    T = NULL;

}

void CreateBiTree(BiTree& T)

{

    stack<BiTNode*> s;

    BiTNode* p = NULL;

    int i = 0;

    bool child_Direct;

    string TreeStr;

    cin >> TreeStr;

    while (TreeStr[i] != '\0') {

        switch (TreeStr[i])

        {

        case'(':

            s.push(p);

            child_Direct = false;

            break;

        case')':

            s.pop();

        case',':

            child_Direct = true;

            break;

        default:

            p = new BiTNode;

            p->data = TreeStr[i];

            p->lchild = p->rchild = NULL;

            if (T == NULL)

                T = p;

            else {

                if (!child_Direct)

                    s.top()->lchild = p;

                else

                    s.top()->rchild = p;

            }

            break;

        }

        i++;

    }

}

void DispBTNode(BiTNode*& b)

{

    if (b != NULL)

    {

        cout << b->data;

        if (b->lchild != NULL || b->rchild != NULL)

        {

            cout << "(";

            DispBTNode(b->lchild);

            if (b->rchild != NULL) cout << (",");

            DispBTNode(b->rchild);

            cout << ")";

        }

    }

}

int preorder_get_nodes_number(BiTNode* b)

{

    if (b == NULL)

        return 0;

    int num = 0;

    stack <BiTNode*> st;

    while (b != NULL || !st.empty())

    {

        while (b != NULL)

        {

            cout << "节点:" << b->data << endl;

            ++num;

            st.push(b);

           b = b->lchild;

        }

        if (!st.empty())

        {

           b = st.top();

            st.pop();

         b = b->rchild;

        }

    }

    return num;

}

int main()

{

    cout << "请输入树:";

    BiTree b;

    Initial(b);

    CreateBiTree(b);

    cout << "结点数为:" << preorder_get_nodes_number(b);

}

  1. 实验结果与分析。

实验八

  • 实验目的。

写出在无头结点的单链表的第i个元素之前插入一个元素的程序。

  • 相关理论

无头结点单链表的遍历、定位、插入;

  • 关键代码。

#include<stdio.h>

#include<malloc.h>

#include <stdlib.h>

#define error -1;

#define OK 1;

typedef int ElemType;

typedef int status;

typedef struct LNode

{

    ElemType data;

    struct LNode* next;

}LNode, * LinkList;

LinkList creat()

{

    LinkList L;

      L = (LinkList)malloc(sizeof(LNode));

        if(!L)   printf("memory malloc error!\n");

      LinkList p = L;

    ElemType a;

    int len;

    printf("请输入待建表的表长:");

    scanf_s("%d", &len);

    if (len > 1)

    {

        printf("请输入第1个元素的值:");

        scanf_s("%d", &a);

        L = (LinkList)malloc(sizeof(LNode));

        if (!L)

            printf("memory malloc error!\n");

        L->data = a;

        LinkList p = L;

        for (int i = 1; i < len; i++)

        {

            printf("请输入第%d个元素的值:", i + 1);

            scanf_s("%d", &a);

            p->next = (LinkList)malloc(sizeof(LNode));

            p->next->data = a;

            p = p->next;

        }

        p->next = NULL;

        return L;

    }

}

void print(LinkList L)

{

    LinkList p = L;

    while (p != NULL)

    {

        printf("%d\n", p->data);

        p = p->next;

    }

}

status insert(LinkList* L, int i, int b)

{

    LinkList p = NULL;

    if (i < 1)     return error;

    if (i == 1)

    {

        p = (LinkList)malloc(sizeof(LNode));

        if (!p)

            printf("memory malloc error!\n");

        p->data = b;

        p->next = *L;                    

        *L = p;        

        return OK;

    }

    else

    {

        p = (LinkList)malloc(sizeof(LNode));

        if (!p)

            printf("memory malloc error!\n");

        p->data = b;

        LinkList q = *L;    

        LinkList qpre = NULL;   

        while (i > 1)

        {

            qpre = q;

            q = q->next;

            i--;

        }

        p->next = q;

        qpre->next = p;

        return OK;

    }

}

int main()

{

    LinkList L = creat();

    int i;

    printf("请输入待插入的位置:");

    scanf_s("%d", &i);

    int b;

    printf("请输入待插入的元素值:");

    scanf_s("%d", &b);

    insert(&L, i, b);

    print(L);

    return 0;

}

  • 实验结果与分析。

实验九

  1. 实验目的

试写一个判别表达式中开、闭括号是否配对出现的程序

  1. 相关理论

栈的定义和初始化;括号入栈出栈的条件;

  1. 关键代码

#include<stdio.h>

#define true 1

#define false 0

#define maxsize 100

typedef int status;

status match(char exp[], int n)

{

    if (n < 0)

    {

        printf("匹配失败!");

        return false;

    }

    char stack[maxsize];    int top = -1;

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

    {

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

            stack[++top] = exp[i];

        else if (exp[i] == ')')

        {

            if (stack[top] == '(')

                top--;

            else

            {

                printf("匹配失败!");

                return false;

            }

        }

        else if (exp[i] == '}')

        {

            if (stack[top] == '{')

                top--;

            else

            {

                printf("匹配失败!");

                return false;

            }

        }

        else if (exp[i] == ']')

        {

            if (stack[top] == '[')

                top--;

            else

            {

                printf("匹配失败!");

                return false;

            }

        }

    }

    if (top == -1)

    {

        printf("匹配成功!");

        return true;

    }

    else

    {

        printf("匹配失败!");

        return false;

    }

}

void main()

{

    char exp[maxsize];

    int n, i, x;

    printf("请输入表达式的长度n:\n");

    scanf_s("%d", &n);

    getchar();  

    if (n > 0)

    {

        printf("请逐个输入表达式中的字符:\n");

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

        {

            x = getchar();     

            exp[i] = x;

            printf("exp[%d]=%c\n", i, exp[i]);

        }

    }

    match(exp, n);

}

  1. 实验结果和分析

实验十

  1. 实验目的

编写从串s删除所有与串t中相同字符串的函数

  1. 相关理论

串的定义和初始化;串的匹配。

  1. 关键代码

#include<iostream>

#include<string>

using namespace std;

void move(string* S, int location)

{

    int length_S = S->length();

    for (int i = location; i < length_S; i++)

    {

        (*S)[i] = (*S)[i + 1];

    }

}

void compare(string* S, string t) {

    int length_S = S->length();

    int length_t = t.length();

    int index = 0;

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

        for (int j = 0; j < length_t; j++) {

            if ((*S)[i] == t[j]) {

                move(S, i);

            }

            else {

                index++;

            }

        }

    }

    if (index == length_t * length_S) {

        cout << endl;

        cout << "未在主串S中找到需要删除的字符!" << endl;

    }

}

void print(string S)

{

    cout << endl;

    cout << "进行删除操作后,字符串S变为:";

    cout << S << endl;

}

int main()

{

    cout << "输入字符串S:";

    string S;

    cin >> S;

    cout << "输入需要删除的字符串t:";

    string t;

    cin >> t;

    compare(&S, t);

    print(S);

    return 0;

}

  1. 实验结果与分析

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值