单链表——单链表的逆转

最早据说是微软的一道题目,就是给出一个单链表和一个整数K,按照每K个个顺序进行逆转

废话不多说,看函数代码

//单链表的逆转,每k个逆转一下子
PtrToNode Reverse(PtrToNode h,int K)
{
	int cnt=0;
	int len=length(h);
	PtrToNode newNode;
	PtrToNode oldNode;
	int i;
	PtrToNode tmp=NULL;
	PtrToNode tmphead=NULL;
	while(cnt+K<=len){
		cnt+=K;
		i=1;
		if(cnt==K){
			newNode=h->Next;
			oldNode=newNode->Next;
			while(i<K){
				tmp=oldNode->Next;
		        oldNode->Next=newNode;
		        newNode=oldNode;
		        oldNode=tmp;
			    i++;
		    }
		}
		else{
			newNode=tmphead->Next;
			oldNode=newNode->Next;
			while(i<K){
				tmp=oldNode->Next;
		        oldNode->Next=newNode;
		        newNode=oldNode;
		        oldNode=tmp;
			    i++;
		    }
		}
		if(cnt==K){
			tmphead=h->Next;//表示上面上一段序列里的最后
			h->Next->Next=oldNode;
	        h->Next=newNode;
		}
		else{
			tmphead->Next->Next=oldNode;
	        tmphead->Next=newNode;
			for(int j=0;j<K;j++)
				tmphead=tmphead->Next;
		}
		
	}
		
	return h;
};

以上是最重要的一段代码


其示意图如上图所示

下面来看执行结果


哈哈哈,没毛病

下面上完整代码

#include <stdio.h>  
#include <stdlib.h>  
  
typedef struct Node *PtrToNode;  
struct Node {  
    int Data;  
    PtrToNode   Next;  
};  
  
//读入链表的函数
PtrToNode Read();
//打印链表的函数
void Print( PtrToNode L );
//单链表的逆转,每k个逆转一下子
PtrToNode Reverse(PtrToNode h,int K);
//求表长    
int length(PtrToNode ptrl);
  
int main()  
{  
	for(int i=0;i<3;i++){
    printf("请输入第%d/3组数据:\n",i+1);
    PtrToNode L1;  
    L1 = Read();  
    int K;
	printf("请输入K:\n");
	scanf("%d",&K);
	Reverse(L1,K);
	Print(L1);
	printf("\n");
	}
	system("pause");
    return 0;  
}  
  
PtrToNode Read()    
{    
  int len = 0;  
  int num = 0;  
  PtrToNode h = NULL;  
  PtrToNode last = NULL;  
    
  h = ( PtrToNode )malloc( sizeof( struct Node ) );//建立头结点  
  h->Next = NULL;  
  last = h;  
    
  scanf( "%d",&len );  
  while(len){  
    scanf( "%d",&num );  
    PtrToNode node = ( PtrToNode )malloc( sizeof( struct Node ) );  
    node->Data = num;  
    node->Next = NULL;  
    last->Next = node;  
    last = node;  
    len--;  
  }  
  return h;  
}    
void Print( PtrToNode L )    
{    
   
     L=L->Next;  
    if(L==NULL){  
      printf("NULL\n");   
        return;  
    }    
    while(L!=NULL){    
        printf("%d ",L->Data);    
        L=L->Next;    
    }    
    putchar('\n');    
};

//求表长    
int length(PtrToNode ptrl){    
    PtrToNode p=ptrl;    
    int j=0;    
    while(p){    
        p=p->Next;    
        j++;    
    }
    return j-1;    
}; 

//单链表的逆转,每k个逆转一下子
PtrToNode Reverse(PtrToNode h,int K)
{
	int cnt=0;
	int len=length(h);
	PtrToNode newNode;
	PtrToNode oldNode;
	int i;
	PtrToNode tmp=NULL;
	PtrToNode tmphead=NULL;
	while(cnt+K<=len){
		cnt+=K;
		i=1;
		if(cnt==K){
			newNode=h->Next;
			oldNode=newNode->Next;
			while(i<K){
				tmp=oldNode->Next;
		        oldNode->Next=newNode;
		        newNode=oldNode;
		        oldNode=tmp;
			    i++;
		    }
		}
		else{
			newNode=tmphead->Next;
			oldNode=newNode->Next;
			while(i<K){
				tmp=oldNode->Next;
		        oldNode->Next=newNode;
		        newNode=oldNode;
		        oldNode=tmp;
			    i++;
		    }
		}
		if(cnt==K){
			tmphead=h->Next;//表示上面上一段序列里的最后
			h->Next->Next=oldNode;
	        h->Next=newNode;
		}
		else{
			tmphead->Next->Next=oldNode;
	        tmphead->Next=newNode;
			for(int j=0;j<K;j++)
				tmphead=tmphead->Next;
		}
		
	}
		
	return h;
};

### C语言实现单链表逆序算法 #### 定义链表结构体 为了实现单链表的逆序,首先定义一个简单的链表节点结构体。 ```c #include <stdio.h> #include <stdlib.h> // 定义链表结点结构体 typedef struct Node { int data; struct Node* next; } Node; ``` #### 创建新节点函数 创建一个新的节点并初始化其数据成员。 ```c Node* create_node(int value) { Node* new_node = (Node*)malloc(sizeof(Node)); if (!new_node) { printf("内存分配失败\n"); exit(1); } new_node->data = value; new_node->next = NULL; return new_node; } ``` #### 插入节点到链表头部 此功能用于构建初始链表以便测试逆序逻辑。 ```c void insert_at_head(Node** head_ref, int new_data) { Node* new_node = create_node(new_data); // 更新新的头指针指向旧的头 new_node->next = *head_ref; // 将新的节点设为新的头 *head_ref = new_node; } ``` #### 打印链表内容 辅助函数用来展示当前链表中的元素顺序。 ```c void print_list(Node* node) { while (node != NULL) { printf("%d -> ", node->data); node = node->next; } printf("NULL\n"); } ``` #### 使用迭代法进行链表逆序 通过迭代的方式逐个改变各节点之间的连接方向来完成整个列表的反转过程[^2]。 ```c Node* reverse_iteratively(Node* head) { Node* prev = NULL; Node* current = head; Node* next = NULL; while (current != NULL) { next = current->next; // 记录下一个位置 current->next = prev; // 反转链接关系 prev = current; // 移动prev向前一步 current = next; // 移动current向前一步 } head = prev; // 新的头是指向原尾部的位置 return head; } ``` 以上就是完整的C语言中实现单链表逆序的方法之一——迭代法。这种方法易于理解和实现,并且只需要常数级别的额外空间开销即可完成操作[^4]。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

拉风小宇

请我喝个咖啡呗

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值