两个链表合并到一个新的链表
这种的要求不高,就是新建一个链表往里面塞,两个指针指向当前结点,比较和后移就行。
最后有一个是剩下了一部分,就把他直接连到新链表上就行了。
两个单调不增加链表合并到其中一个上面去
这种就不能暴力合并了。
两个指针被插入的建议往前一位,方便插入。
void unioned(struct link* heada,struct link* headb)//将有序表b合并到有序表a上(都是升序的)
{
struct link *pa = heada, *pb = headb->next;//被插入的表要往前一个结点,方便插入
while(pa->next && pb)//保证两个表都没有遍历完
{
if(pa->next->data > pb->data)//a要往后移,被插入
{
struct link* temp = pb;
pb = pb->next;
temp->next = pa->next;//插入
pa->next = temp;
}
else//否则a指针后移
pa = pa->next;
}
if(pb)
pa->next = pb;
free(headb);
}
链表的原地反向
有时候需要反向输出一个链表,这个时候呢,可能你会简单粗暴的直接反向遍历,然后输出结点,但这样未免过于麻烦,然后呢,将链表反过来也是一个办法。
思路是这样的,将原来的头节点拿下来,剩下的用另外一个指针连接,每次都把一号位置拿下来,按头插法装到原来的链表里面去,这样的结果就是反过来的。
代码如下:
void turn(struct link* head)
{
struct link* p=head->next;
head->next=NULL;
struct link* temp=NULL;
while(p)
{
temp=p;
p=p->next;
temp->next=head->next;
head->next=temp;
}
p=head->next;
while(p)
{
cout << p->data<<" ";
p=p->next;
}
}
感觉很巧妙的方法,实现上并不困难。
数组的循环移位:
说给你一个数组,然后需要你以线性阶的时间复杂度,将数组向右移动k位,只允许你使用两个变量。
方法是按给出的k将数组进行划分,先将后k个反向,然后将剩下的反向,最后整体反向一次,结果就是右移k位。
这里给出一个示例,就是这个样子。
有一说一,我确实是想不到,也是csdn膜了一波佬才知道怎么回事的。
下面是代码:
void work(int a[],int n,int k)
{
int tempa,tempb;//两个变量
for(tempa=0;tempa<(n-k)/2;tempa++)//移位前一半
{
tempb=a[tempa];
a[tempa]=a[n-k-1-tempa];
a[n-k-1-tempa]=tempb;
}
for(tempa=n-k;tempa<(2*n-k)/2;tempa++)//后一半
{
tempb=a[tempa];
a[tempa]=a[2*n-k-tempa-1];
a[2*n-k-tempa-1]=tempb;
}
for(tempa=0;tempa<n/2;tempa++)//整体移位
{
tempb=a[tempa];
a[tempa]=a[n-1-tempa];
a[n-1-tempa]=tempb;
}
for(int i=0;i<n;i++)//输出
{
cout << a[i]<< " ";
}
}