链表逆序、链表按指定个数逆序

链表:是一种链式存储的结构,它不要求逻辑上相邻的元素在物理位置上也相邻。

因此,为了表示每个数据元素ai与其后继数据元素ai+1之间的逻辑关系,对于数据元素ai来说,它不仅要存储自己的本身信息,还需要存储一个指示其直接后继的信息,这两部分组成数据元素ai的存储映像,称为结点

结点包括两个域:存储本身信息的数据域和存储直接后继位置的指针域。

有这样n个结点链接成的链表为线性表的链式存储。一般结点的定义形式:

typedef struct Node
{
    type data;
    struct Node* next;
}Node,*Linklist;

一般会在第一个结点前设置一个头结点,头结点的数据域可以不存储任何信息,头结点的指针域存储指向第一个结点的指针。

L为头结点 不存储任何数据 a4为最后一个结点,其指针域为空。

所以每定义一个新的结点,不仅要对它输入数据,还要将链表的尾结点指向新结点,新结点的指针要及时置为空。

注意:链表的空间分配是由malloc(sizeof(Node))来申请的 删除结点最后也要通过free()来释放内存。

 

链表逆序:

void reverse(Linklist link)
{
	if (link == NULL || link->next == NULL)
	{
		return;
	}

	Node* pre = link->next; //记录前一个节点,第一次为第一个结点
	Node* node = pre->next; //记录当前节点 如果为NULL 说明除了头结点之外只有一个结点,不需要循环
	while(node != NULL)   //当前节点存在 则开始逆序
	{	
		Node* nextnode = node->next;  //记录当前节点的下一个节点 方便后续逆序操作 以免后续节点丢失
		node->next = pre;   //让当前节点的后继指针指向前一个节点
		pre = node; //让前一个节点记录当前节点
		node = nextnode; //让当前节点记录下一个节点
	}
	link->next->next = NULL;   //当原来的第一个元素变为尾元素 尾元素的下一个元素置为NULL
	link->next = pre;  //pre经过循环后变成尾元素,让链表的头结点指向pre
}

用图像来解析一下 一个初始链表如下所示

第一次进入循环时,将当前结点指向前结点,如下所示

pre和node都记录原链表后继结点,供下一次循环调用

第二次进入循环时,nextnode记录后一结点

第二循环结束后

最后循环体结束后再对link的头结点和尾结点进行操作。

 

链表按指定个数逆序,剩下的若不够个数则按剩下个数逆序:比如链表为1 2 3 4 5 6 7 8 要按每3位逆序 即3 2 1 6 5 4 8 7

void reverseByNum(Node* prev,Node* node,int num){
	if(node == NULL)
		return;
	Node* prevNode = node;
	Node* curNode = node->next;
	int count = 1;
	while(curNode != NULL){
		Node* nextNode = curNode->next;
		curNode->next = prevNode;
		prevNode = curNode;
		curNode = nextNode;
		count++;
		if(count == num){
			Node* tmp = prev->next;
			prev->next->next = curNode;
			prev->next = prevNode;
			reverseByNum(tmp,curNode,num);
			return;
		}
	}
	prev->next->next = curNode;
	prev->next = prevNode;
}

void reverses(Link link,int num){//封装一手手
	Node *node = link->next;	
	reverseByNum(link,node,num);
}

 

 

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值