BJFU实验一链表部分题解整合

目录

题目传送门

214、基于链式存储结构的图书信息表的创建和输出

描述

定义一个包含图书信息(书号、书名、价格)的链表,读入相应的图书数据来完成图书信息表的创建,然后统计图书表中的图书个数,同时逐行输出每本图书的信息。

输入

输入n+1行,其中前n行是n本图书的信息(书号、书名、价格),每本图书信息占一行,书号、书名、价格用空格分隔,价格之后没有空格。最后第n+1行是输入结束标志:0 0 0(空格分隔的三个0)。其中书号和书名为字符串类型,价格为浮点数类型。

输出

总计n+1行,第1行是所创建的图书表中的图书个数,后n行是n本图书的信息(书号、书名、价格),每本图书信息占一行,书号、书名、价格用空格分隔。其中价格输出保留两位小数。

输入样例 1
9787302257646 Data-Structure 35.00
9787302164340 Operating-System 50.00
9787302219972 Software-Engineer 32.00
9787302203513 Database-Principles 36.00
9787810827430 Discrete-Mathematics 36.00
9787302257800 Data-Structure 62.00
9787811234923 Compiler-Principles 62.00
9787822234110 The-C-Programming-Language 38.00
0 0 0
输出样例 1
8
9787302257646 Data-Structure 35.00
9787302164340 Operating-System 50.00
9787302219972 Software-Engineer 32.00
9787302203513 Database-Principles 36.00
9787810827430 Discrete-Mathematics 36.00
9787302257800 Data-Structure 62.00
9787811234923 Compiler-Principles 62.00
9787822234110 The-C-Programming-Language 38.00
AC 代码

前插法:

#include <iostream>
#include <algorithm>

using namespace std;

struct Book // 创建书类数据类型
{
    
    
    string ibsn;
    string name;
    double price;
};

typedef struct LNode // 创建结点类型
{
    
    
    Book data;
    struct LNode *next;
}LNode, *LinkList;

bool InitList(LinkList &L) // 注意这里的参数等价于LNode * &L,返回值为bool值表示状态
{
    
    
    L = new LNode;
    L -> next = NULL;
    return true; // 表示初始化成功
}

int main()
{
    
    
    // 1、创建一个链表(先创建一个头结点),用LinkList用来强调这是一个链表
    LinkList L; 
    
    // 2、初始化链表
    InitList(L);
    
    // 3、前插法创建单链表(注意创建完后是倒序)
    int cnt = 0;
    while (1)
    {
    
    
        LNode *tmp1;
        tmp1 = new LNode;
        cin >> tmp1 -> data.ibsn >> tmp1 -> data.name >> tmp1 -> data.price;
        
        if (tmp1 -> data.price == 0) break;
        
        tmp1 -> next = L -> next;
        L -> next = tmp1;
        
        cnt ++;
    }
    
    cout << cnt << endl;
    // 4、循环倒序输出
    while (cnt --)
    {
    
    
        LNode *tmp2;
        tmp2 = new LNode;
        tmp2 = L -> next;
        for (int i = 0; i < cnt; i ++) // 注意是循环cnt次,目的是使得指针最后指向尾结点
            tmp2 = tmp2 -> next;
        
        cout << tmp2 -> data.ibsn << " " << tmp2 -> data.name << " ";
        printf("%.2lf\n", tmp2 -> data.price);
    }
    
    return 0;
}

尾插法:

AC 代码
#include <iostream>
#include <algorithm>

using namespace std;

struct Book // 创建书类数据类型
{
    
    
    string ibsn;
    string name;
    double price;
};

typedef struct LNode // 创建结点类型
{
    
    
    Book data;
    struct LNode *next;
}LNode, *LinkList;

bool InitList(LinkList &L) // 注意这里的参数等价于LNode * &L,返回值为bool值表示状态
{
    
    
    L = new LNode;
    L -> next = NULL;
    return true; // 表示初始化成功
}

int main()
{
    
    
    // 1、创建一个链表(先创建一个头结点),用LinkList用来强调这是一个链表
    LinkList L; 
    
    // 2、初始化链表
    InitList(L);
    
    // 3、尾插法创建单链表(注意创建完后是正序)
    int cnt = 0;
    
    LNode *r; // 创建尾指针
    r = new LNode;
    r = L;
    while (1)
    {
    
    
        LNode *tmp1; // 创建临时结点
        tmp1 = new LNode;
        
        cin >> tmp1 -> data.ibsn >> tmp1 -> data.name >> tmp1 -> data.price;
        
        if (tmp1 -> data.price == 0) break;
        
        tmp1 -> next = NULL;
        r -> next = tmp1;
        r = tmp1;

        cnt ++;
    }
    
    cout << cnt << endl;

    LNode *tmp2; // 创建输出使用的临时指针
    tmp2 = new LNode;
    tmp2 = L -> next;
    
    // 4、正序输出
	while(tmp2 != r -> next) // 注意,是遍历到r -> next,即尾结点后面那个结点,因为tmp2 = tmp2 -> next 在cout语句后面
	{
    
    
		cout << tmp2 -> data.ibsn << " " << tmp2 -> data.name << " ";
        printf("%.2lf\n", tmp2 -> data.price);
		tmp2 = tmp2 -> next;
	}
    
    return 0;
}

215、基于链式存储结构的图书信息表的排序

描述

定义一个包含图书信息(书号、书名、价格)的链表,读入相应的图书数据来完成图书信息表的创建,然后统计图书表中的图书个数,同时逐行输出每本图书的信息。

输入

输入n+1行,其中前n行是n本图书的信息(书号、书名、价格),每本图书信息占一行,书号、书名、价格用空格分隔,价格之后没有空格。最后第n+1行是输入结束标志:0 0 0(空格分隔的三个0)。其中书号和书名为字符串类型,价格为浮点数类型。

输出

总计n+1行,第1行是所创建的图书表中的图书个数,后n行是n本图书的信息(书号、书名、价格),每本图书信息占一行,书号、书名、价格用空格分隔。其中价格输出保留两位小数。

输入样例 1
9787302257646 Data-Structure 35.00
9787302164340 Operating-System 50.00
9787302219972 Software-Engineer 32.00
9787302203513 Database-Principles 36.00
9787810827430 Discrete-Mathematics 36.00
9787302257800 Data-Structure 62.00
9787811234923 Compiler-Principles 62.00
9787822234110 The-C-Programming-Language 38.00
0 0 0
输出样例 1
9787302257800 Data-Structure 62.00
9787811234923 Compiler-Principles 62.00
9787302164340 Operating-System 50.00
9787822234110 The-C-Programming-Language 38.00
9787302203513 Database-Principles 36.00
9787810827430 Discrete-Mathematics 36.00
9787302257646 Data-Structure 35.00
9787302219972 Software-Engineer 32.00
AC 代码
#include <iostream>

using namespace std;

struct Book // 创建书类数据结构
{
    
    
    string ibsn;
    string name;
    double price;
};

typedef struct LNode // 创建结点
{
    
    
    Book data;
    struct LNode *next;
}LNode, *LinkList;

// 初始化函数,通过头结点指向空
bool InitList(LinkList &L)
{
    
    
    L = new LNode;
    L -> next = NULL;
    return true;
}

// 尾插法创建链表函数
void createList_tail(LinkList &L, int &cnt)
{
    
    
    LNode *r; // 创建尾指针,使得尾指针一开始指向头结点
    r = new LNode;
    r = L;
    

    while (1)
    {
    
    
        LNode *tmp1; // 创建一个临时结点
        tmp1 = new LNode;
        cin >> tmp1 -> data.ibsn >> tmp1 -> data.name >> tmp1 -> data.price;
        
        if (tmp1 -> data.price == 0) break;
        
        tmp1 -> next = NULL;
        r -> next = tmp1;
        r = tmp1;
        
        cnt ++;
    }
}

// 输出函数
void show(LinkList L)
{
    
    
    LNode *tmp2;
    tmp2 = new LNode;
    tmp2 = L -> next;
    
    while (tmp2)
    {
    
    
        cout << tmp2 -> data.ibsn << " " << tmp2 -> data.name << " ";
        printf("%.2lf\n", tmp2 -> data.price);
        tmp2 = tmp2 -> next;
    }
}

// 降序的冒泡排序
void listSort(LinkList &L, int cnt)
{
    
    
    LNode *tmp3;
    
    for (int i = 0; i < cnt; i ++)
    {
    
    
        int j = 0;
        tmp3 = L -> next; // 由于第一个结点是最大的,因此,每次冒泡排序的开始都应该是从头开始
        
        while (tmp3 && j < cnt -i - 1)
        {
    
    
            if (tmp3 -> data.price < tmp3 -> next -> data.price)
            {
    
    
                Book t = tmp3 -> data;
                tmp3 -> data = tmp3 -> next -> data;
                tmp3 -> next -> data = t;
            }
            
            j ++;
            
            tmp3 = tmp3 -> next;
        }
    }
}

int main()
{
    
    
    // 1、创建链表(通过创建一个头结点)并初始化
    LinkList L;
    InitList(L);
    
    // 2、利用尾插法进行创建一个链表(注意是正序输出)
    int cnt = 0;
    createList_tail(L, cnt);
    
    // 3、进行排序,利用双指针的冒泡排序
    listSort(L, cnt);
    
    // // 4、进行正序输出
    show(L);
    
    return 0;
}

216、基于链式存储结构的图书信息表的修改

描述

定义一个包含图书信息(书号、书名、价格)的链表,读入相应的图书数据来完成图书信息表的创建,然后统计图书表中的图书个数,同时逐行输出每本图书的信息。

输入

输入n+1行,前n行是n本图书的信息(书号、书名、价格),每本图书信息占一行,书号、书名、价格用空格分隔,价格之后没有空格。最后第n+1行是输入结束标志:0 0 0(空格分隔的三个0)。其中书号和书名为字符串类型,价格为浮点数类型。

输出

总计n+1行,第1行是修改前所有图书的平均价格,后n行是价格修改后n本图书的信息,每本图书信息占一行,书号、书名、价格用空格分隔。其中价格输出保留两位小数。

输入样例 1
9787302257646 Data-Structure 35.00
9787302164340 Operating-System 50.00
9787302219972 Software-Engineer 32.00
9787302203513 Database-Principles 36.00
9787810827430 Discrete-Mathematics 36.00
9787302257800 Data-Structure 62.00
9787811234923 Compiler-Principles 62.00
9787822234110 The-C-Programming-Language 38.00
0 0 0
输出样例 1
43.88
9787302257646 Data-Structure 42.00
9787302164340 Operating-System 55.00
9787302219972 Software-Engineer 38.40
9787302203513 Database-Principles 43.20
9787810827430 Discrete-Mathematics 43.20
9787302257800 Data-Structure 68.20
9787811234923 Compiler-Principles 68.20
9787822234110 The-C-Programming-Language 45.60
AC 代码
#include <iostream>

