链表是一种物理存储单元上非连续、非顺序的存储结构,数据元素的逻辑顺序是通过链表中的指针链接次序实现的。链表由一系列结点(链表中的一个元素称为结点)组成,结点可以在运行时动态生成。每个结点包括两部分:一个是存储数据元素的数据域,另一个是存储下一个结点地址的指针域。
利用链表结构可以克服数组链表需要预先知道数据大小的缺点,链表结构可以充分利用计算机内存空间,实现灵活的内存动态管理。但是链表失去了数组随机读取的优点,同时链表由于增加了结点的指针域,空间开销比较大。链表最明显的好处就是,常规数组排列关联项目的方式可能不同于这些数据项目在记忆体或磁盘上排序,数据的存去往往要在不同的排列顺序中转换。链表允许插入和移除表上任意位置上的结点,但是不允许随机存取。链表有很多种不同的类型:单向链表,双向链表和循环链表。
代码实现:
#include<iostream>
#include<string>
using namespace std;
struct StuInfo {
int id;
string name;
};
struct Node {
StuInfo info;
Node *next;
Node(){}
Node(StuInfo x) {
info = x;
next = NULL;
}
};
class LinkedList {
public:
LinkedList();//构造函数
~LinkedList();//析构函数
void insert(StuInfo info, int pos);
void remove(int id);//根据学生号进行删除
int find(int id);//根据学号进行查找,返回结点位置
int getlength();//获得链表长度
void print();//打印链表信息
private:
Node * head;
int length;
};
LinkedList::LinkedList() {//为什么自己编写的默认构造函数要认为head是NULL
head = NULL;
length = 0;
}
void LinkedList::insert(StuInfo info, int pos) {//在链表中插入结点的操作
if (pos < 0) {
cout << "结点位置必须是正整数" << endl;
}
int index = 1;
Node *temp = head;
Node *node = new Node(info);
if (pos == 0) {//新创建的结点变成头指针,next指向head,head变成第二个
node->next = temp;
head = node;
length++;
return;
}
while (index < pos&&temp != NULL) {
temp = temp->next;
index++;
}
if (temp == NULL) {
cout << "插入失败,位置序号超过链表长度" << endl;
return;
}
node->next = temp->next;
temp->next = node;
length++;
return;
}
void LinkedList::remove(int id) {
int pos = find(id);
if (pos == -1) {
cout << "链表中没有该学号,无法删除对应信息" << endl;
return;
}
if (pos == 0) {
head = head->next;
length--;
return;
}
int index = 1;
Node *temp = head;
while (index < pos) {
temp = temp->next;
temp->next = temp->next->next;
length--;
return;
}
}
int LinkedList::find(int id) {
Node *temp = head;
int index = 0;
while (temp != NULL) {
if (temp->info.id == id) {
return index;
}
temp = temp->next;
index++;
}
return -1;
}
int LinkedList::getlength() {
return length;
}
void LinkedList::print() {
if (head == NULL) {
cout << "链表为空,没有信息" << endl;
return;
}
Node *temp = head;
while (temp != NULL) {
cout << temp->info.id << "," << temp->info.name << endl;
temp = temp->next;
}
cout << endl;
return;
}