C++之链表

C++之链表

怎么理解链表?

就是说现在有一个小纸条,上面写着一个抽屉的地址,那个抽屉里面有一些你需要的东西,和一个新的写着地址的小纸条,这个小纸条又指向了一个新抽屉,大体可以这么理解

程序所包含的头文件

#include <iostream>
#include <cstdlib>

using namespace std;

1. 构建抽屉

既然把装有东西和写有地址的小纸条比作抽屉那么我们不妨先写出抽屉的结构体

struct listpoint
{
    int data;  //这是一个数字,也就是抽屉里存放的东西
    listpoint* next;  // 这是一个指向新抽屉的指针
};

这就是一个简单的结构体

我们可以在抽屉里面放下一个抽屉的指针,自然也可以放上一个抽屉的指针:

struct listpoint
{
    int data;
    listpoint* next;
    listpoint* last;
};

我们在抽屉里不仅仅可以放一个数,我们可以往里面放一个收纳盒,例如,在下面的结构体中包含了另一个结构体

struct data
{
    int number;
    char name[10];
    char sex[10];
};
struct listpoint
{
    data* information;
    listpoint* next;
    listpoint* last;
};//那个叫做information的小收纳盒装着一个人的学号,姓名,性别等信息

2. 创建一个链表

2.1 创建一个基础链表

listpoint* create_normal_list(int n)
//链表每一个节点都是指向listpoint结构的指针,所以返回值是listpoint*,其中n是指创建的链表的节点数目
{
    listpoint* head, *normal, *end;  //创建头节点,其他节点,尾节点
    head=(listpoint*)malloc(sizeof(listpoint));  //分配内存
    head->information=(data*)malloc(sizeof(data));  //分配内存
    
    end=head;  //最开始最后一个节点就是头节点,注意因为通过指针可以直接对地址上的东西进行操作,此时end与head指向同一个地址
    
    for(int i=0;i<n;i++)
    {
        normal=(listpoint*)malloc(sizeof(listpoint));//给新节点分配内存
        normal->information=(data*)malloc(sizeof(data));
        cout<<"intput the number:";
        cin>>normal->information->number;  //往新节点存入数据,注意我们只给后面的节点存入数据
        cout<<"input the name:";       //head节点不存数据
        cin>>normal->information->name;
        cout<<"input the sex:";
        cin>>normal->information->sex;
        cout<<"---------------------"<<endl;
        
        end->next=normal;                  //往end后增添新节点
        normal->last=end;                  //新节点的上一个节点就是end
        end=normal;                        //让新节点变成end节点
    }
    end->next=NULL;                        //链表的最后next为空指针
    head->last=NULL;                       //链表的开始last为空指针
    return head;
}

2.2 创建环状链表

操作与之前一样,只不过最后一个节点的next指向头节点

listpoint* creat_loop_list(int n)
{
    listpoint* head,*normal,*end;
    head=(listpoint*)malloc(sizeof(listpoint));
    head->infomation=(data*)malloc(sizeof(data));
    end=head;
    for(int i=0; i<n; i++)
    {
        normal=(listpoint*)malloc(sizeof(listpoint));
        normal->information=(data*)malloc(sizeof(data));
        cout<<"intput the number:";
        cin>>normal->information->number; 
        cout<<"input the name:";       
        cin>>normal->information->name;
        cout<<"input the sex:";
        cin>>normal->information->sex;
        cout<<"---------------------"<<endl;
        
        end->next=normal;
        normal->last=end;
        end=normal;
    }
    end->next=head;                             //环状链表这里与前面基础链表不同
    head->last=end;
    return head;
}

3. 修改链表

3.1 修改数据

因为我们通过指针可以直接修改地址储存的信息,所以函数并不需要返回值

void change_point(listpoint* list, int n, data* ifmation)
{
    listpoint* p;
    p=list;
    for(int i=0, i<n, i++)
    {
        p=p->next;
    }
    p->information=ifmation;
}

3.2 删除节点

void delete_point(listpoint* list, int n)
{
    listpoint* p;
    p=list;
    for(int i=0, i<n, i++)
    {
        p=p->next;
    }
    p->last->next=p->next;
    p->next->last=p->last;
    free(p);
}

3.3 插入节点

