数据结构习题解析与实验指导第二章课后算法设计题

  1. 将两个递增的有序列表合并为一个递增的有序链表。要求结果链表仍使用原来两个链表的存储空间,不另外占用存储空间。表中不允许有重复的数据。
#include <iostream>
#include <string>
#include <iomanip>
using namespace std;

class Node {
public:
    int data;
    Node* next;
    Node(int data = 0, Node* next = 0): data(data), next(0) {
    }
};

void add(Node* head, Node* node) {
    for (Node* i = head; i != 0; i = i->next) {
        if (i->next == 0) {
            i->next = node;
            break;
        }
    }
}

void clear(Node* head) {
    while (head->next != 0) {
        Node* temp = head->next;
        head->next = head->next->next;
        delete temp;
    }
}

void display(Node* head) {
    head = head->next;
    while (head != 0) {
        cout << head->data << " ";
        head = head->next;
    }
    cout << endl;
}

Node* combine(Node* list1, Node* list2) {
    Node* head = list1;
    Node* tail = list1;
    list1 = list1->next;
    list2 = list2->next;
    while (list1 != 0 && list2 != 0)
    {
        if (list1->data < list2->data) {
            tail->next = list1;
            tail = tail->next;
            list1 = list1->next;
        }
        else if (list1->data == list2->data) {
            tail->next = list1;
            tail = tail->next;
            Node* temp = list2;
            list1 = list1->next;
            list2 = list2->next;
            delete temp;
        }
        else {
            tail->next = list2;
            tail = tail->next;
            list2 = list2->next;
        }
    }

    if (list1 != 0) {
        tail->next = list1;
    }

    if (list2 != 0) {
        tail->next = list2;
    }

    return head;
}

int main() {
    
    Node list1, list2;
    add(&list1, new Node(1));
    add(&list1, new Node(2));
    add(&list1, new Node(3));
    add(&list1, new Node(4));
    add(&list1, new Node(5));
    add(&list2, new Node(3));
    add(&list2, new Node(5));
    add(&list2, new Node(7));
    add(&list2, new Node(8));
    add(&list2, new Node(9));
    display(&list1);
    display(&list2);
    Node* combined = combine(&list2, &list1);
    display(combined);
    clear(combined);
    return 0;
}

在这里插入图片描述
2. 将两个非递减的有序链表合并为一个非递增的有序链表。要求结果链表仍使用原来两个链表的存储空间,不另外占用存储空间。表中允许有重复的数据。

#include <iostream>
#include <string>
#include <iomanip>

using namespace std;

class Node {
public:
    int data;
    Node* next;
    Node(int data = 0, Node* next = 0): data(data), next(0) {
    }
};

void add(Node* head, Node* node) {
    for (Node* i = head; i != 0; i = i->next) {
        if (i->next == 0) {
            i->next = node;
            break;
        }
    }
}

void clear(Node* head) {
    while (head->next != 0) {
        Node* temp = head->next;
        head->next = head->next->next;
        delete temp;
    }
}

void display(Node* head) {
    head = head->next;
    while (head != 0) {
        cout << head->data << " ";
        head = head->next;
    }
    cout << endl;
}

Node* combine(Node* list1, Node* list2) {
    Node* head = list1;
    Node* tail = list1;
    list1 = list1->next;
    list2 = list2->next;
    while (list1 != 0 && list2 != 0)
    {
        if (list1->data <= list2->data) {
            tail->next = list1;
            tail = tail->next;
            list1 = list1->next;
        }
        else {
            tail->next = list2;
            tail = tail->next;
            list2 = list2->next;
        }
    }

    if (list1 != 0) {
        tail->next = list1;
    }

    if (list2 != 0) {
        tail->next = list2;
    }

    return head;
}

void reverse(Node* head) {
    Node* lastItem = 0;
    for (Node* i = head->next; i != 0; ) {
        Node* temp = i;
        i = i->next;
        if (temp->next == 0) {
            head->next = temp;
        }
        temp->next = lastItem;
        lastItem = temp;
    }
}

int main() {
    Node list1, list2;
    add(&list1, new Node(1));
    add(&list1, new Node(2));
    add(&list1, new Node(3));
    add(&list1, new Node(4));
    add(&list1, new Node(5));
    add(&list2, new Node(3));
    add(&list2, new Node(5));
    add(&list2, new Node(7));
    add(&list2, new Node(8));
    add(&list2, new Node(9));
    display(&list1);
    display(&list2);
    Node* combined = combine(&list2, &list1);
    reverse(combined);
    display(combined);
    clear(combined);
    return 0;
}

