设计一个算法判断单链表中元素是否是递增的。
设计思想:双指针操作
变量说明:
head
表示链表头指针
p
和q
表示两个用来遍历链表的指针节点,且q始终在p之后
bool IsIncrease(LinkList *head)
{
// 代码优先判空,若为空链表,或者只有一个节点,一定是递增的
if(head==NULL || head->next==NULL)
{
return true;
}
// 使用两个指针p和q遍历链表,p始终在q前面一个节点
for(p=head,q=head->next;q!=NULL;p=q,q=q->next)
{
// 比较当前节点p和下一个节点q的值
if(p->data > q->data)
{
// 如果当前节点p的值大于下一个节点q的值,则链表不是递增的
return false;
}
}
return true;
}
设计一个算法将所有奇数移到所有偶数之前。
设计思想:双指针操作
变量说明:
a[]
表示一个整型数组,待处理的数据组
start
表示一个指针,数组将被处理的起始位下标
end
表示一个指针,数组将被处理的结束位下标
start~end是表示数组将被遍历的范围
temp
临时变量用于存储数组元素
(为了不让你把这里的指针和C语言里的指针搞混,下面注释统一叫做指向标)
void quick_move(int a[],int start,int end)
{
int temp;
// 外层循环,确保start指针在end指针左侧,用于控制整个数组的遍历范围
while(start < end)
{
// 从数组的末尾向前移动end指向标直至找到一个奇数
while(end>=0 && a[end]%2==0)
{
end--; // 向前移动end指向标
}
// 从数组的起始位置向后移动start指向标直至找到一个偶数
while(start < end && a[start]%2!=0)
{
start++; // 向后移动start指向标
}
// 如果start仍然在end的左侧,意味着找到了一对需要交换的奇数和偶数,并进行交换
if(start<end)
{
temp=a[start];
a[start]=a[end];
a[end]=temp;
}
}
}
设计一个最优的算法实现输出链表中倒数第k个节点,定义链表结构如下:
struct ListNode
{
int value;
ListNode * next;
}
代码思想:双指针操作(快慢指针),利用p、q两个指针实现,p先走k-1步,然后p和q再同时出发,当p指向最后一个节点时,正好q指向了链表中倒数第k个节点。
ListNode * FindKthToTail(ListNode *head,int k)
{
// 声明并初始化两个用于遍历链表的指针
ListNode *p,*q;
p=head;
q=head;
// 循环,目的是将p移动到正向数第k个节点的位置
for(i=1;i<k;i++)
{
if(p==NULL) return NULL; // 如果p节点为空了,说明链表长度根本没到k,直接返回NULL
p=p->next;
}
// 持续遍历直到p指向成最后一个节点
while(p->next)
{
// p q 两个指针都向下一个节点移动
p=p->next;
q=q->next;
}
return q;
}