赞
踩
//单链表属于线性表
链表是数据结构中线性表的一种,其中的每个元素实际上是一个单独的结构体对象,而所有对象都通过每个元素中的指针链接在一起。它是以结构体为节点,将一个结构体看成数据域和指针域两个部分,数据域用于存储数据,指针域用于连接下一个节点。链表中每个结构体对象叫做节点,其中第一个数据节点叫做链表的首元节点;如果第一个节点不用于存储数据,只用于代表链表的起始点,则这个节点称为链表的头节点。
1、单链表没有固定的长度,可以自由增加节点。 2、单链表能够实现快速的插入删除数据。 3、与数组类似,单链表也是一种线性数据结构。 4、单链表的尾结点的后继必定指向空。 单链表和数组的区别:数组是顺序存储的,而单链表是链式存储的。
- //结构体类型:单链表节点的类型
- struct node
- {
- int id;//节点要保存的数据
- struct node*next;//指针成员:指向下一个节点
- };
- //初始化单链表
- //申请一个头节点:让head指向这个节点
- //头节点:不保存数据,单链表开头的标志
- struct node* init()
- {
- //temp是一个临时指针变量:保存从堆区申请的内存首地址
- struct node*temp = (struct node*)malloc(sizeof(struct node));
- temp->id = 0;
- temp->next = NULL;
- return temp;
- }
- //头插法三步骤
- //1、申请新节点,把数据放进这个新节点S
- //2、新节点S指针域保存头节点的下一个节点的地址
- //3、头节点指针保存新节点S的地址
- void insert(struct node*head,int data)//data:要增加的元素值
- {
- //1、申请新节点,把数据放进这个新节点S
- struct node*S = (struct node*)malloc(sizeof(struct node));
- S->id = data; //新节点保存要增加的元素值
- //2、新节点S指针域保存头节点的下一个节点的地址
- S->next = head->next;
- //3、头节点指针保存新节点S的地址
- head->next = S;
- }
-
- //尾插法
- //1、定义一个指针变量P,P用来保存当前单链表中的最后一个节点的地址
- //2、定义一个指针变量S,申请一个新的节点(保存要增加的数据),生成新节点S
- //3、新节点S指针为空,节点P的指针域指向新节点S
- void insertEnd(struct node*head, int data)
- {
- //1、定义一个指针变量P,P用来保存当前单链表中的最后一个节点的地址
- struct node*p = head;
- while (p->next != NULL)//P不是单链表中最后一个节点
- {
- //p++;//不可以的,因为内存 不连续
- p = p->next;//p指向下一个节点
- }
- //循环执行完之后,p指向单链表中的最后一个节点
- //2、定义一个指针变量S,申请一个新的节点(保存要增加的数据),生成新节点S
- struct node*S = (struct node*)malloc(sizeof(struct node));
- S->id = data; //新节点保存要增加的元素值
-
- //3、新节点S指针为空,节点P的指针域指向新节点S
- S->next = p->next;
- p->next = S;
- }
- void print(struct node*head)
- {
- if (head == NULL)
- {
- printf("单链表不存在\n\n");
- return;
- }
- struct node*p = head->next;
-
- while (p != NULL)//是p指向下一个节点,当p是最后一个节点之后的NULL,结束循环
- {
- printf("%d --> ", p->id);
- p = p->next;
- }
- printf("NULL\n\n");
- }
- /**************单链表——元素的删除*****************/
- //1、定义两个指针变量P1、P2,P1指向头节点,P2指向头节点的下一个节点
- //2、使用循环,使P1、P2同时往后移,当P2指向要删除的这个节点时,结束循环
- //3、P1指向的节点里面的指针 保存 P2 下一个节点的地址
- //4、释放P2指向的节点
- void del(struct node*head,int val)//val表示要被删除的值
- {
- //P1指向删除节点的前驱节点
- //P2指向删除节点
- struct node*P1 = head;
- struct node*P2 = head->next;
- while (P2 != NULL)//P2不为NULL,正在遍历单链表中的数据
- {
- if (P2->id == val)//当P2指向要被删除的节点时
- {
- P1->next = P2->next;
- free(P2);
- P2 = P1->next;
- }
- else//两个指针变量同时往后移
- {
- P1 = P1->next;
- P2 = P2->next;
- }
- }
- }
- int find(struct node*head, int val)//val表示要查找的值
- {
- int flag = 0;//标记是第几个节点
- struct node*p = head->next;
- while (p != NULL)
- {
- flag++;
- if (p->id == val)//找到要查找的值
- {
- printf("这个值:%d 在第 %d 个位置\n\n", p->id,flag);
- }
- p = p->next;
- }
- return val;
- }
- void change(struct node*head, int val,int data)//val表示要被修改的值 ,data要被修改成的值
- {
- struct node*p = head->next;
- while (p != NULL)
- {
- if (p->id == val)//找到要查找的值
- {
- p->id = data;
- }
- p = p->next;
- }
- }
- //需要改变主函数中head的值吗? 需要
- void Allclear(struct node**list)//&head传过来 list=&head
- {
- struct node*p = (*list)->next;//p指向头节点的下一个节点
- while (p != NULL)
- {
- //1、头节点里面的指针成员 保存 p指向的下一个节点的地址
- //2、释放p节点
- //3、更新要删除的节点,p指向头节点后的第一个节点
- (*list)->next = p->next;
- free(p);
- p = (*list)->next;
- }
- free(*list);//释放头节点
- *list = NULL;
- }
- //***********单链表——头节点的初始化
- //头指针变量——保存单链表节点的首地址
- struct node* head = NULL;
- head = init();
-
- //单链表元——元素的增加
- //头插法
- for (int j = 1; j <= 5; j++)
- {
- insert(head, j);
- }
- print(head);
-
- //尾插法
- for (int j = 1; j <= 5; j++)
- {
- insertEnd(head, j);
- }
- print2(head);
-
- //单链表元——元素的删除
- del(head, 3);
- print(head);
-
- //单链表元——元素的查找、修改
- find(head, 3);
- change(head, 3, 66);
- print(head);
-
- //单链表元——节点的释放
- Allclear(&head);
- printf("%p", head);
- print(head);
-
- return 0;
- }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。