在这里插入图片描述
3. 已知链表A和B分表表示两个集合,其元素递增排列。请设计一个算法,用于求出A和B交集并存放在A链表中。

#include <iostream>
#include <string>
#include <iomanip>

using namespace std;

class Node {
public:
    int data;
    Node* next;
    Node(int data = 0, Node* next = 0): data(data), next(0) {
    }
};

void add(Node* head, Node* node) {
    for (Node* i = head; i != 0; i = i->next) {
        if (i->next == 0) {
            i->next = node;
            break;
        }
    }
}

void clear(Node* head) {
    while (head->next != 0) {
        Node* temp = head->next;
        head->next = head->next->next;
        delete temp;
    }
}

void display(Node* head) {
    head = head->next;
    while (head != 0) {
        cout << head->data << " ";
        head = head->next;
    }
    cout << endl;
}

void intersect(Node* list1, Node* list2) {
    Node* p1 = list1->next;
    Node* p2 = list2->next;
    while (p1 != 0 && p2 != 0)
    {
        if (p1->data < p2->data) {
            Node* temp = p1;
            p1 = p1->next;
            delete temp;
        }
        else if (p1->data > p2->data) {
            p2 = p2->next;
        }
        else {
            list1->next = p1;
            list1 = list1->next;
            p1 = p1->next;
            p2 = p2->next;
        }
    }
    list1->next = 0;
}

int main() {
    Node list1, list2;
    add(&list1, new Node(1));
    add(&list1, new Node(2));
    add(&list1, new Node(3));
    add(&list1, new Node(4));
    add(&list1, new Node(5));
    add(&list2, new Node(3));
    add(&list2, new Node(5));
    add(&list2, new Node(7));
    add(&list2, new Node(8));
    add(&list2, new Node(9));
    display(&list1);
    display(&list2);
    intersect(&list2, &list1);
    display(&list2);
    clear(&list1);
    clear(&list2);
    return 0;
}


在这里插入图片描述
4.已知链表A和B分表表示两个集合,其元素递增排列。请设计算法求出两个集合A和B的差集(即仅由在A中出现而不在B中出现的的元素所构成的集合),并以同样的形式存储,同时返回该集合元素的个数。

#include <iostream>
#include <string>
#include <iomanip>

using namespace std;

class Node {
public:
    int data;
    Node* next;
    Node(int data = 0, Node* next = 0): data(data), next(0) {
    }
};

void add(Node* head, Node* node) {
    for (Node* i = head; i != 0; i = i->next) {
        if (i->next == 0) {
            i->next = node;
            break;
        }
    }
}

void clear(Node* head) {
    while (head->next != 0) {
        Node* temp = head->next;
        head->next = head->next->next;
        delete temp;
    }
}

void display(Node* head) {
    head = head->next;
    while (head != 0) {
        cout << head->data << " ";
        head = head->next;
    }
    cout << endl;
}

int substract(Node* list1, Node* list2) {
    Node* p1 = list1->next;
    Node* p2 = list2->next;
    int count = 0;
    while (p1 != 0 && p2 != 0)
    {
        if (p1->data < p2->data) {
            list1->next = p1;
            list1 = list1->next;
            count++;
            p1 = p1->next;
        }
        else if (p1->data > p2->data) {
            p2 = p2->next;
        }
        else {
            Node* temp = p1;
            p1 = p1->next;
            p2 = p2->next;
            delete temp;
        }
    }
    while (p1 != 0)
    {
        list1->next = p1;
        list1 = list1->next;
        p1 = p1->next;
        count++;
    }
    list1->next = 0;
    return count;
}

int main() {
    Node list1, list2;
    add(&list1, new Node(1));
    add(&list1, new Node(2));
    add(&list1, new Node(3));
    add(&list1, new Node(4));
    add(&list1, new Node(5));
    add(&list2, new Node(3));
    add(&list2, new Node(5));
    add(&list2, new Node(7));
    add(&list2, new Node(8));
    add(&list2, new Node(9));
    display(&list1);
    display(&list2);
    int count = substract(&list2, &list1);
    display(&list2);
    cout << "remain size: " << count << endl;
    clear(&list1);
    clear(&list2);
    return 0;
}


