提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档
一、pandas是什么?
1.介绍
链表是一种物理存储单元上非连续、非顺序的存储结构,数据元素的逻辑顺序是通过链表中的指针链接次序实现的。链表由一系列结点(链表中每一个元素称为结点)组成,结点可以在运行时动态生成。每个结点包括两个部分:一个是存储数据元素的数据域,另一个是存储下一个结点地址的指针域。
2.具体思路
我们可以设计一个链表结构体,记录链表的头结点和长度,再设计一个节点结构体,包含指向下一节点的指针和记录的数据,在需要添加或删除节点时,从头节点遍历到相应位置修改节点指针指向,再进行开辟新节点和释放旧节点的操作。
二、程序
1.代码
#include <iostream>
#include "./link_list.h"
using namespace std;
typedef struct LinkNode //链表节点
{
void *data; //数据域,指向自定义数据类型
LinkNode *next; //指针域
} LinkNode;
typedef struct //链表结构体
{
LinkNode header;
int length;
} Header;
struct Person //数据结构体
{
int age;
char name[20];
};
Header *init_link_list(void);
void insert(Header *list, int pos, void *data);
void remove(Header *list, int pos);
void print(Header *list, void (*my_print)(void *data));
void my_print(void *data);
int get_length(Header *list);
void empty(Header *list);
void destroy_list(Header *list);
//初始化
Header *init_link_list(void)
{
Header *my_list = new Header;
if (my_list == NULL)
{
return NULL;
}
my_list->length = 0;
my_list->header.next = NULL;
my_list->header.data = NULL;
return my_list;
}
//插入节点
void insert(Header *list, int pos, void *data)
{
if (list == NULL || data == NULL)
{
return;
}
if (pos < 0 || pos > list->length)
{
pos = list->length;
}
LinkNode *prev_node = &list->header; //前驱节点
LinkNode *current_node = list->header.next; //后继节点
LinkNode *new_node = new LinkNode;
new_node->data = data;
new_node->next = NULL;
for (int i = 0; i < pos; i++)
{
current_node = current_node->next;
prev_node = prev_node->next;
}
prev_node->next = new_node;
new_node->next = current_node;
list->length++;
}
//删除节点
void remove(Header *list, int pos)
{
if (list == NULL)
{
return;
}
if (pos < 0 || pos > list->length)
{
return;
}
LinkNode *prev_node = &list->header; //前驱节点
LinkNode *current_node = list->header.next; //后继节点
for (int i = 0; i < pos; i++)
{
current_node = current_node->next;
prev_node = prev_node->next;
}
prev_node->next = current_node->next;
delete current_node;
current_node = NULL;
list->length--;
}
//打印链表
void print(Header *list, void (*my_print)(void *data))
{
if (list == NULL)
{
return;
}
LinkNode *current_node = list->header.next;
for (int i = 0; i < list->length; i++)
{
my_print(current_node->data);
current_node = current_node->next;
}
}
//自定义类型打印(回调)
void my_print(void *data)
{
if (data == NULL)
{
return;
}
struct Person *p = (struct Person *)data;
cout << p->name << " " << p->age << endl;
}
//返回链表长度
int get_length(Header *list)
{
if (list == NULL)
{
return -1;
}
return list->length;
}
//清空链表
void empty(Header *list)
{
if (list == NULL)
{
return;
}
LinkNode *current = list->header.next;
for (int i = 0; i < list->length; i++)
{
LinkNode *next = current->next;
delete current;
current = next;
}
list->header.next = NULL;
list->length = 0;
}
//销毁链表
void destroy_list(Header *list)
{
if (list == NULL)
{
return;
}
empty(list);
delete list;
list = NULL;
}
int main(int argc, char const *argv[])
{
Header *list = init_link_list();
struct Person p1 = {20, "老王"};
struct Person p2 = {21, "老张"};
struct Person p3 = {22, "老李"};
insert(list, 0, &p1);
insert(list, 0, &p2);
insert(list, 1, &p3);
cout << "删除前长度:" << get_length(list) << endl;
remove(list, 0);
cout << "删除后长度:" << get_length(list) << endl;
cout << "打印:" << endl;
print(list, my_print);
empty(list);
cout << "清空后长度:" << get_length(list) << endl;
destroy_list(list);
return 0;
}
2.运行结果
删除前长度:3
删除后长度:2
打印:
老李 22
老王 20
清空后长度:0