[2019统考真题]
设线性表L=(a1, a2, a3, an-2, an-1, an)采用带头结点的单链表保存,
链表中的结点定义如下:
typedef struct node {
int data;
struct node* next;
}NODE;
请设计一个空间复杂度为0(1)且时间上 尽可能高效的算法,重新排列乙中的各结点,得到线性表L=(a1, an, a2, an-1, a3, an-1..)
要求:
1)给出算法的基本设计思想。
1.先找到链表的中间节点;
分别设立一个快指针和一个慢指针,当快指针到链表末尾时候,慢指针刚好到链表中间节点的位置
2.对链表的后半部夫进行逆置
利用头插法对链表后半部分进行逆置
3.将逆置完的链表再分别插入前半个链表
根据题目要求在把逆置好的链表分别插入前面的链表当中
2)根据设计思想,采用C或C++语言描述算法,关键之处给出注释。
void changelist(NODE* h) {
NODE* p , * q , * r , * s;
p = q = h;
//寻找中间节点
while( q->next != NULL ) {
//p走一步,q走两步
p = p->next;
q = q->next;
if( q->next != NULL ) {
q = q->next;
}
}
q = p->next;//p所指节点为中间节点
p->next = NULL;//q为后半段链表的首届点
while( q != NULL ) {//将链表后半段逆置
r = q->next;
q->next = p->next;
p->next = q;
q = r;
}
s = h->next;//s指向前半段的第一个数据节点,即s为插入点
q = p->next;//q指向后半段的第一个数据节点
p->next = NULL;
//将链表后半段的节点插入到指定位置
while( q != NULL ) {
r = q->next;//r指向后半段的下一个节点
q->next = s->next;//将q所指节点插入到s所指节点之后
s->next = q;
s = q->next;
q = r;
}
}
3)给出你代码的时间复杂度
时间复杂度:O(n)
第一个循环O(n),第二个循环O(n),第三个循环O(n);
总体来看,时间复杂度为O(n);