本系列文章为浙江大学陈越、何钦铭数据结构学习笔记,前面的系列文章链接如下:
数据结构基础:P1-基本概念
数据结构基础:P2.1-线性结构—>线性表
数据结构基础:P2.2-线性结构—>堆栈
数据结构基础:P2.3-线性结构—>队列
数据结构基础:P2.4-应用实例—>多项式加法运算
数据结构基础:P2.5-应用实例—>多项式乘法与加法运算-C实现
数据结构基础:P3.1-树(一)—>树与树的表示
数据结构基础:P3.2-树(一)—>二叉树及存储结构
数据结构基础:P3.3-树(一)—>二叉树的遍历
数据结构基础:P3.4-树(一)—>小白专场:树的同构-C语言实现
数据结构基础:P4.1-树(二)—>二叉搜索树
数据结构基础:P4.2-树(二)—>二叉平衡树
数据结构基础:P4.3-树(二)—>小白专场:是否同一棵二叉搜索树-C实现
文章目录
一、逆转链表
1.1 什么是抽象的链表
题目:给了你一个单链表的头节点,再给你一个整数K。然后要求你把每K个节点逆转一下,然后最后返回给用户的是那个逆转以后链表的头结点的指针。
比较有意思的一个问题是:有同学在论坛上面发言时候说,链表这个东西是不是只对C和C++语言的程序才有意义,我用的是JAVA, JAVA里头没有指针,没有指针哪来的链表呢?所以在这里我们很有必要重申一下,到底什么是链表:
我们来看一下我们这道题目的样例输入。第一行是给了这个单链表头结点的位置、链表结点数量、需要反转的结点数量。接着下面几行分别给出了每个结点的位置、在链表中的位次、每个结点下一个结点的位置。
那我们在编程实现的时候到底怎么来存这样一个链表呢?一个非常直截了当的方法就是整个模拟一个真实的链表在内存里面存在的状态。也就是说,我开一个充分大的结构数组来代表内存空间,这种情况下,什么是一个结点所处的位置?结点的位置就是它在这个数组里面的下标,而元素的下标是可以用一个整数来表示的。在这里我们说到一个指针的时候,实际上我们说的是一个整数,这个整数记录的是下一个结点在这个数组里面的下标而已。因此,链表对应的结构如下:
1.2 链表逆转算法
接下来我们来看怎么样实现单链表的逆转。在这个单链表的前面我个人习惯加一个头结点,虽然说在一定程度上是浪费了空间,但是如果这个头结点的空间对你不是那么紧要的话,那么加一个头结点会使后面的很多操作变得比较简单。这是我们原始的链表的形态。
我们希望完成了逆序以后,整个链表应该是长得这个样子的:前面四个结点的方向是从4指到3指到2指到1的,然后这个头结点要指在4这个位置,而1后面接的是剩余部分的这个链表。
那么怎么去实现它呢?
对应伪代码如下:
Ptr Reverse( Ptr head, int K )
{
cnt = 1;
new = head->next;
old = new->next;
while ( cnt < K ) {
tmp = old->next;
old->next = new;
new = old; old = tmp;
cnt++;
}
head->next->next = old;
return new;
}
1.3 测试数据
我们在设计一道题目的测试数据的时候,至少有两个方面是一定要考虑到的。