设以带头结点的双向循环链表表示的线性表L=(a1,a2,……,an)。
程序员文章站
2024-03-21 14:15:04
...
我的思路是拆开链表,然后先插入奇数位的,再插入偶数位的,要注意链表个数有奇数和偶数两种情况。
我不善于解释,注释都写在代码旁了,function函数就是题目要求的算法,其他函数是用来帮忙构建题目说的链表L的,希望能帮到你。
#include<stdio.h>
#include<malloc.h>
#include<assert.h>
#define Elemtype int
typedef struct DCList
{
Elemtype data;
struct DCList *next;
struct DCList *prior;
}Node;
Node* _buynode(Elemtype x);
void initial(Node **head);
void push_back(Node *head,Elemtype x);
void show(Node *head);
void function(Node *head);
int main()
{
Node *head;
initial(&head);
printf("创建一个双向循环链表(-1结束)\n");
int x;
while(1)
{
scanf("%d",&x);
if(x==-1)
break;
push_back(head,x);
}
printf(">>>");
show(head);
printf("function过后的链表\n");
function(head);
show(head);
return(1);
}
Node* _buynode(Elemtype x)
{//本算法的功能是申请一个节点,数据域赋值为x
//最后返回这个节点的指针
Node *s=(Node*)malloc(sizeof(Node));
assert(s!=NULL);
s->data=x;
s->next=NULL;
s->prior=NULL;
return(s);
}
void initial(Node **head)
{//本算法的功能是初始化一个双向循环链表的头指针
(*head)=(Node*)malloc(sizeof(Node));
assert((*head)!=NULL);
(*head)->data=0;//表长为0
(*head)->next=(*head)->prior=*head;
}
void push_back(Node *head,Elemtype x)
{//本算法的前提是双向循环链表已经初始化
//本算法的功能是双向循环链表的尾部插入一个新的节点
//节点的数据域赋值为x
Node *last=head->prior;//last指向链表的最后一个节点
Node *s=_buynode(x);
s->next=last->next;
head->prior=s;
last->next=s;
s->prior=last;//尾部插入
head->data++;//表长加一
}
void show(Node *head)
{//本算法的前提是链表至少有一个元素
//本算法的功能依次显示链表中所有的数据元素
if(head->data==0)
return;//表长合法性判断
Node *p=head->next;
while(p!=head)
{
printf("%d-->",p->data);
p=p->next;
}
printf("head.\n");
}
void function(Node *head)
{//本算法的前提是链表中至少有三个元素
//本算法是按照一定的规则改造链表
if(head->data<3)
return;//表长合法性判断
Node *p=head->next;
head->prior->next=NULL;
p->prior=NULL;
head->prior=head;
head->next=head;//拆链表
Node *s,*s_front,*pa;
s=p;
pa=s->next;
s=pa->next;//保存地址
p->next=head;
head->prior=p;
head->next=p;
p->prior=head;//尾部插入第一个节点
pa->prior=NULL;
while(s!=NULL && s->next!=NULL)//节点偶数个或者奇数个两种情况
{
p=s;
s_front=s->next;
s=s->next->next;
p->next->prior=p->prior;
p->prior->next=p->next;//删除p
Node *last=head->prior;//last指向head链表尾部节点
p->next=head;
head->prior=p;
last->next=p;
p->prior=last;//尾部插入节点
}//将a1,a3,a5...a2n-1插入到链表中
if(s!=NULL && s->next==NULL)//奇数个情况
{
s_front->next=s->next;
Node *last=head->prior;
s->next=head;
head->prior=s;
last->next=s;
s->prior=last;//插入尾部
}
Node *q=s_front;
while(s_front!=NULL)//插入剩余a2n,a2n-2...a2节点
{
q=q->prior;
Node *last=head->prior;
s_front->next=head;
head->prior=s_front;
last->next=s_front;
s_front->prior=last;
s_front=q;
}
}
时间复杂度方面,前四句话,也就是第一个while循环前面的代码,时间复杂度是O(1),if语句的时间复杂度也是O(1),两个while循环的时间复杂度分别是O(n/2),加起来就是O(n),所以时间复杂度的要求是满足题意的,这个可以用时间函数去验证。
上一篇: js checkbox 全选 取消全选