在这里插入图片描述
5. 设计算法将一个带头结点的单链表A分解为两个具有相同结构的链表B和C,其中B表的结点为A表中值小于0的结点,而C表的结点为A表中值大于0的结点(链表A中的元素为非0整数,要求B、C表利用A表的结点)。

#include <iostream>
#include <string>
#include <iomanip>

using namespace std;

class Node {
public:
    int data;
    Node* next;
    Node(int data = 0, Node* next = 0): data(data), next(0) {
    }
};

void add(Node* head, Node* node) {
    for (Node* i = head; i != 0; i = i->next) {
        if (i->next == 0) {
            i->next = node;
            break;
        }
    }
}

void clear(Node* head) {
    while (head->next != 0) {
        Node* temp = head->next;
        head->next = head->next->next;
        delete temp;
    }
}

void display(Node* head) {
    head = head->next;
    while (head != 0) {
        cout << head->data << " ";
        head = head->next;
    }
    cout << endl;
}

void split(Node* head, Node* list1, Node* list2) {
    for (Node* i = head->next; i != 0; i = i->next)
    {
        if (i->data < 0) {
            list1->next = i;
            list1 = list1->next;
        }
        else {
            list2->next = i;
            list2 = list2->next;
        }
    }
    head->next = 0;
    list1->next = 0;
    list2->next = 0;
}

int main() {
    Node head, list1, list2;
    add(&head, new Node(-1));
    add(&head, new Node(5));
    add(&head, new Node(-2));
    add(&head, new Node(6));
    add(&head, new Node(-3));
    add(&head, new Node(7));
    add(&head, new Node(-4));
    display(&head);
    split(&head, &list1, &list2);
    display(&list1);
    display(&list2);
    clear(&list1);
    clear(&list2);
    return 0;
}

在这里插入图片描述

  1. 设计一个算法,通过一趟遍历确定长度为n的单链表中值最大的结点,返回该结点的数据域。
#include <iostream>
#include <string>
#include <iomanip>

using namespace std;

class Node {
public:
    int data;
    Node* next;
    Node(int data = 0, Node* next = 0): data(data), next(0) {
    }
};

void add(Node* head, Node* node) {
    for (Node* i = head; i != 0; i = i->next) {
        if (i->next == 0) {
            i->next = node;
            break;
        }
    }
}

void clear(Node* head) {
    while (head->next != 0) {
        Node* temp = head->next;
        head->next = head->next->next;
        delete temp;
    }
}

void display(Node* head) {
    head = head->next;
    while (head != 0) {
        cout << head->data << " ";
        head = head->next;
    }
    cout << endl;
}

int max(Node* head) {
    head = head->next;
    int maxValue = head->data;
    while (head != 0)
    {
        if (head->data > maxValue) {
            maxValue = head->data;
        }
        head = head->next;
    }
    return maxValue;
}

int main() {
    Node head;
    add(&head, new Node(-1));
    add(&head, new Node(5));
    add(&head, new Node(-2));
    add(&head, new Node(6));
    add(&head, new Node(-3));
    add(&head, new Node(7));
    add(&head, new Node(-4));
    display(&head);
    cout << "max in it: " << max(&head) << endl;
    clear(&head);
    return 0;
}


在这里插入图片描述
7. 设计一个算法,将链表中所有结点中的链接方向原地逆转,即要求利用原表中的存储空间,换句话说,要求算法的空间复杂度为O(1)。

#include <iostream>
#include <string>
#include <iomanip>

using namespace std;

class Node {
public:
    int data;
    Node* next;
    Node(int data = 0, Node* next = 0): data(data), next(0) {
    }
};

void add(Node* head, Node* node) {
    for (Node* i = head; i != 0; i = i->next) {
        if (i->next == 0) {
            i->next = node;
            break;
        }
    }
}

void clear(Node* head) {
    while (head->next != 0) {
        Node* temp = head->next;
        head->next = head->next->next;
        delete temp;
    }
}

void display(Node* head) {
    head = head->next;
    while (head != 0) {
        cout << head->data << " ";
        head = head->next;
    }
    cout << endl;
}

void reverse(Node* head) {
    Node* last = 0;
    Node* curr = head->next;
    while (curr != 0) {
        Node* temp = curr;
        curr = curr->next;
        temp->next = last;
        last = temp;
        if (curr == 0) {
            head->next = temp;
        }
    }

}

int main() {
    Node head;
    add(&head, new Node(-1));
    add(&head, new Node(5));
    add(&head, new Node(-2));
    add(&head, new Node(6));
    add(&head, new Node(-3));
    add(&head, new Node(7));
    add(&head, new Node(-4));
    display(&head);
    reverse(&head);
    display(&head);
    clear(&head);
    return 0;
}


