赞
踩
单链表:先回顾单链表的特点 逻辑相邻 物理上不一定相连
首先初始化单链表,其中主要保存的是该节点自身的值以及下个节点的地址。
- 有效节点结构体设计:
-
- struct Node{
-
- int data;//数据域
-
- struct Node* next;//指针域
-
- }
以下是单链表的插入以及删除操作:
(一)插入操作
单链表的插入主要分为头插,尾插,以及按位置插入这三种来进行操作。
(1)头插
- bool Insert_head(PNode pn, int val)
- {
- assert(pn!=NULL);//判断不为空
-
- //1.申请新节点
- struct Node* pnewnode = (struct Node*)malloc(1 * sizeof(struct Node));
- assert(pnewnode != NULL);
- pnewnode->data = val;
- pnewnode->next = NULL; // 这里可写可不写
-
-
- //2.找到合适的插入
- //头插时插入在头结点的后边,所以不用找
-
- //3.插入
- pnewnode->next = p->next;//先让C指向B (不能先断开AB中间的线 不然找不到B)
- p->next = pnewnode;//此时再让A指向C
- return true;
- }
(2)尾插
- bool Inseret_tail(PNode pn, int val)
- {
- //1.申请新节点
- struct Node* pnewnode = (struct Node*)malloc(1 * sizeof(struct Node));
- assert(pnewnode != NULL);
- pnewnode->data = val;
- pnewnode->next = NULL; // 这些步骤都与前面的一样
-
- //2.找到合适的插入位置(尾插,需要一个临时指针p指向尾结点)
- struct Node* p = pn;
- for (p; p->next != NULL; p = p->next);
-
- //3.插入
- pnewnode->next = p->next;
- p->next = pnewnode;
-
- return true;
- }
(3)按位置插入(将C插入到AB)
- bool Inseret_pos(PNode pn, int pos, int val)
- {
-
- assert(pos >= 0 && pos <= Get_length(pn));
-
- //1.申请新节点
- struct Node* pnewnode = (struct Node*)malloc(1 * sizeof(struct Node));
- assert(pnewnode != NULL);//确保申请成功
- pnewnode->data = val;//传入val
- pnewnode->next = NULL; //
-
- //2.找到合适的插入位置(按位置插入AB之间,在这里发现规律,pos等于几则让指向头结点的指针p向后走pos步,此时p指向AB的A)
- struct Node* p = pn;
- for (int i = 0; i < pos; i++)
- {
- p = p->next;
- }
- //3.插入
- pnewnode->next = p->next;//先让C指向B (不能先断开AB中间的线 不然找不到B)
- p->next = pnewnode;//此时再让A指向C
-
- return true;
- }
按位置插入这里改变pos的值便可以实现头插和尾插。
(二)删除操作
(1)头删
- bool Del_head(PNode pn)
- {
- //assert
- if (IsEmpty(pn))
- {
- return false;
- }
-
- struct Node* p = pn->next;//pn是头结点 pn->next则是第一个有效节点地址 即头删的节点 则此时p指向待删除节点
- //将待删除节点跨越指向(让带删除节点上家的next域指向下家的地址,而下家的地址在待删节点p的next中)
- pn->next = p->next;
- free(p);
- p = NULL;
-
- return true;
- }
(2)尾删
- bool Del_tail(PNode pn)
- {
- //assert
- if (IsEmpty(pn))
- {
- return false;
- }
-
- //找到待删除节点用p指向(尾删的待删除节点就是倒数第一个节点)
- struct Node* p = pn;
- for (p; p->next != NULL; p = p->next);//当P指向的next域为空停下来
-
- //q指向倒数第二个节点
- struct Node* q = pn;
- for (q; q->next != p; q = q->next);
-
- q->next = pn;//q->next = p->next;
- free(p);
-
- return true;
-
- }
(3)按位置删 同样这里改变pos的值能实现头删和尾删
- bool Del_pos(PNode pn, int pos)
- {
- //assert
- assert(pos >= 0 && pos < Get_length(pn));
- if (IsEmpty(pn))//注意这里的判空操作在后面有定义
- {
- return false;
- }
-
- //先找到待删除节点的上一个节点,用q指向 规律:pos等于几 q就向后走几步
- struct Node* q = pn;
- for (int i = 0; i < pos; i++)
- {
- q = q->next;
- }
- //此时 q指向待删除节点的上一个节点
- //接下来 再让p指向待删除节点 待删除节点在q的next中
- struct Node* p = q->next;
-
- //跨越指向,再释放
- q->next = p->next;
- free(p);//删除待删除节点
-
- return true;
- }
- bool IsEmpty(PNode pn)
- {
- return pn->next == NULL;
- }
(4)按值删
- bool Del_val(PNode pn, int val)
- {
- //assert
- if (IsEmpty(pn))
- {
- return false;
- }
-
- struct Node* p = Search(pn, val);//判断value是否存在
- if (p == NULL)//search返回的地址为空代表没找到
- {
- return false;
- }
- //此时待删除节点存在, 且用指针p指向
-
- struct Node* q = pn;
- for (q; q->next != p; q = q->next);
- //再申请一个临时指针q 让q指向p的上一个节点
-
-
- q->next = p->next;
- free(p);
- //跨越指向,和释放
- return true;
- }
-
- //查找
- struct Node* Search(PNode pn, int val)
- {
- //assert
- for (struct Node* p = pn->next; p != NULL; p = p->next)
- {
- if (p->data == val)
- {
- return p; //找到 则扔出去
- }
- }
-
- return NULL; //没找到,返回NULL地址
- }
以上便是一些单链表的相关操作,简单可直接拿去使用。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。