c语言单链表交换节点,每k个节点反转链表(单链表)--数据结构--C语言算法

给你一个链表,每 k 个节点一组进行翻转,请你返回翻转后的链表。k 是一个正整数,它的值小于或等于链表的长度。如果节点总数不是 k 的整数倍,那么请将最后剩余的节点保持原有顺序。

示例: 给你这个链表:1->2->3->4->5 当 k = 2 时,应当返回: 2->1->4->3->5 当 k = 3 时,应当返回: 3->2->1->4->5

说明:你的算法只能使用常数的额外空间。你不能只是单纯的改变节点内部的值,而是需要实际进行节点交换。

思路:例如有如下链表------------------------------------------------------------------

若此时k=3,则我们只需要翻转123 456,7则保留不动 利用头插的话,首先是要将指针指向2的位置,将其移动到1之前,其次是将3移动到1之前,也就是移动两次(k-1次)。 此时我们利用三个指针,如下图所示。  执行 p->next=q->next;实现将q指向的节点腾出后,使其插入到s之后,即: q->next=s->next; s->next=q; 实现2的头插后,执行q=p->next实现将指针q指向数据为3的节点,按照刚才头插2的方式,将3头插到s之后,就完成了第一次翻转k个节点。 如下图所示。  此时,如果利用长度n除以翻转个数k可知需要翻转的次数。 若还需执行下一次翻转,则需要将三个指针指向指定位置,即: q=q->next; s=p; p=p->next; 如图所示。  参考上述首次翻转,再次执行即可。

代码:

#include

#include

typedef int datatype;

typedef struct node{

datatype data;

struct node *next;

}LNode;

LNode *create(int n);//建表

int get_length(LNode *head);//长度

void print(LNode *head);//打印

LNode *fan(LNode *head,int k);//翻转

LNode *create(int n){//建表

LNode *head,*p,*q;

int i;

head=(LNode *)malloc (sizeof(LNode));

p=head;

printf ("   请输入%d个值:",n);

for (i=0;i

{

q=(LNode *)malloc (sizeof(LNode));

scanf ("%d",&q->data);

p->next=q;

p=q;

}

p->next=NULL;

return head;

}

int get_length(LNode *head){//求链表长度

LNode *p;

int n=0;

p=head;

while (p->next!=NULL)

{

n++;

p=p->next;

}

return n;

}

void print(LNode *head){ //打印链表

LNode *p=head;

printf("\n  -------打印-------\n");

while(p->next!=NULL)

{

p=p->next;

printf("  %d",p->data);

}

printf("\n  ------------------\n");

}

LNode *fan(LNode *head,int k){        //翻转

int n=get_length(head);            //定义n为链表长度

int m,i;            //m用来限制头插节点的个数,每翻转一次需要头插k-1个节点

int c=n/k;    //长度n除以每次翻转个数k,即一个链表需要翻转k个元素的次数

LNode *s,*p,*q;

s=head;

p=head->next;

q=p->next;

for(i=0;i

{

for(m=k-1;m>0;m--)//头插k-1次

{

p->next=q->next;

q->next=s->next;

s->next=q;

q=p->next;

}

if(q!=NULL)//完成k个节点的翻转后,若还需翻转k个节点

{           //则将指针指向下次操作的位置

q=q->next;

s=p;

p=p->next;}

}

return head;

}

main()

{

LNode *head=NULL;

int n;//初始表长

printf("   输入初始表长:");

scanf("%d",&n);

head=create(n);

print(head);

int k;//翻转个数

printf("  输入翻转个数k:(k>1且k<=%d)",get_length(head));

scanf("%d",&k);

head=fan(head,k);

printf("  翻转后:");

print(head);

}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值