在这里插入图片描述

8.设计一个算法,删除递增有序链表中值大于mink且小于maxk(mink和maxk是给定的两个参数,其值可以和表中的元素相同,也可以不同)的所用元素。

#include <iostream>
#include <string>
#include <iomanip>

using namespace std;

class Node {
public:
    int data;
    Node* next;
    Node(int data = 0, Node* next = 0): data(data), next(0) {
    }
};

void add(Node* head, Node* node) {
    for (Node* i = head; i != 0; i = i->next) {
        if (i->next == 0) {
            i->next = node;
            break;
        }
    }
}

void clear(Node* head) {
    while (head->next != 0) {
        Node* temp = head->next;
        head->next = head->next->next;
        delete temp;
    }
}

void display(Node* head) {
    head = head->next;
    while (head != 0) {
        cout << head->data << " ";
        head = head->next;
    }
    cout << endl;
}

void removeBetween(Node* head, int mink, int maxk) {
    while (head->next != 0)
    {
        if (head->next->data > mink&& head->next->data < maxk) {
            Node* temp = head->next;
            head->next = head->next->next;
            delete temp;
            continue;
        }

        head = head->next;
    }
}

int main() {
    Node head;
    add(&head, new Node(1));
    add(&head, new Node(5));
    add(&head, new Node(10));
    add(&head, new Node(16));
    add(&head, new Node(29));
    add(&head, new Node(50));
    add(&head, new Node(1000));
    display(&head);
    removeBetween(&head, 10, 51);
    display(&head);
    clear(&head);
    return 0;
}


在这里插入图片描述
9.已知p指向双向循环链表中的一个结点,基结点结构为data、prior、next三个域,写出算法Exchange§,交换p所指向的结点及其前驱结点的的顺序。


#include <iostream>
#include <string>
#include <iomanip>

using namespace std;

class Node {
public:
    int data;
    Node* prior;
    Node* next;
    Node(int data = 0) : data(data) {
        this->prior = this;
        this->next = this;
    }
};

void add(Node* head, Node* node) {
    Node* before = head->prior;
    Node* after = head;
    node->prior = before;
    node->next = after;
    before->next = node;
    after->prior = node;
}

void clear(Node* head) {
    while (head->next != head)
    {
        Node* temp = head->next;
        Node* before = head;
        Node* after = head->next->next;
        delete temp;
        before->next = after;
        after->prior = before;
    }
}

void display(Node* head) {
    Node* curr = head->next;
    while (curr != head)
    {
        cout << curr->data << " ";
        curr = curr->next;
    }
    cout << " <> ";
    Node* curb = head->prior;
    while (curb != head)
    {
        cout << curb->data << " ";
        curb = curb->prior;
    }
    cout << endl;
}


void moveForward(Node* head, Node* node) {
    //drop
    node->prior->next = node->next;
    node->next->prior = node->prior;
    //insert
    node->prior = node->prior->prior;
    node->next = node->next->prior;
    node->prior->next = node;
    node->next->prior = node;
}

int main() {
    Node head;
    add(&head, new Node(1));
    add(&head, new Node(3));
    Node* five = new Node(5);
    add(&head, five);
    add(&head, new Node(7));
    add(&head, new Node(9));
    display(&head);
    moveForward(&head, five);
    display(&head);
    clear(&head);
    return 0;
}

在这里插入图片描述

10.已知长度为n的经线性表A采用顺序存储结构,请写出时间复杂度为O(n),空间复杂度为O(1)的算法,该算法可以删除线性表中所有值为item的数据元素。

#include <iostream>
#include <string>
#include <iomanip>
#include <array>
using namespace std;

void remove(int table[], int& size, int k) {
    int count = 0;
    for (int i = 0; i < size; i++) {
        if (table[i] == k) {
            count++;
        }
        else {
            table[i - count] = table[i];
        }
    }
    size -= count;
}

void display(int table[], int size) {
    for (int i = 0; i < size; i++) {
        cout << table[i] << " ";
    }
    cout << endl;
}

int main() {
    
    int table[] = { 1, 3, 5, 7, 9, 7, 3, 2, 4, 3, 7, 6 };
    int size = 12;
    display(table, size);
    remove(table, size, 7);
    display(table, size);
    return 0;
}


在这里插入图片描述

  • 0
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值