@单链表学习记录
xdm好,大晚上来随便写点东西,空闲时间去做点温故的事情是有必要的,如果能帮助到正在学习的同学,那就会更加开心了。
今天温习一下单链表。单链表是数据开发常用的数据结构,这里重新温习一下单链表的数据结构与常用的几种方式比如链表创建、添加新节点、链表反转、链表中数据排序等
【本菜鸡只介绍数据结构只用C】
前言
引用一下百度对于单链表的介绍
【一组地址任意的存储单元存放线性表中的数据元素。链表中的数据是以结点来表示的,每个结点的构成:元素(数据元素的映象) + 指针(指示后继元素存储位置),元素就是存储数据的存储单元,指针就是连接每个结点的地址数据。】
单链表中的重点已经用加粗标注啦,来同学们自己去摇一摇小脑袋瓜想一下这几个概念
线性:
元素:
指针:
ok,皮就皮到这里,接下来开始写程序吧
单链表的数据结构
struct List{
int Val; //XDM,这就是百度介绍链表时所说的元素,就是用来存储数据的存储单元
struct List *Next; //这就是介绍里说的指针,指向线性后继元素存储的位置
};
__________________________________________________________________
这样用typedef 声明一个结构体变量‘L’,后续新建节点会省去不停的写struct List的麻烦哦
typedef struct List{
int Val;
struct List *next;
}L;
新建链表
其实呢,新建链表和建立链表头节点是一个意思啦,就是建议一个链表节点就完事了
//这里无需传递参数,
struct List *CreateList( ){
struct List *head; //新建节点变量
head = (struct List*)malloc(sizeof(struct List)); //变量初始化
return head; //返回节点指针的地址
}
是不是还挺简单的
添加链表元素
添加链表元素这里就是新建一个节点,让链表的最后一个节点指向新节点,新节点指向NULL就完成了
void AddNewNode(struct List *Lhead){
//创建两个节点,一个节点用作存放单链表首节点的地址,另一个用作新增的节点
struct List *node, *head;
node = (struct List*)malloc(sizeof(struct List));
head = Lhead;
//遍历到链表的最后一个节点
while(Lhead->Next != NULL){
Lhead = Lhead->Next;
}
//最后一个节点指向新增加的节点即可
Lhead->Next = node;
node->Next = NULL;
return head;
}
删除链表元素
链表删除的操作一般需要配合数据,比如删除链表中元素为3的节点。咱就是说不想整的太麻烦。大概讲一下就行了,链表是由节点、指针连接起来的,要删除的元素被删除后只要保证【被删节点的前节点】指针指向【被删节点的下一个节点】即可
0->1->2->3->4
0->1->3->4
void DeleteNode(struct List *head, int x){
//这里就假设链表足够长,要删除链表的第x个节点,我这里假设就删除链表的第三个节点
x = 3; //删除第三个节点
//新建节点存放链表首地址
struct List*phead;
phead = head;
//遍历到被删节点的前一个节点
for(int i = 0; i < 1; i ++){
head = head->next;
}
//当前head节点表示的第二个节点,也就是1节点
head->next =head->next->next; 将第二个节点的指针指向第四个节点的地址即可
return phead;
}
链表反转
这个啊,蜀蜀给你们将,真的很爱考
就是如图
1->2->3->4
变成
4->3->2->1
酱紫
//head:三节点中的永远的第一个节点
//curNode:三节点操作中的永远的第二个节点
//NextNode:三节点操作中的永远的第三个节点
//如果亲爱的看到这里了,听一句,编码注意格式,一定要注意缩进,关于缩进和空格的使用让代码美观真的很重要!!!
struct List* reservalList(struct List* head){
//新建变量初始化,永远少不了,反转链表只需要三个节点即可,永远以curNode节点作为主要操作的节点和条件判断的节点
struct List *curNode, *NextNode;
curNode = (struct List*)malloc(sizeof(struct List));
NextNode = (struct List*)malloc(sizeof(struct List));
curNode = head->next;
while(curNode != NULL){
if(curNode->next != NULL){
NextNode = curNode->next;
} else {
break;
}
//这里让curNode指向前一个节点,即可完成第二个节点指向第一个节点,即第一个反转
// 1 <- 2
curNode->next = head;
//Head节点赋值第二个节点的地址,作为新的三个节点中的第一个节点
head = curNode;
//curNode节点赋值第三个节点的地址,作为新的三个节点中的第二个节点
curNode = NextNode;
}
return curNode;
}
单链表排序
单链表排序就涉及val了,这里跟二维数组排序的概念差不多,通过两个循环就可以很方便的完成链表的排序。当然方法有很多,我这里就记录一下最简单实现的好了
struct ListNode* sortInList(struct ListNode* head ) {
// write code here
struct ListNode* tmp = (struct ListNode*)malloc(sizeof(struct ListNode));
struct ListNode* phead = (struct ListNode*)malloc(sizeof(struct ListNode));
phead = head;
for (; head != NULL; head = head ->next) {
for (tmp = head ; tmp != NULL; tmp = tmp->next) {
if (head->val < tmp->val) {
continue;
} else {
int tmp_val = head->val;
head->val = tmp->val;
tmp->val = tmp_val;
}
}
}
return phead;
}