链表
一、链表的逻辑,存储结构

链表由链表头节点及其他节点构成。其中每一个节点都有其对应的数据和指向下一元素的指针。
二、链表的代码实现

三、实现简单的链表

三、链表的操作
一、添加节点至链表头部
实现思路:
1.将数据写入一个新建的节点
2.将表头指向的地址(即首个节点的地址)写入新建的节点
3.将表头指向的地址改为新建的节点
代码:
#include<iostream>
using namespace std;
struct Node{
int data;//数据
struct Node* next;//指向下一数据元素的指针
};
struct Node* head;//链表头
void Insert(int _data){
Node* temp = new Node();
temp->data = _data;//写入数据
temp->next = head;//写入首位节点指针,使节点联结原首各节点。
head = temp;//使链表头指向该节点
}
void Print(){
Node* temp = head;
cout<<"List is:";
while(temp!=NULL){
cout<<" "<<temp->data;//输出当前节点的数据
temp = temp->next;//使该临时节点指向下一节点
}
cout<<endl;
}
int main (){
head = NULL; //设置链表头为空指针
Insert(1);//在首位插入节点
Insert(2);
Insert(3);
Insert(4);
Print();
//DONE
}
运行结果:
二、任意位置插入节点
实现思路:
1.将数据写入一个新建的节点
2.如果不是插入到首位,则取出要插入位置的前一位的节点中保存的下一节点地址,赋给新建节点,使得新建节点与下一节点联结。如果插入到第一位,那么将节点指向的地址指向表头,然后将表头指向该节点。
3.将前一位节点的下一节点地址修改为新建节点的地址,使得新建节点与前一节点形成联结。
代码:
#include<iostream>
using namespace std;
struct Node{
int data;//数据
struct Node* next;//指向下一数据元素的指针
};
struct Node* head;//链表头
void Insert(int pos,int _data){
Node* temp = new Node();
temp->data = _data;//写入数据
temp->next = NULL;
if(pos == 1){//插入到首位的情况
temp->next = head;
head = temp;
}else{//插入到非首位的情况
Node* temp2 = head;
for(int i =0;i<pos-2;i++){//循环到插入位前一位
temp2 = temp2->next;
}
if(temp2 == NULL) exit(0);//插入位置非法
temp->next = temp2->next;//将插入节点指向的地址修改为下一节点(即插入位置前一节点保存的地址)
temp2->next = temp;//将前一位节点指向的地址改为该节点的地址。
}
}
void Print(){
Node* temp = head;
cout<<"List is:";
while(temp!=NULL){
cout<<" "<<temp->data;//输出当前节点的数据
temp = temp->next;//使该临时节点指向下一节点
}
cout<<endl;
}
int main (){
head = NULL; //设置链表头为空指针
Insert(1,2);
Insert(2,3);
Insert(3,4);
Insert(4,5);
Print();
}
运行结果:
三、删除某个节点
实现思路:
1.如果删除位置为首位,则将第二位设为表头
2.如果删除位置为非首位,则将第其前一位指向的地址指向其下一位元素,并将删除位置的空间释放。
代码:
#include<iostream>
using namespace std;
struct Node{
int data;//数据
struct Node* next;//指向下一数据元素的指针
};
struct Node* head;//链表头
void Delete(int pos){
Node* temp = head;
if(pos == 1){
free(head);
head = temp->next;
}else{
for(int i =0;i<pos-2;i++){//获得删除位前一位
temp = temp->next;
}
Node* temp2 = temp->next;//获得删除位
temp->next = temp2->next;//将删除为前一位指向的地址改为删除位下一位
free(temp2);
}
}
void Insert(int pos,int _data){
Node* temp = new Node();
temp->data = _data;//写入数据
temp->next = NULL;
if(pos == 1){//插入到首位的情况
temp->next = head;
head = temp;
}else{//插入到非首位的情况
Node* temp2 = head;
for(int i =0;i<pos-2;i++){//循环到插入位前一位
temp2 = temp2->next;
}
if(temp2 == NULL) exit(0);//插入位置非法
temp->next = temp2->next;//将插入节点指向的地址修改为下一节点(即插入位置前一节点保存的地址)
temp2->next = temp;//将前一位节点指向的地址改为该节点的地址。
}
}
void Print(){
Node* temp = head;
cout<<"List is:";
while(temp!=NULL){
cout<<" "<<temp->data;//输出当前节点的数据
temp = temp->next;//使该临时节点指向下一节点
}
cout<<endl;
}
int main (){
head = NULL; //设置链表头为空指针
Insert(1,1);
Insert(2,2);
Insert(3,3);
Insert(4,4);
Insert(5,5);
Insert(6,6);
Insert(7,7);
Insert(8,8);
Delete(1);
Delete(5);//本次删除的是 2 3 4 5 6 7 8 的第五位6.
Print();
}
运行结果:
反转链表(迭代方式)
实现思路:
保存当前节点前,当前,后节点地址。先将当前节点存储的地址转为前一节点,随后转至后一节点进行操作
代码:
#include<iostream>
using namespace std;
struct Node{
int data;//数据
struct Node* next;//指向下一数据元素的指针
};
struct Node* head;//链表头
void Reserve(){
Node* pre,*current,*next;
current = head;
pre = NULL;
while(current!=NULL){
next = current->next;//保存下一节点地址
current->next = pre;//将当前节点的下一地址改为前一位
//移动至下一节点
pre = current;//保存当前地址到pre
current = next;//修改current地址
}
head = pre;//修改表头
}
void Insert(int pos,int _data){
Node* temp = new Node();
temp->data = _data;//写入数据
temp->next = NULL;
if(pos == 1){//插入到首位的情况
temp->next = head;
head = temp;
}else{//插入到非首位的情况
Node* temp2 = head;
for(int i =0;i<pos-2;i++){//循环到插入位前一位
temp2 = temp2->next;
}
if(temp2 == NULL) exit(0);//插入位置非法
temp->next = temp2->next;//将插入节点指向的地址修改为下一节点(即插入位置前一节点保存的地址)
temp2->next = temp;//将前一位节点指向的地址改为该节点的地址。
}
}
void Print(){
Node* temp = head;
cout<<"List is:";
while(temp!=NULL){
cout<<" "<<temp->data;//输出当前节点的数据
temp = temp->next;//使该临时节点指向下一节点
}
cout<<endl;
}
int main (){
head = NULL; //设置链表头为空指针
Insert(1,1);
Insert(2,2);
Insert(3,3);
Insert(4,4);
Insert(5,5);
Insert(6,6);
Insert(7,7);
Insert(8,8);
Print();
Reserve();
Print();
}
运行结果:
扩展
一、打印一个链表(递归的方式)
#include<iostream>
using namespace std;
struct Node{
int data;//数据
struct Node* next;//指向下一数据元素的指针
};
struct Node* head;//链表头
void Print(struct Node* p){
if(p != NULL){
cout<<" "<<p->data;
Print(p->next);
}else{
return;
}
}
void Insert(int pos,int _data){
Node* temp = new Node();
temp->data = _data;//写入数据
temp->next = NULL;
if(pos == 1){//插入到首位的情况
temp->next = head;
head = temp;
}else{//插入到非首位的情况
Node* temp2 = head;
for(int i =0;i<pos-2;i++){//循环到插入位前一位
temp2 = temp2->next;
}
if(temp2 == NULL) exit(0);//插入位置非法
temp->next = temp2->next;//将插入节点指向的地址修改为下一节点(即插入位置前一节点保存的地址)
temp2->next = temp;//将前一位节点指向的地址改为该节点的地址。
}
}
int main (){
head = NULL; //设置链表头为空指针
Insert(1,1);
Insert(2,2);
Insert(3,3);
Insert(4,4);
Insert(5,5);
Insert(6,6);
Insert(7,7);
Insert(8,8);
Print(head);
}
运行结果:
逆转链表(递归的方法)
#include<iostream>
using namespace std;
struct Node{
int data;//数据
struct Node* next;//指向下一数据元素的指针
};
struct Node* head;//链表头
void Reserve(struct Node* p){
if(p->next==NULL){
head = p;
return;
}
Reserve(p->next);
struct Node* temp = p->next;
temp->next = p;
p->next = NULL;
}
void Print(struct Node* p){
if(p != NULL){
cout<<" "<<p->data;
Print(p->next);
}else{
return;
}
}
void Insert(int pos,int _data){
Node* temp = new Node();
temp->data = _data;//写入数据
temp->next = NULL;
if(pos == 1){//插入到首位的情况
temp->next = head;
head = temp;
}else{//插入到非首位的情况
Node* temp2 = head;
for(int i =0;i<pos-2;i++){//循环到插入位前一位
temp2 = temp2->next;
}
if(temp2 == NULL) exit(0);//插入位置非法
temp->next = temp2->next;//将插入节点指向的地址修改为下一节点(即插入位置前一节点保存的地址)
temp2->next = temp;//将前一位节点指向的地址改为该节点的地址。
}
}
int main (){
head = NULL; //设置链表头为空指针
Insert(1,1);
Insert(2,2);
Insert(3,3);
Insert(4,4);
Insert(5,5);
Insert(6,6);
Insert(7,7);
Insert(8,8);
Reserve(head);
Print(head);
}
运行结果:
本文介绍了链表的基本概念,包括链表的逻辑和存储结构,并详细讲解了如何使用C++实现链表的创建、在链表头部添加节点、任意位置插入节点、删除节点以及迭代和递归方式反转链表的操作。通过代码示例和运行结果展示了具体步骤。







619

被折叠的 条评论
为什么被折叠?



