第4章-链式存储基础(2020.03.26)

第4章-链式存储基础

文章目录

    • 第4章-链式存储基础
        • (课堂练习)单链表的创建与输出【简单】
        • 1. 单链表的下标访问【简单】
        • 2. 单链表的指定值插入【简单】
        • 3. 删除单链表的指定值【简单】
        • 4. 约瑟夫问题【中等】
        • 5. 链表置逆【中等】
        • 6. 删除链表中的重复元素【中等】

(课堂练习)单链表的创建与输出【简单】

(单链表的创建与输出)请用链表的形式存储用户输入的n个整数。要求使用堆内存,注意内存的分配和释放。
【输入】第一行整数n,第二行n个整数
【输出】n个整数之和
例如:
【输入】
5
3 6 9 10 1
【输出】
29

#include 
#include 
using namespace std;

struct node
{
    int data;
    node *next;
    node();
    node(int item, node *add_on = NULL);
};

int main()
{
    int n,num;
    cin >> n;
    node *head = new node();
    node *p = head;
    while(n--){
        cin >>num;
        node *pNewnode = new node(num);
        p->next = pNewnode;
        p = pNewnode;
    }

    p = head;
    int sum = 0;
    while(p->next != NULL){
        sum += (p->next)->data;
        p = p->next;
    }
    cout << sum;

    node *pmove;
    while(head->next != NULL){
        pmove = head;
        head = pmove->next;
        delete(pmove);
    }
}

node::node()
{
    next = NULL;
}

node::node(int item, node *add_on)
{
    data = item;
    next = add_on;
}

1. 单链表的下标访问【简单】

(单链表的下标访问)请编写程序输出单链表中对应于下标i到下标j之间的数据。
【输入】第一行整数n(1<=n)
第二行n个整数
第三行i的值 j的值(i和j为合法下标,j >= i)
【输出】下标i到j之间的数值
例如:
【输入】
5
3 6 9 10 1
0 2
【输出】
3 6 9

#include 
#include 
using namespace std;

struct Node
{
    int data;
    Node* next;
    Node();
    Node(int item, Node* add_on = NULL);
};

int main()
{
    int n, num, i, j;
    cin >> n;
    Node* head = new Node();
    Node* cur = head;
    for (i = 0; i < n; i++) {
        cin >> num;
        Node* newptr = new Node(num);
        cur->next = newptr;
        cur = newptr;
    }
    cin >> i >> j;

    int cnt = 0;
    cur = head->next;
    while (1)
    {
        if (cnt >= i && cnt <= j) {
            cout << cur->data << ' ';
            cur = cur->next;
            if (cnt == j) break;
            cnt++;
        }
        else {
            cur = cur->next;
            cnt++;
        }
    }

    while (head != NULL) {
        cur = head;
        head = head->next;
        delete (cur);
    }


    return 0;
}

Node::Node()
{
    next = NULL;
}

Node::Node(int item, Node* add_on)
{
    data = item;
    next = add_on;
}

2. 单链表的指定值插入【简单】

(单链表的指定值插入)请编写程序在单链表的值为x的元素之后均插入值为y的元素,并输出所有的插入位置。
【输入】第一行整数n(1<=n)
第二行为单链表中的n个整数
第三行 x(x在单链表中存在)y要插入的整数,x和y均为int类型,且不相等
【输出】y插入在单链表中的下标位置
例如:
【输入】
5
3 6 9 10 1
6 7 //在所有的数字6后面插入数字7
【输出】
2 //7插入后的位置
【输入】
5
3 6 9 6 1
6 7 //在所有的数字6后面插入数字7
【输出】
2 5 //7插入后的位置

#include 
#include 
using namespace std;

struct Node
{
    int data;
    Node* next;
    Node();
    Node(int item, Node* add_on = NULL);
};

int main()
{
    int n, num, x, y;
    cin >> n;
    Node* head = new Node();
    Node* cur = head;
    while (n--) {
        cin >> num;
        Node* newptr = new Node(num);
        cur->next = newptr;
        cur = newptr;
    }

    cin >> x >> y;
    Node* prev = head->next;
    int cnt = 0;
    while (prev != NULL)
    {
        if (prev->data == x) {
            Node* newptr = new Node(y, prev->next);
            prev->next = newptr;
            cout << cnt + 1 << ' ';
        }
        prev = prev->next;
        cnt++;
    }

    while (head != NULL) {
        cur = head;
        head = head->next;
        delete (cur);
    }
    return 0;
}

Node::Node()
{
    next = NULL;
}

Node::Node(int item, Node* add_on)
{
    data = item;
    next = add_on;
}

3. 删除单链表的指定值【简单】

(删除单链表的指定值)请编写程序删除单链表中所有值为x的元素。并输出删除x后的链表信息。
【输入】第一行整数n(1<=n)
第二行为单链表中的n个整数
第三行 x,x为int类型
【输出】删除x后的单链表信息
例如:
【输入】
6
3 6 9 10 6 1
6
【输出】
3 9 10 1

#include 
#include 
using namespace std;

struct Node
{
    int data;
    Node* next;
    Node();
    Node(int item, Node* add_on = NULL);
};

int main()
{
    int n, num, x;
    cin >> n;
    Node* head = new Node();
    Node* cur = head;
    while (n--) {
        cin >> num;
        Node* newptr = new Node(num);
        cur->next = newptr;
        cur = newptr;
    }
    cin >> x;

    cur = head;
    while (cur->next != NULL) {
        if (cur->next->data == x) {
            Node* temp = cur->next;
            cur->next = temp->next;
            delete temp;
        }
        else {
            cur = cur->next;
        }
    }

    cur = head->next;
    while (cur != NULL) {
        cout << cur->data << ' ';
        cur = cur->next;
    }

    while (head != NULL) {
        cur = head;
        head = head->next;
        delete (cur);
    }
    return 0;
}

