链表学习总结
作者:互联网
为什么学习链表。
链表和数组的区别
链表:包括数据域和指针域;
例如:
//例如:
struct student
{
int id;
//定义一个指针是他本身类型
struct student *next;
//内部有一个指针可以指向下一个数据的数据域;
}
动态链表(malloc动态分配内存)和静态链表(基本上不用);
带头链表和不带头链表,但一般都用带头链表。
不带头的:如果在前面插入一个数据,则头节点仍然是指向第二个,头节点不固定。
带头链表:第二个才是有效节点,第一个是头节点。
双向链表:
1、结构体可以嵌套另外一个结构体的任何类型变量:
typedef struct A
{
int id;
char *p;
}A;
typedef struct B
{
int a;
A tmp1;
A *p1;
}B;
2、结构体不能嵌套本结构体的普通变量,(因为结构体本生没有分配内存空间)
本结构体的类型大小无法确定,类型本质; 是固定大小的内存块别名。
3、结构体嵌套本结构体的指针变量是可以的。
typedef struct A
{
int id;
char *p;
}A;
typedef struct B
{
int a;
A tmp1;
A *p1;
struct B tmp2; //error
struct B *next //指针变量类型大小固定
}B;
静态链表:
typedef struct A
{
int data;
char name[100];
A *next; //指针域
}A;
int main()
{
//初始化结构体变量;
stu s1 = {1,"mike",NULL};
stu s1 = {2,"lily",NULL};
stu s1 = {3,"lilei",NULL};
s1.next = &s2; //s1的next指针指向s2
s2.next = &s3;
s3.next = NULL;
}
链表的每一个节点就是一个结构体
指针指向谁就把谁的地址赋值给它;
循环遍历打印链表数据
动态链表:-------单向链表的实现
动态分配空间:malloc
typedef struct Node
{
int id;
struct Node* next;//指针域
}Node;
//创建头节点;
//链表的头结点地址由函数值返回
Node* SListCreat()
{
Node* head = NULL;
//头节点作为标志,不存储有效数据
head = (Node*)malloc(sizeof(Node));
//给head 的成员变量赋值
head->id = -1;//无效数据
head->next = NULL;
//定义一些辅助变量;
Node *pCur = head;
Node* pNew = NULL;
int data;
while (1)
{
printf("请输入数据:");
scanf("%d",&data);
if (data == -1)
{
break;
}
//新节点
pNew = (Node*)malloc(sizeof(Node));
if (pNew == NULL)
{
continue;
}
//如果成功了,给pNew成员赋值
pNew->id = data;
pNew->next = NULL;
//开始链表建立关系
//当前结点的next指向pNew
pCur->next = pNew;
pNew->next = NULL;
//把pCur 移动到pNew,相当于pCure 指向pNew
pCur = pNew;
}
}
链表的插入
插入结点的代码
#include <stdio.h>
#include <string.h>
#include<stdlib.h>
typedef struct Node
{
int id;
struct Node* next;//指针域
}Node;
//创建头节点;
//链表的头结点地址由函数值返回
Node* SListCreat()
{
Node* head = NULL;
//头节点作为标志,不存储有效数据
head = (Node*)malloc(sizeof(Node));
//给head 的成员变量赋值
head->id = -1;//无效数据
head->next = NULL;
//定义一些辅助变量;
Node *pCur = head;
Node* pNew = NULL;
int data;
while (1)
{
printf("请输入数据:");
scanf_s("%d",&data);
if (data == -1)
{
break;
}
//新节点
pNew = (Node*)malloc(sizeof(Node));
if (pNew == NULL)
{
continue;
}
//如果成功了,给pNew成员赋值
pNew->id = data;
pNew->next = NULL;
//开始链表建立关系
//当前结点的next指向pNew
pCur->next = pNew;
pNew->next = NULL;
//把pCur 移动到pNew,相当于pCure 指向pNew
pCur = pNew;
}
return head;
}
//链表的遍历
int SListPrint(Node* head)
{
if (head == NULL)
{
return -1;
}
//取出第一个有效结点(头节点的next)
Node* pCur = head->next;
while(pCur != NULL)
{
printf("%d->", pCur->id);
pCur = pCur->next;
}
printf("NULL\n");
}
int SListNodeInsert(Node* head, int x, int y)
{
if (head == NULL)
{
return -1;
}
Node *pPre = head;
Node* pCur = head->next;
while (pCur !=NULL)
{
//当pCur 不等于空的时候就往下走
if (pCur->id == x)
{
break;
}
//如果没有找到,就往右移动一位
pPre = pCur;
pCur = pPre->next;
}
//给新结点动态分配空间;
Node* pNew = (Node*)malloc(sizeof(Node));\
if (pNew == NULL)
{
return -2;
}
//给新的成员变量赋值
pNew->id = y;
pNew->next = NULL;
//插入指定位置
pPre->next = pNew;
pNew->next = pCur;
return 0;
}
int main()
{
//定义一个头节点
Node* head = NULL;
head = SListCreat();//创建头节点
SListPrint(head);
SListNodeInsert(head,5,4);//在5的后面插入4
SListPrint(head);//打印
printf("\n");
system("pause");
}
删除指定的结点:
#include <stdio.h>
#include <string.h>
#include<stdlib.h>
typedef struct Node
{
int id;
struct Node* next;//指针域
}Node;
//创建头节点;
//链表的头结点地址由函数值返回
Node* SListCreat()
{
Node* head = NULL;
//头节点作为标志,不存储有效数据
head = (Node*)malloc(sizeof(Node));
//给head 的成员变量赋值
head->id = -1;//无效数据
head->next = NULL;
//定义一些辅助变量;
Node *pCur = head;
Node* pNew = NULL;
int data;
while (1)
{
printf("请输入数据:");
scanf_s("%d",&data);
if (data == -1)
{
break;
}
//新节点
pNew = (Node*)malloc(sizeof(Node));
if (pNew == NULL)
{
continue;
}
//如果成功了,给pNew成员赋值
pNew->id = data;
pNew->next = NULL;
//开始链表建立关系
//当前结点的next指向pNew
pCur->next = pNew;
pNew->next = NULL;
//把pCur 移动到pNew,相当于pCure 指向pNew
pCur = pNew;
}
return head;
}
//链表的遍历
int SListPrint(Node* head)
{
if (head == NULL)
{
return -1;
}
//取出第一个有效结点(头节点的next)
Node* pCur = head->next;
while(pCur != NULL)
{
printf("%d->", pCur->id);
pCur = pCur->next;
}
printf("NULL\n");
}
int SListNodeInsert(Node* head, int x, int y)
{
if (head == NULL)
{
return -1;
}
Node *pPre = head;
Node* pCur = head->next;
while (pCur !=NULL)
{
//当pCur 不等于空的时候就往下走
if (pCur->id == x)
{
break;
}
//如果没有找到,就往右移动一位
pPre = pCur;
pCur = pPre->next;
}
//给新结点动态分配空间;
Node* pNew = (Node*)malloc(sizeof(Node));\
if (pNew == NULL)
{
return -2;
}
//给新的成员变量赋值
pNew->id = y;
pNew->next = NULL;
//插入指定位置
pPre->next = pNew;
pNew->next = pCur;
return 0;
}
//删除结点
int SListNodeDL(Node *head,int x)
{
if (head == NULL)
{
return -1;
}
int flag = 0;//建立一个标志位,0 代表没有找到,1代表找到
Node* pPre = head;
Node* pCur = head->next;
while (pCur != NULL)
{
//当pCur 不等于空的时候就往下走
if (pCur->id == x)
{
pPre->next = pCur->next;
free(pCur);
pCur = NULL;
flag = 1;
break;
}
//如果没有找到,就往右移动一位
pPre = pCur;
pCur = pPre->next;
}
if (flag == 0)
{
printf("没有值的为%d",x);
return -2;
}
return 0;
}
int main()
{
//定义一个头节点
Node* head = NULL;
head = SListCreat();//创建头节点
SListPrint(head);
SListNodeInsert(head,5,4);//在5的后面插入4
SListPrint(head);//打印
//删除5 结点
SListNodeDL(head, 5, 4);//在5的后面插入4
SListPrint(head);//打印
printf("\n");
system("pause");
}
清空链表
//清空链表,释放所有结点
int SListNodeDestroy(Node* head)
{
if (head == NULL)
{
return -1;
}
Node* tmp = NULL;
while (head != NULL)
{
//保存head 的下一个结点
tmp = head->next;
free(head);
head = NULL;
//head 指向tmp;
head = tmp;
}
}
标签:总结,学习,head,NULL,pNew,Node,链表,pCur,next 来源: https://blog.csdn.net/weixin_53700782/article/details/122288365