void insert_point(listpoint* list, int n, data* ifmation)
{
    listpoint* p;
    p=list;
    for(int i=0; i<n; i++)
    {
        p=p->next;
    }
    listpoint* insertpoint;
    insertpoint=(listpoint*)malloc(sizeof(listpoint));
    insertpoint->information=ifmation;
    insertpoint->last=p;
    insertpoint->next=p->next;
    p->next->last=insertpoint;
    p->next=insertpoint;
}

3.4 搜寻节点

listpoint* search_point(listpoint* list, int n)
{
    listpoint* p;
    p=list;
    for(int i=0; i<n; i++)
    {
        p=p->next;
    }
    return p;
}

4. 输出数据

4.1 输出单个节点数据

void output_point(listpoint* point)
{
    cout<<"The number is:"<<point->information->number<<endl;
    cout<<"The name   is:"<<point->information->name<<endl;
    cout<<"The sex    is:"<<point->information->sex<<endl;
    cout<<"----------------------------"<<endl;
}

4.2 输出整个链表数据

void output_list(listpoint* point)
{
    listpoint* p;
    p=point;
    cout<<endl;
    while((p=p->next)!=NULL)
    {
        output_point(p);
    }
}

4.3 输出部分链表m点到n点

dvoid output_list_part(listpoin* list, int m, int n)
{
    int difference=n-m;
    listpoint* p;
    p=list;
    for(int i=0; i<m; i++)
    {
        p=p->next;
    }
    for(int i=0; i<difference; i++)
    {
        output_point(p);
        p=p->next;
    }
}

5. 完整代码

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

struct data
{
    int number;
    char name[10];
    char sex[10];
};
struct listpoint
{
    data* information;
    listpoint* next;
    listpoint* last;
};

listpoint* creat_normal_list(int n)
{
    listpoint* head, *normal, *end;
    head=(listpoint*)malloc(sizeof(listpoint));
    head->information=(data*)malloc(sizeof(data));
    end=head;
    for(int i=0; i<n; i++)
    {
        normal=(listpoint*)malloc(sizeof(listpoint));
        normal->information=(data*)malloc(sizeof(data));
        cout<<"input the number :";
        cin>>normal->information->number;
        cout<<"input the name   :";
        cin>>normal->information->name;
        cout<<"input the sex    :";
        cin>>normal->information->sex;
        cout<<"-----------------------------"<<endl;
        end->next=normal;
        normal->last=end;
        end=normal;
    }
    end->next=NULL;
    head->last=NULL;
    return head;
}

void output_point(listpoint* point)
{
    cout<<"The number is :"<<point->information->number<<";";
    cout<<"The name   is :"<<point->information->name<<";";
    cout<<"The sex    is :"<<point->information->sex<<";"<<endl;
}

void output_list(listpoint* list)
{
    listpoint* p;
    p=list;
    while((p=p->next)!=NULL)
    {
        output_point(p);
    }
}
//**********************************************************
int main()
{
    listpoint* head;
    head=creat_normal_list(2);
    output_list(head);
    return 0;
}

6. 运行结果

创建两个节点,输入两节点相应data数据,最后打印出两节点内容:

在这里插入图片描述

7. C++中list用法

7.1 list中常用的函数

//list中的构造函数
list();              //声明一个空列表
list(n);             //声明一个有n个元素的列表,每个元素都是由其默认构造函数T()构造出来的
list(n,val);         //声明一个有n个元素的列表,每个元素都是由其复制构造函数T(val)得来的
list(first,last);    //声明一个列表,其元素的初始值来源于由区间所指定的序列中的元素

push_back();         //使用list成员函数push_back和push_front插入一个元素到list中
push_front();        //push_back从list的末端插入,push_front实现从list的首端插入

empty();             //利用empty()判断list是否为空

clear();             //清空list中所有函数

front();             //通过front()可以获得list容器中的头部元素
back();              //通过back()可以获得list容器的最后一个元素

pop_back();          //通过pop_back()删除最后一个元素
pop_front();         //通过pop_front()删除第一个元素

assign();            //具体和vector中的操作类似,也是有两种情况
l1.assign(n, val);   //将l1中的元素变为n个T(val)
l1.assign(l2.begin(), l2.end()); //将l2中的从l2.begin()到l2.end()之间的数值赋给l1

swap();              //交换两个链表,一个是l1.swap(l2);另外一个swap(l1,l2),都可以完成两个链表的交换

