https://blog.csdn.net/slandarer/article/details/91863177
上面这个博客写的很好,这是双向链表,随后我还会附上c++中list的库函数用法
双向链表
#include <iostream>
#include <cstdlib>
#include <ctime>
using namespace std;
typedef struct Data {
int num;
string name;
string sex;
}Data;
typedef struct Node{
Data* infromation;
Node* next;
Node* last;
}Node;
Node* creat_list(int n) {
Node* head, * node, * end;
head = new Node;
head->infromation = new Data;
/*分配内存*/
end = head;
for (int i = 0; i < n; i++) {
node = new Node;
node->infromation = new Data;
/*给新节点分配内存*/
cout << "input the num";
cin >> node->infromation->num;
cout << "input the name";
cin >> node->infromation->name;
cout << "input the sex";
cin >> node->infromation->sex;
cout << "------------------------" << endl;
/*往新节点存数据,空头不存数据*/
end->next = node;
node->last = end;
end = node;
}
end->next = NULL;/*end->next = head*/
head->last = NULL;/*head->last = end*/
return head;
}
void change_node(Node* list, int n, Data* info) {
Node* p;
p = list;
for (int i = 0; i < n; i++) {
p = p->next;
}
p->infromation = info;
}
Node * find_node(Node* list, int n) {
Node* p;
p = list;
for (int i = 0; i < n; i++) {
p = p->next;
}
return p;
}
void insert_node(Node* list, int n, Data* info) {/*在第n个之后加一个节点*/
Node* p = find_node(list, n);
Node* node;
node = new Node;
node->infromation = info;
node->next = p->next;
p->next->last = node;
p->next = node;
}
void delete_node(Node* list, int n) {
Node* p = find_node(list, n);
p->last->next = p->next;
p->next->last = p->last;
delete p;
}
void output_list(Node* list) {
Node* p;
p = list;
while (p->next != NULL){
p = p->next;
cout << p->infromation->name;
}
}
int main() {
Node *h = creat_list(3);
delete_node(h, 1);
Data* info = new Data;
info->name = "1";
info->num = 1;
info->sex = "1";
insert_node(h, 1, info);
output_list(h);
}
List用法
list() 声明一个空列表;
list(n) 声明一个有n个元素的列表,每个元素都是由其默认构造函数T()构造出来的
list(n,val) 声明一个由n个元素的列表,每个元素都是由其复制构造函数T(val)得来的
list(n,val) 声明一个和上面一样的列表
list(first,last) 声明一个列表,其元素的初始值来源于由区间所指定的序列中的元素
** begin()和end():**通过调用list容器的成员函数begin()得到一个指向容器起始位置的iterator,可以调用list容器的 end() 函数来得到list末端下一位置,相当于:int a[n]中的第n+1个位置a[n],实际上是不存在的,不能访问,经常作为循环结束判断结束条件使用。
** push_back() 和push_front():**使用list的成员函数push_back和push_front插入一个元素到list中。其中push_back()从list的末端插入,而 push_front()实现的从list的头部插入。
** empty():利用empty()** 判断list是否为空。
** resize():** 如果调用resize(n)将list的长度改为只容纳n个元素,超出的元素将被删除,如果需要扩展那么调用默认构造函数T()将元素加到list末端。如果调用resize(n,val),则扩展元素要调用构造函数T(val)函数进行元素构造,其余部分相同。
** clear():** 清空list中的所有元素。
** front()和back():** 通过front()可以获得list容器中的头部元素,通过back()可以获得list容器的最后一个元素。但是有一点要注意,就是list中元素是空的时候,这时候调用front()和back()会发生什么呢?实际上会发生不能正常读取数据的情况,但是这并不报错,那我们编程序时就要注意了,个人觉得在使用之前最好先调用empty()函数判断list是否为空。
** pop_back和pop_front():**通过删除最后一个元素,通过pop_front()删除第一个元素;序列必须不为空,如果当list为空的时候调用pop_back()和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()); 调用结束后l2变为空,l1中元素包含原来l1 和 l2中的元素,并且排好序,升序。其实默认是升序,greater()可以省略,另外greater()是可以变的,也可以不按升序排列。
#include <iostream>
#include <list>
using namespace std;
int main() {
list<int> l1, l2;
l1.push_back(1);
l1.push_back(3);
l2.push_back(2);
l2.push_back(4);
l1.merge(l2);
for (list<int>::iterator it = l1.begin(); it != l1.end(); it++) {
cout << *it << endl;
}
}