struct Node* head = NULL;//头节点定义为全局变量,便于操作
struct Node//节点
{
int data;
struct Node* next;
};
struct Node* CreatList()
{
int n;//数据个数
printf("请输入要存储数据的个数:n");
scanf("%d",&n);
int i=1;
struct Node* node=(struct Node*)malloc(sizeof(struct Node));//为第一个节点开辟空间
head =node;
printf("请输入数据n");
while (i < n)
{
scanf("%d", &node->data);
node->next= (struct Node*)malloc(sizeof(struct Node));//为后续节点开辟空间
node = node->next;
i++;
}
scanf("%d", &node->data);//输入尾结点数据
node->next= NULL;
return head;
}
2.头插法
struct Node* Hinsert()//头插
{
int data;
printf("请输入要头插的数据:n");
scanf("%d", &data);
struct Node* node=(struct Node*)malloc(sizeof(struct Node));
node->data = data;
if (head == NULL)//若表为空,插入节点即为头节点
{
head = node;
return head;
}
node->next = head;//原头节点为插入节点的后继节点
head = node;//插入节点成为新的头节点
return head;
}
3.尾插法
struct Node* Tinsert()
{
int data;
printf("请输入要尾插的数据:n");
scanf("%d", &data);
struct Node* node= (struct Node*)malloc(sizeof(struct Node));
node->data = data;
if (head == NULL)//若链表为空,插入节点即为头节点
{
head = node;
return head;
}
struct Node* p = head;
while (p->next)
{
p = p->next;
}
p->next = node;//找到尾结点后将要插入的节点连接
node->next = NULL;
return head;
}
4.反转链表
1.通过反转指针从而反转链表
struct Node* InverseList1()//反转指针实现反转链表
{
if (head == NULL)
return NULL;
struct Node* p1 = NULL;//这里需要定义三个指针
struct Node* p2 =head ;//反转操作通过p1,p2实现
struct Node* p3 = head->next;//定义p3是为了让三个指针逐个后移,从而反转每个指针
while (p2)//p2为空后操作完成
{
p2->next= p1;//指针反向
p1= p2;//p1后移
p2 = p3;//p2后移
if(p3)
p3 = p3->next;//p3后移
}
head = p1;//反转后的头节点为p1
return head;
}
反转操作是由p1,p2完成
2.通过连续头插实现链表反转struct Node* InverseList2() //头插法实现反转链表
{
if (head == NULL)
{
return NULL;
}
struct Node* node = head;//为了保持头节点不变
struct Node* head2 = NULL;//第二个链表头
while (node)
{
struct Node* node3 = node->next;//记录node的下一个位置,以便顺利完成原链表节点后移
node->next=head2;//节点插入,node.next已改变因此需要上一步的node3来记录原本的node.next
head2 = node;//插入节点成为新头结点
node = node3;//原链表节点后移
}
head = head2;
return head;
}
功能展示:
完整代码:
#define _CRT_SECURE_NO_WARNINGS 1 #include#include struct Node* head = NULL; struct Node { int data; struct Node* next; }; struct Node* Hinsert()//头插 { int data; printf("请输入要头插的数据:n"); scanf("%d", &data); struct Node* node=(struct Node*)malloc(sizeof(struct Node)); node->data = data; if (head == NULL) { head = node; return head; } node->next = head; head = node; return head; } struct Node* Tinsert() { int data; printf("请输入要尾插的数据:n"); scanf("%d", &data); struct Node* node= (struct Node*)malloc(sizeof(struct Node)); node->data = data; if (head == NULL) { head = node; return head; } struct Node* p = head; while (p->next) { p = p->next; } p->next = node; node->next = NULL; return head; } struct Node* CreatList() { int n; printf("请输入要存储数据的个数:n"); scanf("%d",&n); int i=1; struct Node* node=(struct Node*)malloc(sizeof(struct Node)); head =node; printf("请输入数据n"); while (i < n) { scanf("%d", &node->data); node->next= (struct Node*)malloc(sizeof(struct Node)); node = node->next; i++; } scanf("%d", &node->data); node->next= NULL; return head; } void ShowList() { if (head == NULL) { printf("链表为空n"); } struct Node* node = head; while (node) { printf("%d ",node->data); node = node->next; } printf("n"); } struct Node* InverseList1()//反转指针实现反转链表 { if (head == NULL) return NULL; struct Node* p1 = NULL; struct Node* p2 =head ; struct Node* p3 = head->next; while (p2) { p2->next= p1; p1= p2; p2 = p3; if(p3) p3 = p3->next; } head = p1; return head; } struct Node* InverseList2() //头插法实现反转链表 { if (head == NULL) { return NULL; } struct Node* node = head; struct Node* head2 = NULL; while (node) { struct Node* node3 = node->next; node->next=head2; head2 = node; node = node3; } head = head2; return head; } int main() { struct Node* head=NULL; head=CreatList(); head=InverseList2(); printf("反转后:n"); ShowList(); head=InverseList1(); printf("反转后:n"); ShowList(); head=Tinsert(); printf("尾插后:n"); ShowList(); head = Hinsert(); printf("头插后:n"); ShowList(); return 0; }
一些感想:完成这些操作,真的能加深对指针的理解,同时能增强对指针的掌控能力。