reverse();           //通过reverse()完成list逆置

merge();             //合并两个链表并使之默认升序(可更改),l1.merge(l2, greater<int>());调用结束后,l2变成空,l2元素包含原来的l1,l2的元素,并且排好序,升序。

7.2 程序示例一:

#include <iostream>
#include <list>
using namespace std;

int main()
{
    list<int> l1;
    list<int> l2(2, 0);
    list<int>::iterator iter;
    l1.push_back(1);
    l1.push_back(2);
    l2.push_back(3);

    for(iter = l1.begin(); iter != l1.end(); iter++)
    {
        cout<<"l1 :"<<*iter<<"  ";
    }
    cout<<endl<<endl;
    for(iter = l2.begin(); iter != l2.end(); iter++)
    {
        cout<<"l2 :"<<*iter<<"  ";
    }
    cout<<endl<<endl;

    l1.merge(l2);

    cout<<"After the merge"<<endl<<endl;

    for(iter = l1.begin(); iter != l1.end(); iter++)
    {
        cout<<"l1 :"<<*iter<<"  ";
    }
    cout<<endl<<endl;

    if(l2.empty())
    {
        cout<<"l2 is empty!";
    }
    cout<<endl<<endl;
    
    return 0;
}

运行结果:

7.3 程序示例二:

//结合第5部分代码,我们 #include <list> 进行修改
#include <iostream>
#include <list>
using namespace std;

struct data
{
    int number;
    char name[10];
    char sex[10];
};
//**********************************************************
int main()
{
    list<data> l1;
    for(int i=0; i<2; i++)
    {
        data* list_data = (data*)malloc(sizeof(data));
        cout<<"Input the number is :";
        cin>>list_data->number;
        cout<<"Input the name is :";
        cin>>list_data->name;
        cout<<"Input the sex is :";
        cin>>list_data->sex;
        cout<<"--------------------------------"<<endl;
         
        l1.push_back(*list_data);
    }

    list<data>::iterator iter;
    for(iter = l1.begin(); iter != l1.end(); iter++ )
    {
        cout<<"The number is : "<<iter->number<<";";
        cout<<"The name   is : "<<iter->name<<";";
        cout<<"The sex    is : "<<iter->sex<<";"<<endl;
    }

    return 0;
}

运行结果:

在这里插入图片描述

8. 参考链接

https://blog.csdn.net/slandarer/article/details/91863177

https://blog.csdn.net/yas12345678/article/details/52601578

刚开始尝试写代码,如有问题请指出~

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
你可以使用C++来输入链表和输出链表。以下是一个简单的示例代码: ```cpp #include <iostream> // 链表节点的定义 struct ListNode { int val; ListNode* next; ListNode(int x) : val(x), next(nullptr) {} }; // 输入链表 ListNode* inputLinkedList() { int n; std::cout << "输入链表节点个数: "; std::cin >> n; ListNode* head = nullptr; ListNode* curr = nullptr; std::cout << "输入链表节点值: "; for (int i = 0; i < n; i++) { int val; std::cin >> val; ListNode* newNode = new ListNode(val); if (head == nullptr) { head = newNode; curr = newNode; } else { curr->next = newNode; curr = curr->next; } } return head; } // 输出链表 void outputLinkedList(ListNode* head) { std::cout << "链表节点值: "; while (head != nullptr) { std::cout << head->val << " "; head = head->next; } std::cout << std::endl; } int main() { ListNode* head = inputLinkedList(); outputLinkedList(head); return 0; } ``` 在这个示例中,我们首先定义了一个名为 `ListNode` 的结构体,用于表示链表的节点。然后,我们编写了两个函数 `inputLinkedList` 和 `outputLinkedList` 分别用于输入和输出链表。 在 `inputLinkedList` 函数中,我们首先要求用户输入链表节点的个数。然后,我们使用一个循环来读取每个节点的值,并将其插入链表中。最后,函数返回链表的头节点。 在 `outputLinkedList` 函数中,我们遍历链表并输出每个节点的值。 在 `main` 函数中,我们首先调用 `inputLinkedList` 函数来输入链表,然后调用 `outputLinkedList` 函数来输出链表的节点值。 你可以根据自己的需要修改代码,并根据输入和输出格式进行相应的调整。希望对你有帮助!

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值