单向链表(以加入数字为例)
链表是由一系列节点构成,每个节点包含两个部分,数据和指针。可以把链表看成是不是连续存放的数组
创建链表
class Node{//节点
public:
string name;
int num;//要储存的数据
Node *next;//指针,指向下一个数据,如果没有就是空指针
Node() :next(nullptr) {}//一些必要的构造函数
Node(int num) :num(num), next(nullptr) {}
Node(Node& n) :num(n.num), next(nullptr) {}
void display()//输出数据
{
cout<<num;
}
};
有了节点还需要一条链子将这些节点连起来,还需要Link类
class Link{
private:
Node*head;//头指针,指向第一个数据
public:
Link()//构造函数,定义头指针的值。
{
head = new Node();
}
~Link()//析构函数,使用完后删除创建的链表
{
while (head != nullptr)//如果头指针不是指向空指针的话,说明还有节点没有删除
{
Node* p = head->next;//新创建一个p指针指向透支真的下一个
delete(head);//删除现在的头指针
head = p;//头指针指向p(也就是之前头指针的下一个)
}
}
};
插入节点
头插
void headInsert(int n)//头部插入
{
Node* newNode = new Node(n);//建立一个新节点存放数字n
newNode->next = head->next;//新节点的next指针指向头指针的next
head->next = newNode;//头指针的next 指向新创建的节点
}
函数里面的第二行和第三行是有顺序关系,如果先做第三行,头指针原来指向的数据就会丢失,导致整个链表只剩新插入的指针,所以是先把指针传到新创建的节点,在把指针指向新创建的节点。
尾插
void tailInsert(int n)
{
Node* p = head;//创建一个新节点
while (p->next != nullptr)//先找到原来链表的最后一个,上文说过如果没有一下个数据就是空指针,所以如果不是空指针,说明这个节点就不是链表的最后一个,p一直往下找。
p = p->next;
Node* newNode = new Node(n);//建立一个新节点
p->next = newNode;//将找到的原来的链表的最后一个的next指向新节点的地址,使新节点成为链表的最后一个
}
同样,顺序是不能变的。
按照数据的一定顺序插入
void insertByNum(int n)//按照数字的顺序从小到大排序
{
Node* p = head;//从头指针开始查找
while (p->next != nullptr && p->next->num < n)//如果不是该节点不是最后一个节点并且下一个数据比n小,就继续查找下去
p=p->next;
Node* newNode = new Node(n);//建立一个新节点
newNode->next = p->next;//新节点的指针指向p(查找到的p的下一个比n大或者已经查找到最后一个节点)
p->next = newNode;//现在的p的下一个指向新节点
}
while里面的顺序是不能变的,否则可能导致越界,第四行和第五行也不能改变顺序,如果交换会导致节点丢失。
删除节点
void deleteByNum(int n)//按照输入的n删除带有n的数据的节点
{
Node* p = head->next;//新建一个p指向头指针的下一个
Node* q = head;//新建一个q指向头指针
while (p != nullptr)//找到最后一个节点为止
{
if (p->num == n)//如果找到了
{
q->next = p->next;//上一个的next直接指向找到这个节点的next
delete(p);//删除节点
break;//退出循环
}
else//如果没找到
{
p = p->next;//p继续指向下一个
q = q->next;//q继续指向下一个
}
}
}
查询节点
遍历节点并输出
void traverse()
{
bool k = 0;//按照格式输出
Node* p = head->next;//新建节点p指向第一个数据
while (p != nullptr)//遍历到最后一个
{
if (k)
cout << " ";
else
k = 1;
p->display();//输出数据
p = p->next;//继续输出下一个数据
}
cout << endl;
}
根据某个特定的值查找数据
void displayByName(string s)//根据输入的名字查找
{
Pony* p = head;//从头指针开始
while (p->pNext != nullptr && p->name != s)//根据&&的短路性先判断该节点是不是最后一个节点,再判断如果名字不匹配
p = p->pNext;//就寻找下一个
p->display();//找到了就输出
}