释放结点空间的c语言函数是,链表的学习

起因

记录一下自己线性表的学习过程,当年大学有老师讲的时候听的一塌糊涂,现在研究生二年级了,自己复习一下,总结一些对本科生可用的经验吧

前言

距离我写这篇文章已经过去9个多月了,这9个多月我自认为自己一直在坚持,一直在努力,所以我能回来重构一下这篇文章,顺便说一下,教科书上的数据结构表示还是很规范的,就是命名有些蛋疼。感觉还是叫链表的学习更加准确一些

单链表存储结构

/**

* 单链表的数据结构

*/

typedef struct lnode {

struct lnode *next;

int data;

} lnode, *linklist;

单链表的存储方法

链表的结点结构如图:

f74b271061ecda4d6e821324be70126d.png

链表的结点(Node)包括两个域:

数据域 -- 存储数据元素信息的域

指针域 -- 存储直接后继或者直接前趋的域

n个结点以链接方式存储的线性表称为链表(linked list)

链表的具体存储表示为:

用一组任意的存储单元存放线性表的节点(这组存储单元既可以是连续的,也可以是不连续的)

链表中节点的逻辑顺序和物理顺序不一定一致。为了能够正确的表示节点间的逻辑顺序,因此增加了后继指针(指向后继节点的地址)

指针变量和结点变量

4dd1116716985255cdf013b384e11777.png

指针变量p和结点变量*p的关系

指针变量P

结点变量*P

定义

在变量说明部分显示定义

在指针变量P使用时,通过标准的mallc生成

取值

结点的地址

结点各个域的内容

操作方式

指针变量名访问

通过*取值运算符访问

生成结点变量的标准函数

p = (struct lnode *)malloc(sizeof(struct lnode));

释放结点变量空间的标准函数

free(p);

结点域的访问

(*p).data和(*p).next

p->data和p->next

指针变量p和结点变量*p的关系

指针变量p的值是结点的地址

结点变量*p的值是结点的内容

*((*p).next)是*p后继结点的内容

头指针head和终端节点指针域的表示

单链表中每个节点的存储地址是存放在其前趋节点next域中,而开始节点无前趋,故设头指针head指向开始节点

终端节点无后继,故终端节点的next域为空

注意:

链表可由头指针唯一确定,单链表可由头指针的名字来命名

创建单链表

创建单链表一般有两种考察方法:

简单的创建一个单链表

创建一个有序链表(例如从小到大排序)

下面分别用代码实现

简单的单链表(c语言)

/**

* 构建单链表

*/

void createLink(link **head, int data)

{

link *cur, *pre, *new;

cur = *head;

pre = NULL;

while (cur != NULL) {

pre = cur;

cur = cur->next;

}

new = (link *)malloc(sizeof(link));

new->data = data;

new->next = cur;

if (pre == NULL) {

*head = new;

} else {

pre->next = new;

}

}

因为涉及到对头指针的修改,所以传递二级指针

有序链表(c语言)

/**

* 构建有序链表

*/

void createOrderLink(lnode **head, int value)

{

lnode *pre, *cur, *new;

cur = *head;

pre = NULL;

while (cur != NULL && cur->data < value) {

// 找到第一个大于value的节点

pre = cur;

cur = cur->next;

}

new = (lnode *)malloc(sizeof(lnode));

new->data = value;

new->next = cur;

if (pre == NULL) { // 需要修改头节点

*head = new;

} else {

pre->next = new;

}

}

单链表的查找运算

单链表不是顺序存储结构,因此在单链表里查找一个节点的时间复杂度为O(n)

/**

* 查找指定节点,返回NULL代表没找到

*/

lnode* searchLink(lnode *head, int value)

{

lnode *p = head;

while (p != NULL && p->data != value) {

p = p->next;

}

return p;

}

单链表逆序

写这个题目主要是看到有同学在这篇文章下面留言,我也是为了锻炼一下自己的数据结构功底,这里写一下单链表逆序的实现

f43a42f34ecebfcba8de6d03729fac52.png

注:

一个链表

把d之前的所有结点的next都指向前一个节点,导致链表在c、d之间断裂

不难发现,再调整节点c的指针时,除了知道节点c本身外,还需要知道c的前一个节点b,因为我们需要把c的next指针指向前一个节点,同时为了防止链表断开,我们还需要保存c后面的节点d

/**

* 翻转单链表

*/

void reverseLink(link **head)

{

link *pre, *cur, *post;

cur = *head;

pre = NULL;

while (cur != NULL) {

post = cur->next;

if (post == NULL) {

*head = cur;

}

cur->next = pre;

pre = cur;

cur = post;

}

}

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值