using namespace std;

struct Book // 建立书类数据结构
{
    
    
    string ibsn;
    string name;
    double price;
};

typedef struct LNode
{
    
    
    Book data;
    struct LNode *next;
}LNode, *LinkList;

// 初始化函数
bool InitList(LinkList &L)
{
    
    
    L = new LNode;
    L -> next = NULL;
    return true;
}

// 尾插法创建函数
void createList_tail(LinkList &L, int &len, double &sum) // len是指长度
{
    
    
    LNode *tail;
    tail = new LNode;
    tail = L;                               // 创建尾指针,一开始指向头结点
    
    while (1)
    {
    
    
        LNode *tmp;                         // 创建一个临时结点
        tmp = new LNode;
        
        cin >> tmp -> data.ibsn >> tmp -> data.name >> tmp -> data.price;
        
        if (tmp -> data.price == 0) break; // 情况特判
    
        sum += tmp -> data.price;           // 算出总价格
    
        tmp -> next = NULL;
        tail -> next = tmp;
        tail = tmp;
        
        len ++;
    }
}

// 改变价格函数
void changePrice(LinkList &L, double ave)
{
    
    
    LNode *p;
    p = new LNode;
    p = L;
    
    while (p)
    {
    
    
        if (p -> data.price < ave) p -> data.price *= 1.2;
        else p -> data.price *= 1.1;
        p = p -> next;
    }
}

// 输出函数
void show(LinkList L)
{
    
    
    LNode *tmp2;
    tmp2 = new LNode;
    tmp2 = L -> next;
    
    while (tmp2)
    {
    
    
        cout << tmp2 -> data.ibsn << " " << tmp2 -> data.name << " ";
        printf("%.2lf\n", tmp2 -> data.price);
        tmp2 = tmp2 -> next;
    }
}

int main()
{
    
    
    // 1、通过创建一个头结点创建链表
    LinkList L;
    
    // 2、通过将头结点指向NULL进行初始化
    InitList(L);

    // 3、利用尾插法建立链表
    int len = 0;
    double sum = 0;
    createList_tail(L, len, sum);
    
    // 4、按照题意改变价格
    double ave = sum / len;
    printf("%.2lf\n", ave);
    changePrice(L, ave);
    
    // 5、输出
    show(L);
    
    return 0;
}

217、基于链式存储结构的图书信息表的逆序存储

描述

定义一个包含图书信息(书号、书名、价格)的链表,读入相应的图书数据来完成图书信息表的创建,然后将读入的图书逆序存储,逐行输出逆序存储后每本图书的信息。

输入

输入n+1行,第一行是图书数目n,后n行是n本图书的信息(书号、书名、价格),每本图书信息占一行,书号、书名、价格用空格分隔,价格之后没有空格。其中书号和书名为字符串类型,价格为浮点数类型。

输出

总计n行,第i行是原有图书表中第n-i+1行的图书的信息(书号、书名、价格),每本图书信息占一行,书号、书名、价格用空格分隔。其中价格输出保留两位小数。

输入样例 1
8
9787302257646 Data-Structure 35.00
9787302164340 Operating-System 50.00
9787302219972 Software-Engineer 32.00
9787302203513 Database-Principles 36.00
9787810827430 Discrete-Mathematics 36.00
9787302257800 Data-Structure 62.00
9787811234923 Compiler-Principles 62.00
9787822234110 The-C-Programming-Language 38.00
输出样例 1
9787822234110 The-C-Programming-Language 38.00
9787811234923 Compiler-Principles 62.00
9787302257800 Data-Structure 62.00
9787810827430 Discrete-Mathematics 36.00
9787302203513 Database-Principles 36.00
9787302219972 Software-Engineer 32.00
9787302164340 Operating-System 50.00
9787302257646 Data-Structure 35.00
AC 代码
#include <iostream>

using namespace std;

struct Book // 建立书类数据结构
{
    
    
    string ibsn;
    string name;
    double price;
};

typedef struct LNode
{
    
    
    Book data;
    struct LNode *next;
}LNode, *LinkList;

// 初始化函数
bool InitList(LinkList &L)
{
    
    
    L = new LNode;
    L -> next = NULL;
    return true;
}

// 尾插法创建函数
void createList_tail(LinkList &L, int n) // len是指长度
{
    
    
    LNode *tail;
    tail = new LNode;
    tail = L;                           
    
    while (n --)
    {
    
    
        LNode *tmp;                         // 创建一个临时结点
        tmp = new LNode;
        
        cin >> tmp -> data.ibsn >> tmp -> data.name >> tmp -> data.price;
    
        tmp -> next = NULL;
        tail -> next = tmp;
        tail = tmp;
        
    }
}

// 输出函数
void show(LinkList L, int n)
{
    
    

    
    while (n --)
    {
    
    
        LNode *tmp2;
        tmp2 = new LNode;
        tmp2 = L -> next;
        
        for (int i = 0; i < n; i ++)
            tmp2 = tmp2 -> next;
        
        cout << tmp2 -> data.ibsn << " " << tmp2 -> data.name << " ";
        printf("%.2lf\n", tmp2 -> data.price);
    }
}

int main()
{
    
    
    // 1、通过创建一个头结点创建链表
    LinkList L;
    
    // 2、通过将头结点指向NULL进行初始化
    InitList(L);

    // 3、利用尾插法建立链表
    int n;
    cin >> n;
    createList_tail(L, n);
    
    // 4、按照题意改变价格
    // double ave = sum / len;
    // printf("%.2lf\n", ave);
    // changePrice(L, ave);
    
    // 5、逆序输出
    show(L, n);
    
    return 0;
}

218、基于链式存储结构的图书信息表的最贵图书的查找

描述

定义一个包含图书信息(书号、书名、价格)的链表,读入相应的图书数据来完成图书信息表的创建,然后查找价格最高的图书,输出相应图书的信息。

输入

总计输入n+1行,其中,第一行是图书数目n,后n行是n本图书的信息(书号、书名、价格),每本图书信息占一行,书号、书名、价格用空格分隔,价格之后没有空格。其中书号和书名为字符串类型,价格为浮点数类型。

输出

总计输出m+1行,其中,第一行是最贵图书数目(价格最高的图书可能有多本),后m行是最贵图书的信息(书号、书名、价格),每本图书信息占一行,书号、书名、价格用空格分隔,其中价格输出保留两位小数。

输入样例 1
8
9787302257646 Data-Structure 35.00
9787302164340 Operating-System 50.00
9787302219972 Software-Engineer 32.00
9787302203513 Database-Principles 36.00
9787810827430 Discrete-Mathematics 36.00
9787302257800 Data-Structure 62.00
9787811234923 Compiler-Principles 62.00
9787822234110 The-C-Programming-Language 38.00
输出样例 1
2
9787302257800 Data-Structure 62.00
9787811234923 Compiler-Principles 62.00
AC 代码
#include <iostream>

using namespace std;

struct Book // 建立书类数据结构
{
    
    
    string ibsn;
    string name;
    double price;
};

typedef struct LNode
{
    
    
    Book data;
    struct LNode *next;
}LNode, *LinkList;

// 初始化函数
bool InitList(LinkList &L)
{
    
    
    L = new LNode;
    L -> next = NULL;
    return true;
}

// 尾插法创建函数
void createList_tail(LinkList &L, int n) 
{
    
    
    LNode *tail;
    tail = new LNode;
    tail = L;                           
    
    while (n --)
    {
    
    
        LNode *tmp;                         // 创建一个临时结点
        tmp = new LNode;
        
        cin >> tmp -> data.ibsn >> tmp -> data.name >> tmp -> data.price;
    
        tmp -> next = NULL;
        tail -> next = tmp;
        tail = tmp;
    }
}

void listSort(LinkList &L, int n)                                                   // 冒泡排序
{
    
    
    LNode * tmp;
    
    for (int i = 0; i < n; i ++)
    {
    
    
        tmp = L -> next;
        
        int j = 0;
        while (tmp && j < n - i - 1)
        {
    
    
            if (tmp -> data.price < tmp -> next -> data.price)
            {
    
    
                Book t = tmp -> data;
                tmp -> data = tmp -> next -> data; 
                tmp -> next -> data = t;
            }
            
            j ++;
            tmp = tmp -> next;
        }
    }
}


// 输出函数
void show(LinkList L, int n)
{
    
    
    LNode *tmp;
    tmp = new LNode;
    tmp = L -> next;
    
    int count = 0;                                                                  // 存储最贵图书数量
    n -= 1;                                                                         // 由于tmp是从首元结点开始遍历,因此需要先减去 1
    while (n --)
    {
    
    
        if (tmp -> data.price == tmp -> next -> data.price)                         // 注意这里不要用浮点数的相等判断,因为输入的值时固定的
            count ++;
        tmp = tmp -> next;
    }
 
    
    cout << count << endl;
    while (count --)
    {
    
    
        cout << L -> next -> data.ibsn << " " << L -> next -> data.name << " ";
        printf("%.2lf\n", L -> next -> data.price);   
        L = L -> next;
    }
}

int main()
{
    
    
    // 1、通过创建一个头结点创建链表
    LinkList L;
    
    // 2、通过将头结点指向NULL进行初始化
    InitList(L);

    // 3、利用尾插法建立链表
    int n;
    cin >> n;
    createList_tail(L, n);
    
    // 4、进行降序排序
    listSort(L, n);
    
    // 5、输出最贵图书信息
    show(L, n);
    
    return 0;
}

219、基于链式存储结构的图书信息表的最爱图书的查找

描述

定义一个包含图书信息(书号、书名、价格)的链表,读入相应的图书数据来完成图书信息表的创建,然后根据指定的最爱图书的名字,查找最爱的图书,输出相应图书的信息。

输入

总计n+m+2行。首先输入n+1行,其中,第一行是图书数目n,后n行是n本图书的信息(书号、书名、价格),每本图书信息占一行,书号、书名、价格用空格分隔,价格之后没有空格。其中书号和书名为字符串类型,价格为浮点数类型。然后输入m+1行,其中,第一行是一个整数m,代表查找m次,后m行是每次待查找的最爱图书名字。

输出

若查找成功: 总计输出m*(k+1)行,对于每一次查找,第一行是最爱图书数目(同一书名的图书可能有多本),后k行是最爱图书的信息(书号、书名、价格),每本图书信息占一行,书号、书名、价格用空格分隔,其中价格输出保留两位小数。 若查找失败: 只输出以下提示:抱歉,没有你的最爱!

