一、理论部分
1.节点组成
数据域+指针域(下一个链表的地址)
note:表头变量head存放链表首地址
struct Node{
int data; //数据域可随意定义
struct Node* next; //指针域
}
2.基本操作
a.插入:头插法,尾插法,任意位置插入
b.删除
c.遍历打印
d.逆转链表(递归、迭代)
二、具体实现
1.基本操作——插入
A.尾插法
a.定义头节点为全局变量
#include<stdio.h>
#include<stdlib.h>
struct Node{
int data;
struct Node* next;
};
struct Node* head;
void Insert(int x)
{
struct Node* temp=(struct Node*)malloc(sizeof(struct Node));
temp->data=x;
temp->next=head; //将申请的node插到表头前
head=temp; //更新表头位置
}
void Print()
{
struct Node* temp=head;
printf("链表为\n");
while(temp!=NULL)
{
printf(" %d",temp->data);
temp=temp->next;
}
printf("\n");
}
int main()
{
head=NULL;
printf("输入多少?\n");
int n,x,i;
scanf("%d",&n);
for(int i=0;i<n;i++)
{
printf("请输入!\n");
scanf("%d",&x);
Insert(x);
Print();
}
return 0;
}
b.定义头节点为局部变量
#include<stdio.h>
#include<stdlib.h>
struct Node{
int data;
struct Node* next;
};
Node* Insert(Node* head,int x)
{
struct Node* temp=(struct Node*)malloc(sizeof(struct Node));
temp->data=x;
temp->next=head;
head=temp;
return head;
}
void Print(Node* head)
{
struct Node* temp=head;
printf("链表为\n");
while(temp!=NULL)
{
printf(" %d",temp->data);
temp=temp->next;
}
printf("\n");
}
int main()
{
struct Node* head=NULL;
printf("输入多少?\n");
int n,x,i;
scanf("%d",&n);
for(int i=0;i<n;i++)
{
printf("请输入!\n");
scanf("%d",&x);
head=Insert(head,x);
Print(head);
}
return 0;
}
B.头插法
a.定义头节点为全局变量
替换尾插法a中的Insert函数即可
void Insert(int x)
{
struct Node* temp=(struct Node*)malloc(sizeof(struct Node));
temp->data=x;
temp->next=NULL;
if(head==NULL)
head=temp;
else{
Node *temp1=head;
while(temp1->next!=NULL)
temp1=temp1->next;
temp1->next=temp;
}
}
b.定义头节点为局部变量
替换尾插法b中的Insert函数即可
Node* Insert(Node* head,int x)
{
struct Node* temp=(struct Node*)malloc(sizeof(struct Node));
temp->data=x;
temp->next=NULL;
if(head==NULL)
head=temp;
else{
Node* temp1=head;
while(temp1->next!=NULL)
temp1=temp1->next;
temp1->next=temp;
}
return head;
}
C.任意位置插入
a.定义头节点为全局变量
void Insert(int x,int n)
{
struct Node* temp1=(struct Node*)malloc(sizeof(struct Node));
temp1->data=x;
temp1->next=NULL;
if(n==1)
{
temp1->next=head;
head=temp1;
return;
}
Node* temp2=head;
for(int i=0;i<n-2;i++)
temp2=temp2->next;
temp1->next=temp2->next;
temp2->next=temp1;
}
b.定义头节点为局部变量
Node* Insert(Node* head,int x,int n)
{
struct Node* temp1=(struct Node*)malloc(sizeof(struct Node));
temp1->data=x;
temp1->next=NULL;
if(n==1)
{
temp1->next=head;
head=temp1;
return head;
}
Node* temp2=head;
for(int i=0;i<n-2;i++)
temp2=temp2->next;
temp1->next=temp2->next;
temp2->next=temp1;
return head;
}
2.基本操作——删除
a.定义头节点为全局变量
void Delete(int n)
{
struct Node* temp1=head;
if(n==1)
{
head=temp1->next;
free(temp1);
return;
}
struct Node* temp2;
int i;
for(i=0;i<n-2;i++)
temp1=temp1->next;
temp2=temp1->next;
temp1->next=temp2->next;
free(temp2);
}
b.定义头节点为局部变量
Node* Delete(Node* head,int n)
{
struct Node* temp1=head;
if(n==1)
{
head=temp1->next;
free(temp1);
return head;
}
struct Node* temp2;
int i;
for(i=0;i<n-2;i++)
temp1=temp1->next;
temp2=temp1->next;
temp1->next=temp2->next;
free(temp2);
return head;
}
3.基本操作——链表逆置
A.原地逆置
a.定义头节点为全局变量
void Reverse()
{
struct Node *current,*prev,*next;
current=head;
prev=NULL;
while(current!=NULL)
{
next=current->next;
current->next=prev;
prev=current;
current=next;
}
head=prev;
}
b.定义头节点为局部变量
Node* Reverse(Node* head)
{
struct Node *current,*prev,*next;
current=head;
prev=NULL;
while(current!=NULL)
{
next=current->next;
current->next=prev;
prev=current;
current=next;
}
head=prev;
return head;
}
B.递归逆置
void Reverse(struct Node* p)
{
if(p->next==NULL)
{
head=p;
return;
}
Reverse(p->next);
struct Node* q=p->next;
q->next=p;
p->next=NULL;
}
链表问题一定要画图