目录
目录
1.链表的基本概念
2.创建单链表
3.插入结点(头部插入法)
4.遍历链表
5.链表结点的删除
6.链表的释放
7.翻转链表
什么是链表?
其实就是很多个相同类型结构体成线性排列,“串”在一起,形成一条链,叫做链表。
怎么做到结构体和结构体之间能“串”在一起?
链表中的每个结构体都相当于一个结点,我们创建的结构体,分为两块区域,
一块叫数据域,用于存储我们想存放的信息,
另一块叫指针域,用于存放下一个结点的地址(这样才能访问下一个结点,乃至整条链表)
比如我现在创建了一个结构体,如下
typedef struct Node
{
int data;//数据域
struct Node* next;//指针域
}Node;
我们要将若干个相同的结构体串联成如下效果
静态链表的使用,利于理解上图
struct Node
{
int data;
struct Node* next;
};
void test()
{
struct Node node1 = { 1,NULL };
struct Node node2 = { 2,NULL };
struct Node node3 = { 3,NULL };
struct Node node4 = { 4,NULL };
struct Node node5 = { 5,NULL };
node1.next = &node2;
node2.next = &node3;
node3.next = &node4;
node4.next = &node5;
//遍历列表
struct Node* pCurrent = &node1;
while (pCurrent)
{
printf("%d\n", pCurrent->data);
pCurrent = pCurrent->next;
}
}
int main()
{
test();
return 0;
}
创建一个单链表,相当于创造一个作为头的结点,头结点后的链表身,属于链表插入的内容
Node* creathead()
{
Node* headnode = (Node*)malloc(sizeof(Node));//创建一个指针,要么初始化,要么制空
if (headnode == NULL)
{
printf("创建头节点失败\n");
exit(0);
}
headnode->next = NULL;
return headnode;
}
这样我们就创建好了头结点,然后把头结点的地址返回主函数,有了头结点的地址就可以访问整个链表
(借用一下其他博主的图)
Node* creatnode(int input)
{
Node* node = (Node*)malloc(sizeof(Node));
if (node == NULL)
{
printf("添加数据失败\n");
exit(0);
}
node->data = input;
node->next = NULL;
return node;
}
void PrintNode(Node* headnode)
{
Node* pMove = headnode->next;//定义一个辅助指针,用于遍历
while (pMove)
{
printf("%d\n", pMove->data);
pMove = pMove->next;
}
}
void DelectNode(Node* headnode)
{
int input = 0;
scanf("%d", &input);
Node* pMove = headnode;//定义一个辅助指针,用于遍历
while (pMove->next != NULL && pMove->next->data != input)//这里不能调换顺序!
{ //要先判断pMove->next是否为NULL,
pMove = pMove->next; //再判断pMove->next->data,
} //否则就读取了空指针的data,会报错!
if (pMove->next == NULL)
{
printf("该结点不存在\n");
exit(0);
}
Node* d = pMove->next;
pMove->next = pMove->next->next;
free(d);
printf("该结点已删除\n");
}
void FreeNode(Node* headnode)
{
Node* pMove = headnode;
Node* pfree = pMove;
while (pMove != NULL)
{
pMove = pMove->next;
free(pfree);
pfree = pMove;
}
printf("链表已释放成功\n");
}
最后是全部源代码
typedef struct Node
{
int data;
struct Node* next;
}Node;
Node* creathead()
{
Node* headnode = (Node*)malloc(sizeof(Node));//创建一个指针,要么初始化,要么制空
if (headnode == NULL)
{
printf("创建头节点失败\n");
exit(0);
}
headnode->next = NULL;
return headnode;
}
Node* creatnode(int input)
{
Node* node = (Node*)malloc(sizeof(Node));
if (node == NULL)
{
printf("添加数据失败\n");
exit(0);
}
node->data = input;
node->next = NULL;
return node;
}
void PrintNode(Node* headnode)
{
Node* pMove = headnode->next;//定义一个辅助指针,用于遍历
while (pMove)
{
printf("%d\n", pMove->data);
pMove = pMove->next;
}
}
void DelectNode(Node* headnode)
{
int input = 0;
scanf("%d", &input);
Node* pMove = headnode;//定义一个辅助指针,用于遍历
while (pMove->next != NULL && pMove->next->data != input)//这里不能调换顺序!
{ //要先判断pMove->next是否为NULL,
pMove = pMove->next; //再判断pMove->next->data,
} //否则就读取了空指针的data,会报错!
if (pMove->next == NULL)
{
printf("该结点不存在\n");
exit(0);
}
Node* d = pMove->next;
pMove->next = pMove->next->next;
free(d);
printf("该结点已删除\n");
}
void FreeNode(Node* headnode)
{
Node* pMove = headnode;
Node* pfree = pMove;
while (pMove != NULL)
{
pMove = pMove->next;
free(pfree);
pfree = pMove;
}
printf("链表已释放成功\n");
}
int main()
{
int input = 0;
Node* headnode = creathead();//创建头结点
Node* p = headnode;//辅助指针
for (int i = 0; i < 5; i++)//头部插入法
{
scanf("%d", &input);
Node* node = creatnode(input);//创建结点
node->next = p->next;
p->next = node;
}
//endinsert(headnode);
DelectNode(headnode);
PrintNode(headnode);//遍历链表
FreeNode(headnode);
return 0;
}
Node* ReverseList(Node* headnode)//翻转无头链表
{
Node* n1;//还未考虑链表小于3的情况
Node* n2;
Node* n3;
n1 = NULL;
n2 = headnode;
n3 = headnode->next;
while (n2 != NULL)//迭代
{
n2->next = n1;
n1 = n2;
n2 = n3;
if (n3)
{
n3 = n3->next;
}
}
printf("链表翻转成功\n");
return n1;
}
typedef struct Node
{
int val;
Node* pre;
Node* next;
}Node;
Node* CreatList()
{
Node* head = (Node*)malloc(sizeof(Node));
head->val = NULL;
head->pre = head;
head->next = head;
return head;
}
void ListPushBack(Node* head,int val)//尾插法
{
Node* node = (Node*)malloc(sizeof(Node));
Node* tail = head->pre;
node->val = val;
node->pre = tail;
node->next = head;
tail->next = node;
head->pre = node;
}
void DelectNode(Node* head,int val)//尾删法
{
Node* cur = head->next;
while (cur != head)
{
if (cur->val == val)//指定数据的删除(还不够完善)
{
cur->pre->next = cur->next;
cur->next->pre = cur->pre;
cur->next = NULL;
cur->pre = NULL;
free(cur);
printf("删除成功");
break;
}
cur = cur->next;
}
if (cur == head)
{
printf("该结点不存在\n");
}
}
void SearchNode(Node* head, int val)
{
Node* cur = head->next;
while (cur != head)
{
if (cur->val == val)//指定数据的删除(还不够完善)
{
printf("找到了,该结点存在\n");
break;
}
cur = cur->next;
}
if (cur == head)
{
printf("该结点不存在\n");
}
}
void ModifyNode(Node* head, int val)
{
int input = 0;
Node* cur = head->next;
while (cur != head)
{
if (cur->val == val)//指定数据的删除(还不够完善)
{
printf("您要将数据%d修改为:\n",val);
scanf("%d", &input);
cur->val = input;
printf("修改成功\n");
break;
}
cur = cur->next;
}
if (cur == head)
{
printf("该结点不存在\n");
}
}
void ListPrint(Node* head)
{
Node* cur = head->next;
while (cur->next != head)
{
printf("%d<->", cur->val);
cur = cur->next;
}
printf("%d\n", cur->val);
}
int main()
{
Node* head = CreatList();
int i = 0;
int val = 0;
printf("请输入您要添加的数据:\n");
for (i = 0; i < 5; i++)
{
scanf("%d", &val);
ListPushBack(head, val);
val = 0;
}
ListPrint(head);
printf("请选择您要修改的数据:\n");
scanf("%d", &val);
ModifyNode(head, val);
ListPrint(head);
printf("请选择您要删除的数据:\n");
scanf("%d", &val);
DelectNode(head, val);
ListPrint(head);
printf("请选择您要查找的数据\n");
scanf("%d", &val);
SearchNode(head, val);
return 0;
}