输入样例 1
8
9787302257646 Data-Structure 35.00
9787302164340 Operating-System 50.00
9787302219972 Software-Engineer 32.00
9787302203513 Database-Principles 36.00
9787810827430 Discrete-Mathematics 36.00
9787302257800 Data-Structure 62.00
9787811234923 Compiler-Principles 62.00
9787822234110 The-C-Programming-Language 38.00
2
Java-Programming-Language
Data-Structure
输出样例 1
Sorry,there is no your favourite!
2
9787302257646 Data-Structure 35.00
9787302257800 Data-Structure 62.00
AC 代码
#include <iostream>

using namespace std;

struct Book // 建立书类数据结构
{
    
    
    string ibsn;
    string name;
    double price;
};

typedef struct LNode
{
    
    
    Book data;
    struct LNode *next;
}LNode, *LinkList;

// 初始化函数
bool InitList(LinkList &L)
{
    
    
    L = new LNode;
    L -> next = NULL;
    return true;
}

// 尾插法创建函数
void createList_tail(LinkList &L, int n) 
{
    
    
    LNode *tail;
    tail = new LNode;
    tail = L;                           
    
    while (n --)
    {
    
    
        LNode *tmp;                         // 创建一个临时结点
        tmp = new LNode;
        
        cin >> tmp -> data.ibsn >> tmp -> data.name >> tmp -> data.price;
    
        tmp -> next = NULL;
        tail -> next = tmp;
        tail = tmp;
    }
}

// 输出最爱图书函数
void findFavorite(LinkList L, string name, int n)
{
    
    
    LNode *tmp;
    tmp = new LNode;
    tmp = L -> next;
    
    int count = 0;                                                                  // 存储最爱图书数量
    n -= 1;                                                                         // 由于tmp是从首元结点开始遍历,因此需要先减去 1
    while (n --)
    {
    
    
        if (tmp -> data.name == name)                                               
            count ++;
        tmp = tmp -> next;
    }
 
    if (!count)                                                                     // 表示没有找到最爱图书
    {
    
    
        cout << "Sorry,there is no your favourite!" << endl;
        return ;                                                                    // 函数返回值类型类void
    }
    else
    {
    
    
        cout << count << endl;
        
        LNode *tmp1;
        tmp1 = new LNode;
        tmp1 = L -> next;
        
        while (tmp1)                                                                // 遍历
        {
    
    
            if (name == tmp1 -> data.name)
            {
    
    
                cout << tmp1 -> data.ibsn << " " << tmp1 -> data.name << " ";
                printf("%.2lf\n", tmp1 -> data.price);                   
            }
            tmp1 = tmp1 -> next;
        }
    }
}

int main()
{
    
    
    // 1、通过创建一个头结点创建链表
    LinkList L;
    
    // 2、通过将头结点指向NULL进行初始化
    InitList(L);

    // 3、利用尾插法建立链表
    int n;
    cin >> n;
    createList_tail(L, n);
    
    // 4、输入最爱图书
    int t;
    cin >> t;
    while (t --)
    {
    
    
        string name;
        cin >> name;
        
        findFavorite(L, name, n);
    }
    
    return 0;
}

220、基于链式存储结构的图书信息表的最佳位置图书的查找

描述

定义一个包含图书信息(书号、书名、价格)的链表,读入相应的图书数据来完成图书信息表的创建,然后根据指定的最佳位置的序号,查找该位置上的图书,输出相应图书的信息。

输入

总计n+m+2行。首先输入n+1行,其中,第一行是图书数目n,后n行是n本图书的信息(书号、书名、价格),每本图书信息占一行,书号、书名、价格用空格分隔,价格之后没有空格。其中书号和书名为字符串类型,价格为浮点数类型。然后输入m+1行,其中,第一行是一个整数m,代表查找m次,后m行每行内容为一个整数,代表待查找的图书的位置序号。

输出

输出m行 若查找成功: 输出内容为第i次查询的指定位置上的一本图书的信息(书号、书名、价格),书号、书名、价格用空格分隔,其中价格输出保留两位小数。 若查找失败: 只输出以下提示:抱歉,最佳位置上的图书不存在!

输入样例 1
8
9787302257646 Data-Structure 35.00
9787302164340 Operating-System 50.00
9787302219972 Software-Engineer 32.00
9787302203513 Database-Principles 36.00
9787810827430 Discrete-Mathematics 36.00
9787302257800 Data-Structure 62.00
9787811234923 Compiler-Principles 62.00
9787822234110 The-C-Programming-Language 38.00
2
2
0
输出样例 1
9787302164340 Operating-System 50.00
Sorry,the book on the best position doesn't exist!
AC 代码
#include <iostream>

using namespace std;

struct Book // 建立书类数据结构
{
    
    
    string ibsn;
    string name;
    double price;
};

typedef struct LNode
{
    
    
    Book data;
    struct LNode *next;
}LNode, *LinkList;

// 初始化函数
bool InitList(LinkList &L)
{
    
    
    L = new LNode;
    L -> next = NULL;
    return true;
}

// 尾插法创建函数
void createList_tail(LinkList &L, int n) 
{
    
    
    LNode *tail;
    tail = new LNode;
    tail = L;                           
    
    while (n --)
    {
    
    
        LNode *tmp;                         // 创建一个临时结点
        tmp = new LNode;
        
        cin >> tmp -> data.ibsn >> tmp -> data.name >> tmp -> data.price;
    
        tmp -> next = NULL;
        tail -> next = tmp;
        tail = tmp;
    }
}

// 查找函数
void find(LinkList L, int site, int n)
{
    
    
    LNode *tmp;
    tmp = new LNode;
    tmp = L -> next;
    
    if (site < 1 || site > n)               // 不合法位置
    {
    
     
        cout << "Sorry,the book on the best position doesn't exist!" << endl;
        return ;
    }
    
    site -= 1;
    while (site --)
        tmp = tmp -> next;

    cout << tmp -> data.ibsn << " " << tmp -> data.name << " ";
    printf("%.2lf\n", tmp -> data.price);    
}

int main()
{
    
    
    // 1、通过创建一个头结点创建链表
    LinkList L;
    
    // 2、通过将头结点指向NULL进行初始化
    InitList(L);

    // 3、利用尾插法建立链表
    int n;
    cin >> n;
    createList_tail(L, n);
    
    // 4、输入查找位置
    int t;
    cin >> t;
    while (t --)
    {
    
    
        int site;
        cin >> site;
        find(L, site, n);        
    }
    
    return 0;
}

221、基于链式存储结构的图书信息表的新图书的入库

描述

定义一个包含图书信息(书号、书名、价格)的链表,读入相应的图书数据来完成图书信息表的创建,然后根据指定的待入库的新图书的位置和图书的信息,将新图书插入到图书表中指定的位置上,最后输出新图书入库后的所有图书的信息。

输入

总计n+3行。首先输入n+1行,其中,第一行是图书数目n,后n行是n本图书的信息(书号、书名、价格),每本图书信息占一行,书号、书名、价格用空格分隔,价格之后没有空格。其中书号和书名为字符串类型,价格为浮点数类型。之后输入第n+2行,内容仅为一个整数,代表待入库的新图书的位置序号。最后输入第n+3行,内容为新图书的信息,书号、书名、价格用空格分隔。

输出

若插入成功: 输出新图书入库后所有图书的信息(书号、书名、价格),总计n+1行,每行是一本图书的信息,书号、书名、价格用空格分隔。其中价格输出保留两位小数。 若插入失败: 只输出以下一行提示:抱歉,入库位置非法!

输入样例 1
7
9787302257646 Data-Structure 35.00
9787302164340 Operating-System 50.00
9787302219972 Software-Engineer 32.00
9787302203513 Database-Principles 36.00
9787810827430 Discrete-Mathematics 36.00
9787302257800 Data-Structure 62.00
9787811234923 Compiler-Principles 62.00
2
9787822234110 The-C-Programming-Language 38.00
输出样例 1
9787302257646 Data-Structure 35.00
9787822234110 The-C-Programming-Language 38.00
9787302164340 Operating-System 50.00
9787302219972 Software-Engineer 32.00
9787302203513 Database-Principles 36.00
9787810827430 Discrete-Mathematics 36.00
9787302257800 Data-Structure 62.00
9787811234923 Compiler-Principles 62.00
AC 代码
#include <iostream>

using namespace std;

struct Book                                                 // 定义书类数据结构
{
    
    
    string ibsn;
    string name;
    double price;
};

typedef struct LNode                                        // 定义结点数据类型
{
    
    
    Book data;
    struct LNode *next;
}LNode, *LinkList;

// 初始化函数
bool Init(LinkList &L)                                      // 创建头结点并使头结点指向空
{
    
    
    L = new LNode;
    L -> next = NULL;
    return true;
}

// 尾插法
void createList_tail(LinkList &L, int n)                    // 利用尾插法得到链表,记得尾指针
{
    
    
    LNode *tail;
    tail = new LNode;
    tail = L;
    
    while (n --)
    {
    
    
        LNode *tmp;
        tmp = new LNode;
        
        cin >> tmp -> data.ibsn >> tmp -> data.name >> tmp -> data.price;
        tail -> next = tmp;
        tmp -> next = NULL;
        tail = tmp;
    }
    
}

// 输出整个链表
void show(LinkList L)
{
    
    
    LNode *tmp;
    tmp = new LNode;
    tmp = L -> next;
    
    while (tmp)                                             // 遍历
    {
    
    
        cout << tmp -> data.ibsn << " " << tmp -> data.name << " ";
        printf("%.2lf\n", tmp -> data.price);
        tmp = tmp -> next;
    }
}

void add(LinkList &L, int site, int n)
{
    
    
    if (site < 1 || site > n)                               // 情况特判
    {
    
    
        cout << "Sorry,the position to be inserted is invalid!" << endl;
        return ;
    }
    
    LNode *tmp;
    tmp = new LNode;
    tmp = L;
    
    site -= 1;
    while (site --)                                         // 先遍历找到待插入的位置
        tmp = tmp -> next;
        
    LNode *tmp1;                                            // 先改右指向,再改左指向
    tmp1 = new LNode;
    cin >>  tmp1 -> data.ibsn >> tmp1 -> data.name >> tmp1 -> data.price;
    
    tmp1 -> next = tmp -> next;
    tmp -> next = tmp1;
    
    show(L);                                                // 输出整个链表(内嵌函数)
}

int main()
{
    
    
    // 1、通过头结点创建一个链表
    LinkList L;
    
    // 2、初始化
    Init(L);
    
    // 3、插入
    int n;
    cin >> n;
    createList_tail(L, n);
    
    // 4、进行入库
    int site;
    cin >> site;
    add(L, site, n);
    
    return 0;
}

222、基于链式存储结构的图书信息表的旧图书的出库

描述

定义一个包含图书信息(书号、书名、价格)的链表,读入相应的图书数据来完成图书信息表的创建,然后根据指定的待出库的旧图书的位置,将该图书从图书表中删除,最后输出该图书出库后的所有图书的信息。

输入