Node::Node()
{
    next = NULL;
}

Node::Node(int item, Node* add_on)
{
    data = item;
    next = add_on;
}

4. 约瑟夫问题【中等】

(约瑟夫问题)n 个人围成一个圆圈,首先第1个人从1开始一个人一个人顺时针报数, 报到第m个人,令其出列。然后再从下一个人开始,从1顺时针报数,报到第m个人,再令其出列,…,如此下去, 直到圆圈中只剩一个人为止。此人即为优胜者。请用环形链表实现约瑟夫问题。
【输入】n(2<=n<=60) m(1<=m)
【输出】最后的胜利者编号(编号范围是1至n)
例如:
【输入】
8 3
【输出】
7

#include 
#include 
using namespace std;

struct Node
{
    int data;
    Node* next;
    Node();
    Node(int item, Node* add_on = NULL);
};

int main()
{
    int n, m, cnt;
    cin >> n;
    Node* head = new Node();
    Node* cur = head;
    for (int i = 1; i <= n - 1; i++) {
        cur->data = i;
        Node* temp = new Node();
        cur->next = temp;
        cur = temp;
    }
    Node* prev = cur;
    cur->data = n;
    cur->next = head;

    cin >> m;
    cnt = 1;
    cur = head;
    while (n > 1) {
        while (cnt != m) {
            prev = prev->next;
            cur = cur->next;
            cnt++;
        }
        if (cnt == m) {
            cnt = 1;
            prev->next = cur->next;
            delete cur;
            cur = prev->next;
            n--;
        }
    }
    cout << prev->data;
    delete prev;
    return 0;
}

   /*值得借鉴
    Node* temp;
    cur = prev;//即head的前一个
    //删除n-1次,留下一个人
    for (int i = 1; i < n; i++)
    {
        for (int j = 1; j < m; j++)
        //执行m-1次,把游走指针停在要删除的位值的前一个
            cur = cur->next;
        temp = cur->next;
        cur->next = temp->next;//注意,cur还是保持不变
        delete temp;
    }
    */

Node::Node()
{
    next = NULL;
}

Node::Node(int item, Node* add_on)
{
    data = item;
    next = add_on;
}

5. 链表置逆【中等】

(有个同学写的可好了,就是没记全,好可惜,我太懒了QAQ)
(链表置逆)设有一个表头指针为h的单链表。试设计一个算法,通过遍历一趟链表,将链表中所有结点的链接方向逆转。要求逆转结果链表的表头指针h指向原链表的最后一个结点。
【输入】第一行整数n(1<=n)
第二行为单链表中的n个整数
【输出】置逆后的单链表信息
例如:
【输入】
6
3 6 9 10 6 1
【输出】
1 6 10 9 6 3

#include 
#include 
using namespace std;

struct Node
{
    int data;
    Node* next;
    Node();
    Node(int item, Node* add_on = NULL);
};

int main()
{
    int n, num;
    cin >> n;
    Node* head = new Node();
    Node* cur = head;
    while (n--) {
        cin >> num;
        Node* newptr = new Node(num);
        cur->next = newptr;
        cur = newptr;
    }

    cur = head->next;
    head->next = NULL;
    while (cur != NULL) {
        Node* temp = cur->next;
        cur->next = head->next;
        head->next = cur;//每次都更新最前面的位置
        cur = temp;
    }

    /*值得借鉴
    void inverse(Node*&head)
    {
       cur = head;
       prev = NULL;
       while (cur != NULL) {
           Node* temp = cur->next;
           cur->next = prev;
           prev = cur;
           cur = temp;
       }
       head = prev;//最后指向最前面的位置
    }
    */
    

    cur = head->next;
    while (cur != NULL) {
        cout << cur->data << ' ';
        cur = cur->next;
    }

    while (head != NULL) {
        cur = head;
        head = head->next;
        delete (cur);
    }
    return 0;
}

Node::Node()
{
    next = NULL;
}

Node::Node(int item, Node* add_on)
{
    data = item;
    next = add_on;
}

6. 删除链表中的重复元素【中等】

(删除链表中的重复元素)请编写程序删除链表中的多余节点,即:若链表中有多个节点具有相同的值,则只保留其中的一个节点即可,使得处理后的链表中的值各不相同。
【输入】第一行整数n(1<=n)
第二行为单链表中的n个整数
【输出】删除链表中的重复元素后的单链表信息
例如:
【输入】
9
3 6 9 10 6 1 3 10 6
【输出】
3 6 9 10 1

#include 
#include 
using namespace std;

struct Node
{
    int data;
    Node* next;
    Node();
    Node(int item, Node* add_on = NULL);
};

int main()
{
    int n, num;
    cin >> n;
    Node* head = new Node();
    Node* cur = head;
    while (n--) {
        cin >> num;
        Node* newptr = new Node(num);
        cur->next = newptr;
        cur = newptr;
    }

    Node* prev = head->next;
    while (prev != NULL) {
        cur = prev;
        while (cur->next != NULL) {
            if (prev->data == cur->next->data) {
                Node* temp = cur->next;
                cur->next = temp->next;
                delete temp;
            }
            else {
                cur = cur->next;
            }
        }
        prev = prev->next;
    }

    cur = head->next;
    while (cur != NULL) {
        cout << cur->data << ' ';
        cur = cur->next;
    }

    while (head != NULL) {
        cur = head;
        head = head->next;
        delete (cur);
    }
    return 0;
}

Node::Node()
{
    next = NULL;
}

Node::Node(int item, Node* add_on)
{
    data = item;
    next = add_on;
}

你可能感兴趣的:(20春数据结构与算法(C++))