链表示意图:
1.创建链表:
创建链表函数:
//创造链表
node* create()
{
node* head, * tail, * pnew;
int score;
head = new(std::nothrow) node;
if (head == nullptr)
{
cout << "no enough memory" << endl;
return nullptr;
}
head->next = nullptr;
tail = head;
cout << "创建学生链表" << endl;
while (1)
{ //创建学生线性链表
cin >> score; //输入成绩
if (score < 0) break;
pnew=new(std::nothrow) node;
if (pnew == nullptr)
{
cout << "no enough memory" << endl;
return nullptr;
}
pnew->score=score;
pnew->next=nullptr; //将新结点的next指向空地址
tail->next = pnew; //新结点插入到链表尾
tail = pnew; //尾指针指向当前的尾结点
}
return head; //返回创建的链表的头结点
}
2.链表的插入:
链表插入函数:
//将pnew所指向的结点插入到以head为头指针的链表的第i个结点之后
void insert(node* head, node* pnew, int i)
{
node* p;
int j;
p = head; //要保证p从头结点开始
for (j = 0; j < i && p != nullptr; j++) //将p指向要插入的前驱结点i(在第i结点后创建新结点,所以j应从0开始,循环i次,让最后的p刚好指向i结点)
p = p->next;
if (p == nullptr) //表明链表中前驱结点i不存在
{
cout << "the 第" << i << "结点不存在" << endl;
return;
}
pnew->next = p->next; //将插入结点的指针域指向第i个结点的后继结点
p->next = pnew; //将第i个结点的指针域指向插入结点
}
3.链表的删除
链表的删除函数:
//删除以head为头指针的链表的第i个结点 void del(node* head, int i) { node* p, * q; int j; if (i == 0) return; //删除的是头指针,则返回,因为当i=0时,表示头结点,不可删除 p = head; //要保证p从头结点开始 for (j = 1; j < i && p->next != nullptr; j++) //这里让j=1而不是0,是为了让循环次数少1(即i-1次),好让p指向i的前驱结点 p = p->next; //将p指向要删除的第i个结点的前驱结点 if (p->next == nullptr) //表明链表中第i个结点不存在 { cout << "the 第" << i << "结点不存在" << endl; return; } q = p->next; //q指向待删除的结点i p->next = q->next; //删除结点i,也可以写成:p->next=p->next->next;(这时p->next=q) delete q; //释放结点i的内存单元 }
4.输出链表
//链表输出操作函数
void print(node* head)
{
node* p;
for (p = head->next; p != nullptr; p = p->next)
cout << p->score << " ";
cout << endl;
cout << endl;
}
5.销毁链表:
//链表销毁函数
void free_(node* head)
{
node* p, * q;
p = head;
while (p->next != nullptr)
{
q = p->next;
p->next = q->next;
delete q; //逐一销毁头结点后面的结点
}
delete head; //最后要销毁头结点
}
第二种写法:
//链表销毁函数
void free_(node* head)
{
node* p, * q;
p = head->next;
while (p!= nullptr)
{
q = p;
p = p->next;
delete q;
}
delete head;
}
6.完整代码:
建立一个学生成绩的线性链表,然后对其进行插入、删除、显示,最后销毁该链表’
#include <iostream>
using namespace std;
struct node
{
int score;
struct node* next;
};
node* create(); //链表创建函数
void insert(node* head, node* pnew, int i); //链表插入函数
void del(node* head, int i); //链表删除函数
void print(node* head); //链表输出函数
void free_(node* head); //链表销毁函数
int main()
{
//创建链表
node* head,*pnew;
head = create();
if (head == nullptr) //创建失败
return -1;
cout << "after create:" << endl;
print(head); //输出链表中的值
//新建一插入的结点
pnew = new(std::nothrow) node;
if (pnew == nullptr)
{
cout << "no enough memory" << endl;
return -1;
}
pnew->score=88;
pnew->next=nullptr;
//将新结点插入结点3后面
insert(head, pnew, 3);
cout << "after insert:" << endl;
print(head);
//删除链表结点3
del(head, 3);
cout << "after del:" << endl;
print(head);
//销毁链表
free_(head);
return 0;
}
//创造链表
node* create()
{
node* head, * tail, * pnew;
int score;
head = new(std::nothrow) node;
if (head == nullptr)
{
cout << "no enough memory" << endl;
return nullptr;
}
head->next = nullptr;
tail = head;
cout << "创建学生链表" << endl;
while (1)
{ //创建学生线性链表
cin >> score; //输入成绩
if (score < 0) break;
pnew=new(std::nothrow) node;
if (pnew == nullptr)
{
cout << "no enough memory" << endl;
return nullptr;
}
pnew->score=score;
pnew->next=nullptr; //将新结点的next指向空地址
tail->next = pnew; //新结点插入到链表尾
tail = pnew; //尾指针指向当前的尾结点
}
return head; //返回创建的链表的头结点
}
//将pnew所指向的结点插入到以head为头指针的链表的第i个结点之后
void insert(node* head, node* pnew, int i)
{
node* p;
int j;
p = head; //要保证p从头结点开始
for (j = 0; j < i && p != nullptr; j++) //将p指向要插入的前驱结点i(在第i结点后创建新结点,所以j应从0开始,循环i次,让最后的p刚好指向i结点)
p = p->next;
if (p == nullptr) //表明链表中前驱结点i不存在
{
cout << "the 第" << i << "结点不存在" << endl;
return;
}
pnew->next = p->next; //将插入结点的指针域指向第i个结点的后继结点
p->next = pnew; //将第i个结点的指针域指向插入结点
}
//删除以head为头指针的链表的第i个结点
void del(node* head, int i)
{
node* p, * q;
int j;
if (i == 0) return; //删除的是头指针,则返回,因为当i=0时,表示头结点,不可删除
p = head; //要保证p从头结点开始
for (j = 1; j < i && p->next != nullptr; j++) //这里让j=1而不是0,是为了让循环次数少1(即i-1次),好让p指向i的前驱结点
p = p->next; //将p指向要删除的第i个结点的前驱结点
if (p->next == nullptr) //表明链表中第i个结点不存在
{
cout << "the 第" << i << "结点不存在" << endl;
return;
}
q = p->next; //q指向待删除的结点i
p->next = q->next; //删除结点i,也可以写成:p->next=p->next->next;(这时p->next=q)
delete q; //释放结点i的内存单元
}
//链表输出操作函数
void print(node* head)
{
node* p;
for (p = head->next; p != nullptr; p = p->next)
cout << p->score << " ";
cout << endl;
cout << endl;
}
//链表销毁函数
void free_(node* head)
{
node* p, * q;
p = head;
while (p->next != nullptr)
{
q = p->next;
p->next = q->next;
delete q; //逐一销毁头结点后面的结点
}
delete head; //最后要销毁头结点
}