总计n+2行。首先输入n+1行,其中,第一行是图书数目n,后n行是n本图书的信息(书号、书名、价格),每本图书信息占一行,书号、书名、价格用空格分隔,价格之后没有空格。其中书号和书名为字符串类型,价格为浮点数类型。之后输入第n+2行,内容仅为一个整数,代表待删除的旧图书的位置序号。

输出

若删除成功: 输出旧图书出库后所有图书的信息(书号、书名、价格),总计n-1行,每行是一本图书的信息,书号、书名、价格用空格分隔。其中价格输出保留两位小数。 若删除失败: 只输出以下一行提示:抱歉,出库位置非法!

输入样例 1
8
9787302257646 Data-Structure 35.00
9787302164340 Operating-System 50.00
9787302219972 Software-Engineer 32.00
9787302203513 Database-Principles 36.00
9787810827430 Discrete-Mathematics 36.00
9787302257800 Data-Structure 62.00
9787811234923 Compiler-Principles 62.00
9787822234110 The-C-Programming-Language 38.00
2
输出样例 1
9787302257646 Data-Structure 35.00
9787302219972 Software-Engineer 32.00
9787302203513 Database-Principles 36.00
9787810827430 Discrete-Mathematics 36.00
9787302257800 Data-Structure 62.00
9787811234923 Compiler-Principles 62.00
9787822234110 The-C-Programming-Language 38.00
输入样例 2
8
9787302257646 Data-Structure 35.00
9787302164340 Operating-System 50.00
9787302219972 Software-Engineer 32.00
9787302203513 Database-Principles 36.00
9787810827430 Discrete-Mathematics 36.00
9787302257800 Data-Structure 62.00
9787811234923 Compiler-Principles 62.00
9787822234110 The-C-Programming-Language 38.00
9
输出样例 2
Sorry,the position to be deleted is invalid!
AC 代码
#include <iostream>

using namespace std;

struct Book                                                 // 定义书类数据结构
{
    
    
    string ibsn;
    string name;
    double price;
};

typedef struct LNode                                        // 定义结点数据类型
{
    
    
    Book data;
    struct LNode *next;
}LNode, *LinkList;

// 初始化函数
bool Init(LinkList &L)                                      // 创建头结点并使头结点指向空
{
    
    
    L = new LNode;
    L -> next = NULL;
    return true;
}

// 尾插法
void createList_tail(LinkList &L, int n)                    // 利用尾插法得到链表,记得尾指针
{
    
    
    LNode *tail;
    tail = new LNode;
    tail = L;
    
    while (n --)
    {
    
    
        LNode *tmp;
        tmp = new LNode;
        
        cin >> tmp -> data.ibsn >> tmp -> data.name >> tmp -> data.price;
        tail -> next = tmp;
        tmp -> next = NULL;
        tail = tmp;
    }
    
}

// 输出整个链表
void show(LinkList L)
{
    
    
    LNode *tmp;
    tmp = new LNode;
    tmp = L -> next;
    
    while (tmp)                                             // 遍历
    {
    
    
        cout << tmp -> data.ibsn << " " << tmp -> data.name << " ";
        printf("%.2lf\n", tmp -> data.price);               
        tmp = tmp -> next;
    }
}

void remove(LinkList &L, int site, int n)
{
    
    
    if (site < 1 || site > n)                               // 情况特判
    {
    
    
        cout << "Sorry,the position to be deleted is invalid!" << endl;
        return ;
    }
    
    LNode *tmp;
    tmp = new LNode;
    tmp = L;
    
    site -= 1;
    while (site --)                                         // 先遍历找到待删除的位置
        tmp = tmp -> next;
        
    tmp -> next = tmp -> next -> next;                      // 只需要将next向后直接指两位,等价于删除一个结点
    
    show(L);                                                // 输出整个链表(内嵌函数)
}

int main()
{
    
    
    // 1、通过头结点创建一个链表
    LinkList L;
    
    // 2、初始化
    Init(L);
    
    // 3、插入
    int n;
    cin >> n;
    createList_tail(L, n);
    
    // 4、进行出库
    int site;
    cin >> site;
    remove(L, site, n);
    
    return 0;
}

223、基于链存储结构的图书信息表的图书去重

描述

出版社出版的任何一本图书的书号(ISBN)都是唯一的,即图书表中不允许包含书号重复的图书。定义一个包含图书信息(书号、书名、价格)的链表,读入相应的图书数据来完成图书信息表的创建(书号可能重复),然后进行图书的去重,即删除书号重复的图书(只保留第一本),最后输出去重后所有图书的信息。

输入

总计输入n+1行,其中,第一行是图书数目n,后n行是n本图书的信息(书号、书名、价格),每本图书信息占一行,书号、书名、价格用空格分隔,价格之后没有空格(书号可能重复)。其中书号和书名为字符串类型,价格为浮点数类型。

输出

总计输出m+1行(m≤n),其中,第一行是去重后的图书数目,后m行是去重后图书的信息(书号、书名、价格),每本图书信息占一行,书号、书名、价格用空格分隔,其中价格输出保留两位小数。

输入样例 1
9
9787302257646 Data-Structure 35.00
9787302164340 Operating-System 50.00
9787302219972 Software-Engineer 32.00
9787302203513 Database-Principles 36.00
9787810827430 Discrete-Mathematics 36.00
9787302257800 Data-Structure 62.00
9787811234923 Compiler-Principles 62.00
9787811234923 Compiler-Principles 62.00
9787822234110 The-C-Programming-Language 38.00
输出样例 1
8
9787302257646 Data-Structure 35.00
9787302164340 Operating-System 50.00
9787302219972 Software-Engineer 32.00
9787302203513 Database-Principles 36.00
9787810827430 Discrete-Mathematics 36.00
9787302257800 Data-Structure 62.00
9787811234923 Compiler-Principles 62.00
9787822234110 The-C-Programming-Language 38.00
AC 代码
#include <iostream>

using namespace std;

struct Book                                                 // 定义书类数据结构
{
    
    
    string ibsn;
    string name;
    double price;
};

typedef struct LNode                                        // 定义结点数据类型
{
    
    
    Book data;
    struct LNode *next;
}LNode, *LinkList;

// 初始化函数
bool Init(LinkList &L)                                      // 创建头结点并使头结点指向空
{
    
    
    L = new LNode;
    L -> next = NULL;
    return true;
}

// 尾插法
void createList_tail(LinkList &L, int n)                    // 利用尾插法得到链表,记得尾指针
{
    
    
    LNode *tail;
    tail = new LNode;
    tail = L;
    
    while (n --)
    {
    
    
        LNode *tmp;
        tmp = new LNode;
        
        cin >> tmp -> data.ibsn >> tmp -> data.name >> tmp -> data.price;
        tail -> next = tmp;
        tmp -> next = NULL;
        tail = tmp;
    }
    
}

// 去重
void unique(LinkList &L, int n)
{
    
    
    LNode * tmp1 = L -> next;                                               // 第一个指针从首元结点开始
    
    int cnt = 0;                                                            //  存储重复的数量
    while (tmp1)                                                            // 只要指针 1 不为空(未遍历到最后)
    {
    
    
        LNode *tmp2 = tmp1;                                                 // 让第二指针从首元结点开始,并且我们功能使用的是其next结点
        while (tmp2 -> next)                                                // 比较 n - 1次
        {
    
    
            if (tmp1 -> data.ibsn == tmp2 -> next -> data.ibsn)
            {
    
    
                LNode *tmp3 = tmp2 -> next;                                 // 创建一个临时LNode变量存储这个结点的地址,然后释放
                delete tmp3;
                tmp2 -> next = tmp2 -> next -> next;
                
                cnt ++;                                                     // 重复数量进行 ++
            }
            
            else tmp2 = tmp2 -> next;
        }
        
        tmp1 = tmp1 -> next;
    }
    
    cout << n - cnt << endl;                                                // 输出去重后的数量
}

// 输出整个链表
void show(LinkList L)
{
    
    
    LNode *tmp;
    tmp = new LNode;
    tmp = L -> next;
    
    while (tmp)                                             // 遍历
    {
    
    
        cout << tmp -> data.ibsn << " " << tmp -> data.name << " ";
        printf("%.2lf\n", tmp -> data.price);
        tmp = tmp -> next;
    }
}

int main()
{
    
    
    // 1、通过头结点创建一个链表
    LinkList L;
    
    // 2、初始化
    Init(L);
    
    // 3、插入
    int n;
    cin >> n;
    createList_tail(L, n);
    
    // 4、去重
    unique(L, n);
    
    // 5、输出
    show(L);
    
    return 0;
}

224、基于链表的两个一元多项式的基本运算

AC 代码
#include <iostream>

using namespace std;

typedef struct PNode
{
    
    
    double a; // a指整数
    int x;
    struct PNode *next;
}*Polynomial, PNode;

void createPolynomial(Polynomial &L, int n)
{
    
    
    L = new PNode;
    L -> next = NULL;
    for (int i = 0; i < n; i ++)
    {
    
    
        PNode *s = new PNode;
        cin >> s -> a >> s -> x;
        PNode *pre = L;
        PNode *cur = L -> next;
        
        while (cur && s -> x < cur -> x)
        {
    
    
            pre = cur;
            cur = cur -> next;
        }
        
        s -> next = cur;
        pre -> next = s;
    }
}

void outPutPolynomial(Polynomial L)
{
    
    
    if (!L || !L -> next)
    {
    
    
        cout << 0 << endl;
        return ;
    }
    
    PNode *p = L -> next;
    while (p)
    {
    
    
        if (p == L -> next)
        {
    
    
            if (p -> x)
                cout << p -> a << "x^" << p -> x;
        }
        else 
        {
    
    
            if (p -> a > 0) cout << "+" ;
            if (p -> x)
                cout << p -> a << "x^"  << p -> x;
            else 
                cout << p -> a;
        }
        p = p -> next;
    }
    
    cout << endl;
}

int main()
{
    
    
    int T;
    cin >> T;
    while (T --)
    {
    
    
        int a, b;
        cin >> a >> b;
        
        Polynomial L1, L2;
        createPolynomial(L1, a);
        createPolynomial(L2, b);
        
        outPutPolynomial(L1);
        outPutPolynomial(L2);
        
        // char c;
        // cin >> c;
        
        // if (c == '+') outPutPolynomial(add(L1, L2));
    }
    
    return 0;
}

### 226、基于链表的两个非递减有序序列的合并

##### 描述

给定两个非递减的整数序列A和B,利用链表表示序列A和B,将A和B合并为一个非递增的有序序列C,序列C允许有重复的数据。要求空间复杂度为O(1)。

##### 输入

多组数据,每组数据有三行,第一行为序列A和B的长度n和m,第二行为序列A的n个元素,第三行为序列B的m个元素(元素之间用空格分隔)。n=0且m=0时输入结束。

##### 输出

对于每组数据输出一行,为合并后的序列,每个数据之间用空格分隔。

