计算机考研408的算法题详解

2019年真题

题目:设线性表L=(a1,a2,a3,......,a(n-2),a(n-1),a(n)),采用带头结点的单链表保存,链表中的结点定义如下。请设计一个空间复杂度为O(1)且时间上尽可能高效的算法,重新排列L中的各结点,得到新线性表L'=(a1,a(n),a2,a(n-1),a3,a(n-2),......)。

typedef struct node {
    int data;
    struct node *next;
} NODE;

 思路分析:①先找到链表的中心结点,使用两个指针p,每次p走一步,q走两步,当q到链表尾时,p正好在链表中心结点。②将链表后半段原地逆置。③将单链表前后两段中依次各取一个结点,进行重排。

NODE *reverseList(NODE *head) {
	//将指针全部反转 
	NODE* pre = NULL;
	NODE* cur = head;
	NODE* tmp = NULL;//记录cur的下一个结点
	while(cur != NULL) {
		//记录当前节点的下一个节点
		tmp = cur->next;
		//然后将当前节点指向pre
		cur->next = pre;
		//pre和cur节点都前进一位
		pre = cur;
		cur = tmp;
	}
	return pre;
} 

void changeList(NODE *head) {
	NODE *p, *q, *temp;
	p = q = head;
	//1、找到中间结点 
	while(q->next != NULL) {
		p = p->next;
		q = q->next;
		if(q->next != NULL) {//q走两步。用if再判断一次是为了防止走一步后就已到队尾,出现NULL->next异常 
			q = q->next;
		}
	} 
	//此时p指向链表L的中心结点 n/2,向下取整。 
	//2、后半段链表反转。 
	NODE *back = reverseList(p-next);//将后半段链表逆置,back指向后半段链表的第一个节点。 
	NODE *pre = head->next;  
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值