后附创建链表的两种方法的示意图。
#include<iostream>
typedef struct Node{
int value;
Node *next;
}node,*linklist;
const int numoflink = 10;//创建有10个节点的链表
const int delete_n = 9;//删除第9个节点
const int delete_forward_n = 2;//删除前两个节点
const int insert_num = 6;//被插入节点的位置
const int insert_value = 100;//插入的值
const int auto_num = 3;//更改第3个节点的值
const int auto_value = 500;//将值更改为100
linklist CreateLink(int n);//创建链表
linklist DeleteNode(node* head,int i);//删除链表第i个元素
linklist DeleteForwardNode(node* head,int n);//删除链表前n个元素
linklist InsertNode(node* head,int n);//在第n个节点后面添加一个节点
linklist AutoNode(node* head,int n,int value);//更改第n个节点的数据
void print(node *head);//打印链表
//链表中第一个节点的存储位置叫做头指针;单链表的第一个节点前附设一个结头,为头结点
//头结点是在链表的开始结点之前附加的一个结点;第一个结点(或称首元结点)是链表中存储第一个数据元素的结点
//创建链表
linklist CreateLink(int n)//返回的是该链表的地址
{
//头插法
node *l = (node*)malloc(sizeof(node));
l->next = NULL;//先将l的下一个指针置空,是为了让指针l指向的下一个链表类型作为链表的第一个数,每次往链表中加数都加到链表中的第1个位置(即指针l指向的位置)。
//for(int i = 0;i < n;i++)
//{
// node *p = (node*)malloc(sizeof(node));//新建一个node结构并为其申请空间
// p->value = i;//给新建的node结构赋值
// p->next = l->next;//赋值p所指的节点(就是l所指的节点,即链表的第2个节点)
// l->next = p;//将l所指的节点更新为p点
//}
//尾插法
node *r;//r指向的始终是该链表的最后一个node结构
r = l;//这个地方是地址之间的赋值,所以对r操作就相当于对l操作(l指向的空间并不改变),即对链表最后一个node结构操作
for(int i = 0;i < n;i++)
{
node *h = (node*)malloc(sizeof(node));
h->value = i;
r->next = h;//将h插入到链表的最后一个node结构的后面
h->next = NULL;//此时h已经是链表的最后一个了,给h的next赋值
r = h;//让r等于链表的最后一个node结构,即h节点
}
return l;
}
//删除链表第i个元素
linklist DeleteNode(node* head,int i)
{
node* p;
p = head;//这个地方是地址之间的赋值,所以对p操作就相当于对head操作(head指向的空间并不改变),即对链表最后一个node结构操作
int num = 0;
//将p移动到要删除的节点的前一个的位置
while(num < i-1 && p->next != NULL)
{
p = p->next;
num++;
}
//获取被删除点后面的链表
node* q = p->next->next;
//将被删除点前后的两端链表连接起来
p->next = q;
return head;
}
//删除链表前n个元素
linklist DeleteForwardNode(node* head,int n)
{
node *p;
p =head->next;
int num = 0;
while(p != NULL)
{
if(num == n-1)
{
//获取删除前n个节点后开始节点的位置,并直接将后一段链表输出
p = p->next;
break;
}
num++;
}
head = p;
return head;
}
//在第n个节点后面插入数据insert
linklist InsertNode(node* head,int n,int insert)
{
node* p;
//这个地方是地址之间的赋值,所以对p操作就相当于对head操作(head指向的空间并不改变),即对链表最后一个node结构操作
p = head;
int num = 0;
//创建一个新的节点存储要插入的元素
node *q = (node*)malloc(sizeof(node));
q->value = insert;
node* h;
while(num <= n && p->next != NULL)
{
//h用于定位被插入节点位置的前一个节点的位置(例如在第6个位置插入节点,则h最后存储的是第5个节点的位置)
h = p;
p = p->next;
num++;
}
//将插入节点与后面的节点连接起来(例如新节点插入到第6个位置,则q这个链表包括了新节点+原链表第6个元素及其之后的元素组成的链表)
q->next = p;
//将两段链表串接起来
h->next = q;
return head;
}
//更改第n个节点的数据
linklist AutoNode(node* head,int n,int value)
{
node* p;
//这个地方是地址之间的赋值,所以对p操作就相当于对head操作(head指向的空间并不改变),即对链表最后一个node结构操作
p = head;
int num = 0;
while(num < n && p->next != NULL)
{
p = p->next;
num++;
}
p->value = value;
return head;
}
//打印链表
void print(node *head) //输出双向链表的所有的元素
{
node *p;
p =head->next;
while(p!=NULL)
{
printf("%d ",p->value);
p=p->next;
}
printf("\n");
}
int main()
{
node *head;
head = CreateLink(numoflink);
printf("初始链表:\n");
print(head);
head = DeleteNode(head,delete_n);
printf("删除第%d个元素:\n",delete_n);
print(head);
head = DeleteForwardNode(head,delete_forward_n);
printf("删除前%d个元素:\n",delete_forward_n);
print(head);
head = InsertNode(head,insert_num,insert_value);
printf("在第%d个节点后面进行插入,数值为%d:\n",insert_num,insert_value);
print(head);
head = AutoNode(head,auto_num,auto_value);
printf("更改第%d点的值,将值更改为%d:\n",auto_num,auto_value);
print(head);
return 0;
}