##### 输入样例 1

```Cpp
5 5
1 3 5 7 9
2 4 6 8 10
5 6
1 2 2 3 5
2 4 6 8 10 12
0 0
输出样例 1
10 9 8 7 6 5 4 3 2 1
12 10 8 6 5 4 3 2 2 2 1
  • 草了,原来根本不需要去重,XS
AC 代码
#include <iostream>

using namespace std;

typedef struct LNode
{
    
    
    int data;
    struct LNode *next;
}LNode, *LinkList;
                                            // 尾插法创建函数
LinkList createList(int n)
{
    
    
    LinkList L;                             // 初始化
    L = new LNode;                          // 申请空间必不可少
    L -> next = NULL;                   
    
    LNode *r = L ;                          // 尾指针
    for (int i = 0; i < n; i ++)
    {
    
    
        LNode *tmp;
        tmp = new LNode;
        cin >> tmp -> data;
        
        tmp -> next = NULL;
        r -> next = tmp;
        r = tmp;
    }
    
    return L;
}

void merge(LinkList &L1, LinkList &L2)      // 合并的整体思路是将两个链表合并之后,仍然使用L1的空间
{
    
    
    // 分为两种情况,如果 L1更小,则将L1的元素拿走;如果L2更小,则将L2的元素拿走;
    // 拿走操作是指先将遍历结点接到工作指针之后,然后遍历结点和工作结点均后移
    
    LNode *r1 = L1 -> next;
    LNode *r2 = L2 -> next;
    LNode *r3 = L1;
    
    while (r1 && r2)
    {
    
    
        if (r1 -> data <= r2 -> data)
        {
    
    
            r3 -> next = r1;
            r3 = r1;
            r1 = r1 -> next;
        }
        else
        {
    
    
            r3 -> next = r2;
            r3 = r2;
            r2 = r2 -> next;
        }        
    }
    
    r3 -> next = r1 ? r1 : r2;
    
    delete L2;
}

void reserShow(LinkList L)                  // 整个链表的输出函数
{
    
                                               // 注意这里为暴力逆序输出
    LNode *r;
    r = new LNode;
    r = L;
    
    int cnt = 0;
    while (r -> next)
    {
    
    
        cnt ++;
        r = r -> next;
    }

    while (cnt --)
    {
    
    
        if (cnt == 0)                       // 这里进行特判是为了处理最后的空格
        {
    
    
            cout << L -> next -> data;
            break;
        }
        LNode *tmp;
        tmp = new LNode;
        tmp = L -> next;
        
        for (int i = 0; i < cnt; i ++)
            tmp = tmp -> next;
        cout << tmp -> data << " ";
    }
    cout << endl;
    // while (r -> next -> next)            // 这里之所以用第三个结点作为遍历结点
    // {                                    // 是因为某OJ丧心病狂卡最后一个空格
    //     cout << r -> next -> data << " ";
    //     r = r -> next;
    // }
    
    // cout << r -> next -> data << endl;
}

int main()
{
    
    
    int n1, n2;
    while (true)
    {
    
    
        cin >> n1 >> n2;
        if (n1 == 0 && n2 == 0) break;      // 特判输入
        
        LinkList L1, L2;                    // 1、创建两个链表
        L1 = createList(n1);
        L2 = createList(n2);
        
        merge(L1, L2);                      // 2、进行合并
        
        reserShow(L1);                      // 3、逆序输出
    }
    return 0;
}

225、基于链表的两个递增有序序列的合并

描述

给定两个递增的整数序列A和B,利用链表表示序列A和B,将A和B合并为一个递增的有序序列C,序列C不允许有重复的数据。要求空间复杂度为O(1)。

输入

多组数据,每组数据有三行,第一行为序列A和B的长度n和m,第二行为序列A的n个元素,第三行为序列B的m个元素(元素之间用空格分隔)。n=0且m=0时输入结束。

输出

对于每组数据输出一行,为合并后的序列,每个数据之间用空格分隔。

输入样例 1
5 5
1 3 5 7 9 
2 4 6 8 10 
3 4
1 5 9
1 2 5 9
0 0
输出样例 1
1 2 3 4 5 6 7 8 9 10
1 2 5 9
  • 题目要求空间复杂度是O(1),因此不能单独创建一个链表用来作为合并后的链表
  • 草了,居然卡结尾空格
  • 关于申请空间操作,如果是声明之后需要用到next指针,那么就必须要申请空间;如果可以直接赋值某个结点,那么申请空间操作就可以省略
AC 代码:
#include <iostream>

using namespace std;

typedef struct LNode
{
    
    
    int data;
    struct LNode *next;
}LNode, *LinkList;

                                            // 尾插法创建函数
LinkList createList(int n)
{
    
    
    LinkList L;                             // 初始化
    L = new LNode;                          // 申请空间必不可少
    L -> next = NULL;                   
    
    LNode *r = L ;                          // 尾指针
    for (int i = 0; i < n; i ++)
    {
    
    
        LNode *tmp;
        tmp = new LNode;
        cin >> tmp -> data;
        
        tmp -> next = NULL;
        r -> next = tmp;
        r = tmp;
    }
    
    return L;
}

void merge(LinkList &L1, LinkList &L2)      // 合并的整体思路是将两个链表合并之后,仍然使用L1的空间
{
    
    
    // 分为三种情况,如果 L1更小,则将L1的元素拿走;如果L2更小,则将L2的元素拿走;
    // 若相等,则拿走 L1 ,且使 L2 的指针也需要后移
    // 拿走操作是指先将遍历结点接到工作指针之后,然后遍历结点和工作结点均后移
    
    LNode *r1 = L1 -> next;
    LNode *r2 = L2 -> next;
    LNode *r3 = L1;
    
    while (r1 && r2)
    {
    
    
        if (r1 -> data < r2 -> data)
        {
    
    
            r3 -> next = r1;
            r3 = r1;
            r1 = r1 -> next;
        }
        else if (r1 -> data == r2 -> data)
        {
    
    
            r3 -> next = r1;
            r3 = r1;
            r1 = r1 -> next;
            r2 = r2 -> next;
        }
        else
        {
    
    
            r3 -> next = r2;
            r3 = r2;
            r2 = r2 -> next;
        }        
    }
    
    if (r1)                                 // 如果还有剩下,则只需要直接连接就好,不需要遍历
        r3 -> next = r1;
    if (r2) 
        r3 -> next = r2;
    // 也可以用三目运算符进行骚操作
    // r3 -> next = r1 ? r1 : r2;
    delete L2;
}

void show(LinkList L)                       // 整个链表的输出函数
{
    
    
    LNode *r;
    r = new LNode;
    r = L;
    
    while (r -> next -> next)               // 这里之所以用第三个结点作为遍历结点
    {
    
                                           // 是因为某OJ丧心病狂卡最后一个空格
        cout << r -> next -> data << " ";
        r = r -> next;
    }
    
    cout << r -> next -> data << endl;
}

int main()
{
    
    
    int n1, n2;
    while (true)
    {
    
    
        cin >> n1 >> n2;
        if (n1 == 0 & n2 == 0) break;      // 特判输入
        
        LinkList L1, L2;                    // 1、创建两个链表
        L1 = createList(n1);
        L2 = createList(n2);
        
        merge(L1, L2);                      // 2、进行合并
        
        show(L1);                           // 3、输出
    }
    return 0;
}

226、基于链表的两个非递减有序序列的合并

描述

给定两个非递减的整数序列A和B,利用链表表示序列A和B,将A和B合并为一个非递增的有序序列C,序列C允许有重复的数据。要求空间复杂度为O(1)。

输入

多组数据,每组数据有三行,第一行为序列A和B的长度n和m,第二行为序列A的n个元素,第三行为序列B的m个元素(元素之间用空格分隔)。n=0且m=0时输入结束。

输出

对于每组数据输出一行,为合并后的序列,每个数据之间用空格分隔。

输入样例 1
5 5
1 3 5 7 9
2 4 6 8 10
5 6
1 2 2 3 5
2 4 6 8 10 12
0 0
输出样例 1
10 9 8 7 6 5 4 3 2 1
12 10 8 6 5 4 3 2 2 2 1
  • 草了,原来根本不需要去重,XS
AC 代码
#include <iostream>

using namespace std;

typedef struct LNode
{
    
    
    int data;
    struct LNode *next;
}LNode, *LinkList;
                                            // 尾插法创建函数
LinkList createList(int n)
{
    
    
    LinkList L;                             // 初始化
    L = new LNode;                          // 申请空间必不可少
    L -> next = NULL;                   
    
    LNode *r = L ;                          // 尾指针
    for (int i = 0; i < n; i ++)
    {
    
    
        LNode *tmp;
        tmp = new LNode;
        cin >> tmp -> data;
        
        tmp -> next = NULL;
        r -> next = tmp;
        r = tmp;
    }
    
    return L;
}

void merge(LinkList &L1, LinkList &L2)      // 合并的整体思路是将两个链表合并之后,仍然使用L1的空间
{
    
    
    // 分为两种情况,如果 L1更小,则将L1的元素拿走;如果L2更小,则将L2的元素拿走;
    // 拿走操作是指先将遍历结点接到工作指针之后,然后遍历结点和工作结点均后移
    
    LNode *r1 = L1 -> next;
    LNode *r2 = L2 -> next;
    LNode *r3 = L1;
    
    while (r1 && r2)
    {
    
    
        if (r1 -> data <= r2 -> data)
        {
    
    
            r3 -> next = r1;
            r3 = r1;
            r1 = r1 -> next;
        }
        else
        {
    
    
            r3 -> next = r2;
            r3 = r2;
            r2 = r2 -> next;
        }        
    }
    
    r3 -> next = r1 ? r1 : r2;
    
    delete L2;
}

void reserShow(LinkList L)                  // 整个链表的输出函数
{
    
                                               // 注意这里为暴力逆序输出
    LNode *r;
    r = new LNode;
    r = L;
    
    int cnt = 0;
    while (r -> next)
    {
    
    
        cnt ++;
        r = r -> next;
    }

    while (cnt --)
    {
    
    
        if (cnt == 0)                       // 这里进行特判是为了处理最后的空格
        {
    
    
            cout << L -> next -> data;
            break;
        }
        LNode *tmp;
        tmp = new LNode;
        tmp = L -> next;
        
        for (int i = 0; i < cnt; i ++)
            tmp = tmp -> next;
        cout << tmp -> data << " ";
    }
    cout << endl;
    // while (r -> next -> next)            // 这里之所以用第三个结点作为遍历结点
    // {                                    // 是因为某OJ丧心病狂卡最后一个空格
    //     cout << r -> next -> data << " ";
    //     r = r -> next;
    // }
    
    // cout << r -> next -> data << endl;
}

int main()
{
    
    
    int n1, n2;
    while (true)
    {
    
    
        cin >> n1 >> n2;
        if (n1 == 0 && n2 == 0) break;      // 特判输入
        
        LinkList L1, L2;                    // 1、创建两个链表
        L1 = createList(n1);
        L2 = createList(n2);
        
        merge(L1, L2);                      // 2、进行合并
        
        reserShow(L1);                      // 3、逆序输出
    }
    return 0;
}

227、基于链表的两个集合的交集

描述

给定两个递增的整数集合A和B,分别用链表表示集合A和B,求出A和B的交集,并存放在A中。要求空间复杂度为O(1)。

输入

多组数据,每组数据有三行,第一行为序列A和B的长度n和m,第二行为序列A的n个元素,第三行为序列B的m个元素(元素之间用空格分隔)。n=0且m=0时输入结束。

输出

对于每组数据输出一行,为A和B的交集,每个数据之间用空格分隔。

输入样例 1
5 5
1 3 5 7 9
1 2 3 4 5
3 4
1 2 5
2 4 5 6
0 0
输出样例 1
1 3 5
2 5
AC代码
#include <iostream>

using namespace std;

typedef struct LNode
{
    
    
    int data;
    struct LNode *next;
}LNode, *LinkList;

LinkList createList(int n)                  // 链表的创建和初始化函数
{
    
    
    LinkList L;
    L = new LNode;
    L -> next = NULL;
    
    LNode* r = L;                         // 利用尾插法进行创建
    for (int i = 0; i < n; i ++)
    {
    
    
        LNode *tmp;
        tmp = new LNode;
        cin >> tmp -> data;
        
        tmp -> next = NULL;
        r -> next = tmp;
        r = tmp;
    }
    
    return L;
}

// 基本思路为用两个指针遍历两个链表,分三种情况讨论
LinkList merge(LinkList &L1, LinkList &L2)
{
    
    
    LinkList L = createList(0);
    LinkList p = L;
    LinkList p1 = L1 -> next;
    LinkList p2 = L2 -> next;
    while (p1 && p2)
    {
    
    
        if (p1 -> data == p2 -> data)
        {
    
    
            p -> next = p1;
            p = p1;
            
            p1 = p1 -> next;
            p2 = p2 -> next;
        }
        
        else if(p1 -> data > p2 -> data)
            p2 = p2 -> next;
        else
            p1 = p1 -> next;
    }
    
    p -> next = NULL;                      
    return L;
}

void show(LinkList L)                       // 输出函数(注意特判结尾空格)
{
    
    
    LinkList p;
    p = L -> next;
    while (p -> next)
    {
    
    
        cout << p -> data << " ";
        p = p -> next;
    }
    cout << p -> data;
    cout << endl;
}

int main()
{
    
    
    int n, m;
    while (cin >> n >> m, n && m)
    {
    
    
        LinkList L1 = createList(n);        // 进行链表的创建和初始化
        LinkList L2 = createList(m);
        
        LinkList L3 = merge(L1, L2);
        // show(L1);
        // show(L2);
        show(L3);
    }
    
    return 0;  
}
//给定两个递增的整数集合A和B,分别用链表表示集合A和B,求出A和B的交集,并存放在A中。要求空间复杂度为O(1)。
#include <bits/stdc++.h>
using namespace std;
typedef struct link {
    
    
    int data;
    struct link* next;
}link,*linklist;

void Createlist(linklist& L, int n)
{
    
    
    L = new link[sizeof(link)];
    L->next = NULL;
    linklist p,r;
    r = L;
    while (n)
    {
    
    
        p=new link[sizeof(link)];
        cin >> p->data;
        p->next = r->next;
        r->next = p;
        r = p;
        n--;
    }
}

void Output(linklist L)
{
    
    
    linklist p;
    p = L->next;
    int flag = 1;
    while (p)
    {
    
    
        if (flag)
        {
    
    
            cout << p->data;
            flag = 0;
        }
        else
            cout << " " << p->data;
        p=p->next;
    }
    cout << endl;
}
void Intersect(linklist& A, linklist& B)
{
    
    
    linklist pa, pb, pc;
    pa = A->next;
    pc = A;
    while (pa)
    {
    
    
        int flag = 1;
        pb = B->next;
        while (pb)
        {
    
    
            if (pb->data == pa->data)
            {
    
    
                flag = 0;
                break;
            }
            else
                pb = pb->next;
        }
        if (!flag)
        {
    
    
            pc->next = pa;
            pc = pa;
            pa = pa->next;
        }   
        else
            pa = pa->next;
    }
    pc->next=NULL;
    delete B;
}

int main()
{
    
    
    linklist A, B;
    int n, m;
    while (1)
    {
    
    
        cin>>n>>m;
        if(n==0&&m==0)
          break; 
        Createlist(A, n);
        Createlist(B, m);
        Intersect(A, B);
        Output(A);
    }
    return 0;
}

228、基于链表的两个集合的差集

描述

给定两个递增的整数集合,分别用链表A和B表示,求出A和B的差集(即仅由在A中出现而不在B中出现的元素所构成的集合),并以同样的形式存储,同时返回该集合的元素个数。要求空间复杂度为O(1)。

输入

多组数据,每组数据有三行,第一行为序列A和B的长度n和m,第二行为序列A的n个元素,第三行为序列B的m个元素(元素之间用空格分隔)。n=0且m=0时输入结束。

输出

对于每组数据输出两行,第一行是A和B的差集,第二行为差集中的元素个数,每个数据之间用空格分隔。

输入样例 1
5 5
1 3 5 7 9
1 2 3 4 5
3 4
1 2 6
2 4 5 7
0 0
输出样例 1
7 9
2
1 6
2
AC代码
#include <iostream>

using namespace std;

typedef struct LNode
{
    
    
    int data;
    struct LNode *next;
}LNode, *LinkList;

LinkList createList(int n)
{
    
    
    LinkList L;
    L = new LNode;
    L -> next = NULL;
    
    LinkList r = L;
    while (n --)
    {
    
    
        LNode *tmp;
        tmp = new LNode;
        cin >> tmp -> data;
        
        tmp -> next = NULL;
        r -> next = tmp;
        r = tmp;
    }
    
    return L;
}

// LinkList difference(LinkList L1, LinkList L2)
// {
    
    
//     LinkList L = createList(0);
//     LinkList p = L;
//     LinkList p1 = L1 -> next;
//     LinkList p2 = L2 -> next;
    
//     while (p1 && p2)
//     {
    
    
//         if (p1 -> data == p2 -> data)
//         {
    
    
//             p1 = p1 -> next;
//             p2 = p2 -> next;
//         }
//         else if (p1 -> data < p2 -> data)
//         {
    
    
//             p -> next = p1;
//             p = p1 -> next;
            
//             p1 -> next;
//         }
//         else 
//             p2 = p2 -> next;
//     }
            
//     p -> next = NULL;
//     return L;
// }

LinkList diff(LinkList L1, LinkList L2)
{
    
    
    LinkList L = createList(0);
    LinkList p = L;
    LinkList p1 = L1 -> next;
    LinkList p2 = L2 -> next;
    
    while (p1 && p2)
    {
    
    
        if (p1 -> data == p2 -> data)
        {
    
    
            p1 = p1 -> next;
            p2 = p2 -> next;
        }
        else if (p1 -> data > p2 -> data)
            p2 = p2 -> next;
        
        else if (p1 -> data < p2 -> data)
        {
    
    
            p -> next = p1;
            p1 = p1 -> next;
            p = p -> next;
        }
        if (!p2) p -> next = p1;
    }
    
    return L;
}

void show(LinkList L)
{
    
    
    LinkList p = L -> next;
    
    int cnt = 0;
    while (p -> next)
    {
    
    
        cout << p -> data << " ";
        p = p -> next;
        cnt ++;
    }
    
    cout << p -> data;
    cout << endl;
    cout << cnt + 1 << endl;
}

int main()
{
    
    
    int n, m;
    while (cin >> n >> m, n && m)
    {
    
    
        LinkList L1 = createList(n);
        LinkList L2 = createList(m);
        
        LinkList L3 = diff(L1, L2);
        
        show(L3);
    }
    
    return 0;
}

229、链表的分解

描述

利用单链表A表示一个非零整数序列,把A分解为两个具有相同结构的链表B和C,其中B表的结点为A表中值小于零的结点,而C表的结点为A表中值大于零的结点。要求空间复杂度为O(1),链表B和C均利用链表A的结点空间。

输入

多组数据,每组数据有两行,第一行为链表A的长度n,第二行为链表A的n个元素(元素之间用空格分隔)。当n=0时输入结束。

输出

对于每组数据分别输出两行,分别对应链表B和C的元素,每个数据之间用空格分隔。

输入样例 1
7
3 -6 1 -2 4 -3 8
8
2 5 3 -1 -2 2 6 -1
0
输出样例 1
-6 -2 -3
3 1 4 8
-1 -2 -1
2 5 3 2 6
AC代码
#include <iostream>

using namespace std;

typedef struct LNode
{
    
    
    int data;
    struct LNode *next;
}LNode, *LinkList;

LinkList createList(int n)
{
    
    
    LinkList L;
    L = new LNode;
    L -> next = NULL;
    
    LinkList r = L;
    while(n --)
    {
    
    
        LNode *tmp;
        tmp = new LNode;
        cin >> tmp -> data;
        
        tmp -> next = NULL;
        r -> next = tmp;
        r = tmp;
    }
    
    return L;
}

void show(LinkList L)
{
    
    
    LinkList p = L -> next;
    
    while (p -> next)
    {
    
    
        cout << p -> data << " ";
        p = p -> next;
    }
    cout << p -> data;
    cout << endl;
}

void resolve(LinkList L)
{
    
    
    LinkList L1 = createList(0);        // 初始化创建两个链表
    LinkList L2 = createList(0);
        
    LinkList r1 = L1;                   // 两个链表的尾指针
    LinkList r2 = L2;
    
    LinkList p = L -> next;
    while (p)
    {
    
    
        if (p -> data < 0)
        {
    
    
            r1 -> next = p;
            r1 = p;
        }
        else if (p -> data > 0)
        {
    
    
            r2 -> next = p;
            r2 = p;
        }
        else ;                          // 如果和 0 相等的话,就不执行任何操作
        
        p = p -> next;
    }
    
    r1 -> next = NULL;                  // 注意这两步,我们需要将尾指针置空,不然的话,最后的尾指针是指向 p
    r2 -> next = NULL;
    show (L1);
    show (L2);
}

int main()
{
    
    
    int n;
    while (cin >> n, n)
    {
    
    
        LinkList L = createList(n);
        
        resolve(L);                     // 分解函数中包含输出
    }
    
    return 0;
}

230、查找链表中的最大值

描述

利用单链表表示一个整数序列,通过一趟遍历在单链表中确定值最大的结点。

输入

多组数据,每组数据有两行,第一行为链表的长度n,第二行为链表的n个元素(元素之间用空格分隔)。当n=0时输入结束。

输出

对于每组数据分别输出一行,输出每个链表的最大值。

输入样例 1
5
2 1 3 5 4
6
2 3 10 4 5 1
4
-1 -2 -3 -4
0
输出样例 1
5
10
-1
AC代码
#include <iostream>

using namespace std;

typedef struct LNode
{
    
    
    int data;
    struct LNode *next;
}LNode, *LinkList;

LinkList createList(int n)
{
    
    
    LinkList L;
    L = new LNode;
    L -> next = NULL;
    
    LinkList r = L;
    while (n --)
    {
    
    
        LNode *tmp;
        tmp = new LNode;
        cin >> tmp -> data;
        
        tmp -> next = NULL;
        r -> next = tmp;
        r = tmp;
    }
    
    return L;
}

void show(LinkList L)
{
    
    
    LinkList p = L -> next;
    while (p -> next)
    {
    
    
        cout << p -> data << " ";
        p = p -> next;
    }
    cout << p -> data;
    cout << endl;
}

/* 基本思路是:
将结点 1 的data值作为最大值,遍历链表时,如果有结点的值
大于 max ,则进行替换
*/

int getMax(LinkList L)
{
    
    
    LinkList p = L -> next;
    
    int max = p -> data;
    while (p)
    {
    
    
        if (p -> data > max)
            max = p -> data;
        p = p -> next;
    }
    
    return max;
}

int main()
{
    
    
    int n;
    while (cin >> n, n)
    {
    
    
        LinkList L = createList(n);
        
        cout << getMax(L) << endl;       // 得到最大值并输出
    }
    
    return 0;
}

231、链表的逆转

描述

利用单链表表示一个整数序列,通过一趟遍历,将单链表中所有结点的链接方向逆转。要求空间复杂度为O(1)。

输入

多组数据,每组数据有两行,第一行为链表的长度n,第二行为链表的n个元素(元素之间用空格分隔)。当n=0时输入结束。

输出

对于每组数据分别输出一行,逆序输出链表中的元素,元素之间用空格分隔。

输入样例 1
5
1 2 3 4 5
6
3 1 2 5 4 6
0
输出样例 1
5 4 3 2 1
6 4 5 2 1 3
AC代码
#include <iostream>

using namespace std;

typedef struct LNode
{
    
    
    int data;
    struct LNode *next;
}LNode, *LinkList;

LinkList createList(int n)
{
    
    
    LinkList L;
    L = new LNode;
    L -> next = NULL;
    
    LinkList r = L;
    while (n --)
    {
    
    
        LNode *tmp;
        tmp = new LNode;
        cin >> tmp -> data;
        
        tmp -> next = NULL;
        r -> next = tmp;
        r = tmp;
    }
    
    return L;
}

void show(LinkList L)
{
    
    
    LinkList p = L -> next;
    while (p -> next)
    {
    
    
        cout << p -> data << " ";
        p = p -> next;
    }
    cout << p -> data;
    cout << endl;
}

/* 基本思路:
用一个指针暴力到输入链表的尾端,然后将该结点存入新链表中
暴力循环的次数减 1,再次进行循环
*/
LinkList reserve(LinkList L, int n)     // 注意这里将链表长度也传进去
{
    
    
    LinkList L1 = createList(0);        // 创建一个链表接收翻转后的链表
    
    LinkList r1 = L1;
    while (n --)
    {
    
    
        LinkList r = L -> next;
        for (int i = 0; i < n; i ++)
            r = r -> next;
        
        r1 -> next = r;
        r1 = r;
    }
    
    r1 -> next = NULL;
    return L1;
}

int main()
{
    
    
    int n;
    while (cin >> n, n)
    {
    
    
        LinkList L = createList(n);
        
        show (reserve(L, n));
    }
    
    return 0;
}

232、删除链表中满足区间值的结点

描述

利用单链表表示一个递增的整数序列,删除链表中值大于等于mink且小于等于maxk的所有元素(mink和maxk是给定的两个参数,其值可以和表中的元素相同,也可以不同)。

输入

多组数据,每组数据有两行,第一行为链表的长度n,第二行为链表的n个元素(元素之间用空格分隔),第三行为给定的mink和maxk(用空格分隔)。当n=0时输入结束。

输出

对于每组数据分别输出一行,依次输出删除元素后的链表元素,元素之间用空格分隔。

输入样例 1
5
1 2 3 4 5
2 4
6
2 4 6 8 10 12
3 5
0
输出样例 1
1 5 
2 6 8 10 12
AC代码
#include <iostream>

using namespace std;

typedef struct LNode
{
    
    
    int data;
    struct LNode *next;
}LNode, *LinkList;

LinkList createList(int n)
{
    
    
    LinkList L;
    L = new LNode;
    L -> next = NULL;
    
    LinkList r = L;
    while (n --)
    {
    
    
        LNode *tmp;
        tmp = new LNode;
        cin >> tmp -> data;
        
        tmp -> next = NULL;
        r -> next = tmp;
        r = tmp;
    }
    
    return L;
}

void show(LinkList L)
{
    
    
    LinkList p = L -> next;
    while (p -> next)
    {
    
    
        cout << p -> data << " ";
        p = p -> next;
    }
    cout << p -> data;
    cout << endl;
}

/*
原理简单不解释,记住删除结点的抽象操作
*/
LinkList del(LinkList L, int mink, int maxk)
{
    
    
    LinkList p = L;
    while (p -> next)
    {
    
      
        if (p -> next -> data >= mink && p -> next -> data <= maxk)
        {
    
    
            LNode *tmp = p -> next;
            p -> next = p -> next -> next;
            delete tmp;
        }
        else p = p -> next;                         // 这个else一定要加上,不然就会重复进行后移操作
    }
    
    p -> next = NULL;
    
    return L;
}

int main()
{
    
    
    int n;
    while (cin >> n, n)
    {
    
    
        LinkList L = createList(n);
        
        int mink, maxk;
        cin >> mink >> maxk;
        
        show(del(L, mink, maxk));
    }
    
    return 0;
}

233、双向循环链表中结点的交换

描述

利用双向循环链表表示一个整数序列,指定一个结点位置用p指向该结点,交换p所指向的结点及其前驱结点的顺序。

输入

多组数据,每组数据有三行,第一行为链表的长度n,第二行为链表的n个元素(元素之间用空格分隔),第三行为p所指向的结点位置。当n=0时输入结束。

输出

对于每组数据分别输出一行,依次输出交换结点顺序后的链表元素,元素之间用空格分隔。

输入样例 1
5
44 11 22 33 55
3
6
22 33 11 66 44 55
6
0	
输出样例 1
44 22 11 33 55
22 33 11 66 55 44
AC代码
/*这道题难点如下:
1、循环链表的建立
2、循环链表的输出
*/
#include <iostream>

using namespace std;

typedef struct BCLNode
{
    
    
    int data;
    struct BCLNode *next;
    struct BCLNode *prior;
}BCLNode, *BCLinkList;

BCLinkList createList(int n)
{
    
    
    BCLinkList L = new BCLNode;         // 这是创建链表的简洁方式
    cin >> L -> data;                   // 这里一定要注意,双向循环链表的每一个结点都有值
    
    BCLinkList r = L;                   // 作为双向循环链表的尾指针
    for (int i = 1; i < n; i ++)        // 由于之前赋了一次值,因此只循环 n - 1 次
    {
    
    
        BCLNode *tmp = new BCLNode;     // 临时结点
        cin >> tmp -> data;
        
        r -> next = tmp;
        tmp -> prior = r;
        r = tmp;
    }
    
    r -> next = L;                      // 最后将尾结点和头结点连接
    L -> prior = r;
    
    return L;
}

void show(BCLinkList L)
{
    
    
    cout << L -> data << " ";           // 注意这里需要先输出一次头结点
    
    BCLNode *p = L -> next;
    while (p -> next != L)              // 终止条件是遍历指针指向头结点
    {
    
    
        cout << p -> data << " ";            
        p = p -> next;
    }
    cout << p -> data;
    cout << endl;
}

/* 思路:
交换方面我们进行取巧,与其修改众多指针指向,
我们不如直接只交换遍历指针所指结点与其前驱结点
的数据即可,只是一个简单的swap函数
*/

void exchange(BCLinkList &L, int key)
{
    
    
    BCLinkList p = L -> next;
    for (int i = 0; i < key - 2; i ++)  //  这里注意循环次数是 key - 2
        p = p -> next;
        
    int tmp = p -> prior -> data;
    p -> prior -> data = p -> data;
    p -> data = tmp;
}

int main()
{
    
    
    int n;
    while (cin >> n, n)
    {
    
    
        BCLinkList L = createList(n);

        int key;
        cin >> key;
        
        exchange(L, key);
        
        show(L);
    }
    
    return 0;
}

235、查找链表中倒数第k个结点

描述

利用单链表表示一个整数序列,请实现一个时间复杂度为O(n)、空间复杂度为O(1)的算法,通过一趟遍历在单链表中确定倒数第k个结点。

输入

多组数据,每组数据有三行,第一行为链表的长度n,第二行为链表的n个元素(元素之间用空格分隔),第三行为k。当n=0时输入结束。

输出

对于每组数据分别输出一行,输出每个链表的倒数第k个结点对应的数值。

输入样例 1
7
5 2 3 4 50 100 70
3
5
20 30 10 4 5
5
0

输出样例 1
50
20
AC代码
// 简单题,不解释
#include <iostream>

using namespace std;

typedef struct LNode
{
    
    
    int data;
    struct LNode *next;
}LNode, *LinkList;

LinkList createList(int n)
{
    
    
    LinkList L;
    L = new LNode;
    L -> next = NULL;
    
    LinkList r = L;
    while (n --)
    {
    
    
        LNode *tmp;
        tmp = new LNode;
        cin >> tmp -> data;
        
        tmp -> next = NULL;
        r -> next = tmp;
        r = tmp;
    }
    
    return L;
}

int main()
{
    
    
    int n;
    while (cin >> n, n)
    {
    
    
        LinkList L = createList(n);
        
        int k;
        cin >> k;
        for (int i = 0; i < n - k + 1; i ++)
        {
    
    
           L = L -> next;
        }
        cout << L -> data << endl;
    }
    
    return 0;
}

236、删除链表中绝对值相等的结点

描述

利用单链表表示一个整数序列,实现一个时间复杂度为O(n)的算法,对于链表中绝对值相

等的结点,仅保留第一次出现的结点而删除其余绝对值相等的结点。

例如,若给定的单链表HEAD如下:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-sDgOY7st-1635648565407)(https://www.bjfuacm.com/public/upload/b6286aba48.png)]

删除后的单链表HEAD为:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-QoszRfRK-1635648565410)(https://www.bjfuacm.com/public/upload/a6f8e04e53.png)]

输入

多组数据,每组数据有两行,第一行为链表的长度n,第二行为链表的n个元素(元素之间用空格分隔)。当n=0时输入结束。

输出

对于每组数据分别输出一行,依次输出删除结点后的链表元素,元素之间用空格分隔。

输入样例 1
5
21 -15 -15 -7 15
7
90 32 -90 -66 77 66 90
0
输出样例 1
21 -15 -7
90 32 -66 77
AC代码
描述

利用单链表表示一个整数序列,请实现一个时间复杂度为O(n)、空间复杂度为O(1)的算法,通过一趟遍历在单链表中确定倒数第k个结点。

输入

多组数据,每组数据有三行,第一行为链表的长度n,第二行为链表的n个元素(元素之间用空格分隔),第三行为k。当n=0时输入结束。

输出

对于每组数据分别输出一行,输出每个链表的倒数第k个结点对应的数值。

输入样例 1
7
5 2 3 4 50 100 70
3
5
20 30 10 4 5
5
0

输出样例 1
50
20
AC代码
#include <iostream>
#include <algorithm>
#include <cmath>

using namespace std;

typedef struct LNode
{
    
    
    int data;
    struct LNode *next;
}LNode, *LinkList;

LinkList createList(int n)
{
    
    
    LinkList L;
    L = new LNode;
    L -> next = NULL;
    
    LinkList r = L;
    while (n --)
    {
    
    
        LNode *tmp;
        tmp = new LNode;
        cin >> tmp -> data;
        
        tmp -> next = NULL;
        r -> next = tmp;
        r = tmp;
    }
    
    return L;
}

void show(LinkList &L)
{
    
    
	LinkList p=L->next;
	while(p)
	{
    
    
		cout<<p->data;
		if(p->next) cout<<" ";
		p=p->next;
	}
	cout<<endl;
	return;
}

/* 这段代码就是比较好的诠释了我对于结点指针的疑问
*/
// void delAbs(LinkList &L)
// {
    
    
//     LinkList p = L -> next;
//     while (p)
//     {
    
    
//         LinkList tmp = p -> next;
//         while (tmp)
//         {
    
    
//             if (p -> data == tmp -> data || p -> data == (- tmp -> data))
//             {
    
    
//                 LNode *tmp1 = tmp -> next;
//                 tmp -> next = tmp -> next -> next;
//                 delete tmp1;
//             }
//             tmp = tmp -> next;
//         }
//         p = p -> next;
//     }
// }

void delAbs(LinkList &L)
{
    
    
    LinkList p1, p2;
    p1 = L -> next;
    p2 = p1 -> next; 
    
    bool flag[100010] = {
    
    0};                                        // 注意,这个数组定义在函数中,不要定义在全局范围内,因为只能使用一次
    
    flag[abs(p1 -> data)] = 1;                                      // 将这个值进行标记
    while(p2)
    {
    
    
        if (flag[abs(p2 -> data)] == 0)                             // 如果这个值没有被标记,则标记
            flag[abs(p2 -> data)] = 1;
        
        else if (p2 -> next && flag[abs(p2 -> data)] == 1)          // 如果pre不是尾结点且这个值被标记了,则删除这个结点
            p1 -> next = p2 -> next;
        else if (p2 -> next == NULL && flag[abs(p2 -> data)] == 1)  // 如果为尾结点,且这个值被标记了,则指针置空
            p1 -> next = NULL;
        
        p2 = p2 -> next;                                            // 使遍历指针后移
        if (p1 -> next != p2)                                       // 说明删除了一次,有可能后面还需要删,因此第一个遍历指针不能后移
            p1 = p1 -> next;
    }
}

int main()
{
    
    
    int n;
    while (cin >> n, n)
    {
    
    
        LinkList L = createList(n);
        
        delAbs(L);
        show(L);
    }
    
    return 0;
}

237、求解两个升序序列的中位数

描述

一个长度为L(L≥1)的升序序列S,处在第L/2(若为小数则去掉小数后加1)个位置的数称为S的中位数。例如,若序列S1=(11,13,15,17,19),则S1的中位数是15。两个序列的中位数是含它们所有元素的升序序列的中位数。例如,若S2=(2,4,6,8,20),则S1和S2的中位数是11。现有两个等长升序序列A和B,试实现一个在时间和空间两方面都尽可能高效的算法,找出两个序列A和B的中位数。

输入

多组数据,每组数据有三行,第一行为序列的长度n,第二行为序列A的n个元素,第三行为序列B的n个元素(元素之间用空格分隔)。当n=0时输入结束。

输出

对于每组数据分别输出两个序列的中位数,占一行。

输入样例 1
511 13 15 17 19 2 4 6 8 2061 2 3 4 5 67 8 9 10 11 120
输出样例 1
116
AC代码
#include <iostream>
#include <algorithm>
#include <cmath>

using namespace std;

typedef struct LNode
{
    
    
    int data;
    struct LNode *next;
}LNode, *LinkList;

LinkList createList(int n)
{
    
    
    LinkList L;
    L = new LNode;
    L -> next = NULL;
    
    LinkList r = L;
    while (n --)
    {
    
    
        LNode *tmp;
        tmp = new LNode;
        cin >> tmp -> data;
        
        tmp -> next = NULL;
        r -> next = tmp;
        r = tmp;
    }
    
    return L;
}

/*整体思路:
遍历L1和L2,从小到大将结点存到新链表L3中,
然后由于两个链表合并之后,中位数即为第 n 位,
直接输出第 n 个结点
*/
void getMidian(LinkList L1, LinkList L2, int n)
{
    
    
    LinkList p1 = L1 -> next;
    LinkList p2 = L2 -> next;
    
    LinkList L3 = createList(0);
    LinkList p3 = L3;
    while (p1 && p2)
    {
    
    
        if (p1 -> data < p2 -> data)
        {
    
    
            p3 -> next = p1;
            p3 = p1;
            p1 = p1 -> next;
        }
        else 
        {
    
    
            p3 -> next = p2;
            p3 = p2;
            p2 = p2 -> next;
        }
    }
    
    p3 -> next = NULL;
    
    for (int i = 0; i < n; i ++)
        L3 = L3 -> next;
    
    cout << L3 -> data << endl;
}

int main()
{
    
    
    int n;
    while (cin >> n, n)
    {
    
    
        LinkList L1 = createList(n);
        LinkList L2 = createList(n);
        
        getMidian(L1, L2, n);
    }
    
    return 0;
}

238、查找两个单词链表共同后缀的起始结点

描述

利用单链表表示一个整数序列,通过一趟遍历在单链表中确定值最大的结点。

输入

多组数据,每组数据有两行,第一行为链表的长度n,第二行为链表的n个元素(元素之间用空格分隔)。当n=0时输入结束。

输出

对于每组数据分别输出一行,输出每个链表的最大值。

输入样例 1
52 1 3 5 462 3 10 4 5 14-1 -2 -3 -40
输出样例 1
510-1
AC代码
#include <iostream>
#include <algorithm>
#include <cmath>

using namespace std;

typedef struct LNode
{
    
    
    char ch;
    struct LNode *next;
}LNode, *LinkList;

/*整体思路:
我们使用前插法,这样的话,就不需要遍历了
*/
LinkList createList(int n)
{
    
    
    LinkList L;
    L = new LNode;
    L -> next = NULL;
    
    while (n --)
    {
    
    
        LNode *tmp;
        tmp = new LNode;
        cin >> tmp -> ch;
        
        tmp -> next = L -> next;
        L -> next = tmp;
    }
    
    return L;
}

// test

// void show(LinkList L)
// {
    
    
//     LinkList p = L -> next;
//     while (p -> next)
//     {
    
    
//         cout << p -> ch << " ";
//         p = p -> next;
//     }
//     cout << p -> ch;
//     cout << endl;
// }

void findSame(LinkList L1, LinkList L2)
{
    
    
    LinkList p1 = L1 -> next;
    LinkList p2 = L2 -> next;
    
    while (p1 -> next && p2 -> next)
    {
    
    
        if (p1 -> next -> ch != p2 -> next -> ch)
        {
    
    
            cout << p1 -> ch << endl;
            return ;
        }
        
        p1 = p1 -> next;
        p2 = p2 -> next;
    }
}

int main()
{
    
    
    int n, m;
    while (cin >> n >> m, n && m)
    {
    
    
        LinkList L1 = createList(n);
        LinkList L2 = createList(m);

        findSame(L1, L2);
    }
    
    return 0;
}

239、猴子选大王问题

描述

一堆猴子都有编号,编号是1,2,3 …m,这群猴子(m个)按照1~m的顺序围坐一圈,从第1开始数,每数到第n个,该猴子就要离开此圈,这样依次下来,直到圈中只剩下最后一只猴子,则该猴子为大王。利用单向循环链表模拟此过程,依次输出出圈的猴子编号。

输入

多组数据,每组数据占一行,包括两个数据m和n。m代表猴子个数,n代表步数,m=0且n=0时输入结束。

输出

依次输出出圈的猴子编号,编号之间用空格隔开。

输入样例 1
10 48 30 0
输出样例 1
4 8 2 7 3 10 9 1 6 53 6 1 5 2 8 4 7
AC代码
#include <iostream>

using namespace std;

typedef struct LNode
{
    
    
    int data;
    struct LNode *next;
}LNode, *LinkList;

/*注意,这里的创建函数和之前不太一样,循环单链表要求不能有头结点
因此,使用尾插法创建函数时,我们应该先输入首元结点,然后再创建剩
下的 n - 1个结点,最后使得尾指针指向首元结点
*/

LinkList createList(LinkList &L, int n)
{
    
    
    L = new LNode;
    L -> data = 1;
    L -> next = NULL;
    
    LinkList r = L;
    for (int i = 2; i <= n; i ++)           // 注意这里是从 2 开始
    {
    
    
        LNode *tmp;
        tmp = new LNode;
        tmp -> data = i;
        
        tmp -> next = NULL;
        r -> next = tmp;
        r = tmp;
    }
    
    r -> next = L;                          // 尾指针的next指向头结点
    L = r;                                  // 链表名指向尾指针

    return L;
}

void moneyKing(LinkList L, int m)
{
    
    
    while (L -> next != L)
    {
    
    
        for (int i = 1; i < m; i ++)
            L = L -> next;
        
        LinkList tmp = L -> next;
        cout << tmp -> data << " ";
        L -> next = tmp -> next;            // 输出最后一个猴子,顺便特判空格
        delete(tmp);
    }
    cout << L -> data;
    cout << endl;
}

int main()
{
    
    
    int n, m;
    while (cin >> n >> m, n)
    {
    
    
        LinkList L;
        createList(L, n);
        
        moneyKing(L, m);
    }
    
    return 0;
}

猜你喜欢

转载自blog.csdn.net/weixin_57095511/article/details/121061169