今天给大家介绍几道常考的关于数据结构线性表的习题。小小拙见,希望对你有帮助哦!
一、移除链表元素
问题描述
删除链表中等于给定值 val 的所有节点。
示例:
输入: 1->2->6->3->4->5->6, val = 6
输出: 1->2->3->4->5
思路
分析:
这道题是关于单链表的操作,这道题比较简单。要删除链表中等于给定值 val 的所有节点,首先应该找到为val 的节点,然后将此节点删除即可。
需要注意的是题目要求为删除等于给定值 val 的所有节点,所以我们需要遍历链表,遇到等于val 的节点,将其删除,直到将整个链表遍历一遍此操作结束。
思路有了之后我们就开始上手写代码,具体代码如下。
代码
#include"list.h"
void RemoveAll(SList *plist, int val)
{
assert(plist != NULL);
SListNode *p = plist->head;
SListNode *prev = NULL;
if (p== NULL)
return;
while (p != NULL)
{
if (p->data == val)
{
SListNode *next = p->next; //保存p->next
//第一个节点值为val
if (prev == NULL)
plist->head = p->next;
else
prev->next = p->next;
free(p);
p = next;
}
else
{
prev = p;
p = p->next;
}
}
return;
}
测试:
void main()
{
SList p;
SListInit(&p);
SListPushFront(&p, 1);
SListPushFront(&p, 2);
SListPushFront(&p, 3);
SListPushFront(&p, 6);
SListPushFront(&p, 4);
SListPushFront(&p, 5);
SListPushFront(&p, 6);
SListShow(&p);
RemoveAll(&p, 6);
SListShow(&p);
}
测试结果:
说明:首先调用头插将元素1、2、3、6、4、5、6插入链表p,在调用RemoveAll函数删除链表中所有值为6的节点。删除后的链表为5->4->3->2->1。
链表结构体定义、初始化、头插等操作在前面也有讲解哦!在这里只负责调用哦!
附上链接:
数据结构——线性表(顺序表、链表)
二、取单链表中间值(带头结点)
问题描述
给定一个带有头结点 head 的非空单链表,返回链表的中间结点。
如果有两个中间结点,则返回第二个中间结点。
思路
分析:这道题也是单链表的操作,通过遍历单链表找出中间结点。最后返回中间结点。
思路:采用两个快慢指针,一起从头结点的后继开始遍历单链表,慢指针走一步相应的快指针走两步,当快指针为NULL的时候慢指针所指的结点就为中间结点。假设一个单链表有n+1个结点(含头结点),则慢指针遍历过的结点数为n/2(n为偶数)或者(n+1)/2,快指针遍历过的结点数为n。
代码
#include"list.h"
SListNode* middleNode(SList *st)
{
SListNode *fast, *slow;
if (st->head == NULL || st->head->next == NULL)
return NULL;
fast = slow = st->head->next;
while (fast&&fast->next != NULL)
{
fast = fast->next->next;
slow = slow->next;
}
return slow->data;
}
测试:
void main()
{
SList p;
SListInit(&p);
SListPushFront(&p, 1);
SListPushFront(&p, 2);
SListPushFront(&p, 3);
SListPushFront(&p, 6);
SListPushFront(&p, 4);
SListPushFront(&p,