设以带头结点的双向循环链表表示的线性表L=(a1,a2,……,an)。

来源:互联网 发布:最好背单词软件 编辑:程序博客网 时间:2024/06/05 07:35

我的思路是拆开链表,然后先插入奇数位的,再插入偶数位的,要注意链表个数有奇数和偶数两种情况。
我不善于解释,注释都写在代码旁了,function函数就是题目要求的算法,其他函数是用来帮忙构建题目说的链表L的,希望能帮到你。

#include<stdio.h>#include<malloc.h>#include<assert.h>#define Elemtype inttypedef 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),所以时间复杂度的要求是满足题意的,这个可以用时间函数去验证。

阅读全文
0 0
原创粉丝点击