设以带头结点的双向循环链表表示的线性表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
- 设以带头结点的双向循环链表表示的线性表L=(a1,a2,……,an)。
- 设以带头结点的双向循环链表表示的线性表L= (a1,a2,…,an),试写一时间复杂度O(n)的算法,将L改造为 (a1,a3,…,an,…,a4,a2)。
- 设双链表表示的线性表L=(a1,a2,a3.....an)将L改造为L=(a1,a3,....an...a4,a2)
- 将双向循环链表L=(a1,a2,...,an)改造成L=(a1,a3,...,an,...,a4,a2)
- 有一个带头结点的单链表L={a1,b1,a2,b2,...,an,bn},设计一个算法将其拆分成两个带头结点的单链表A和B,正序链表A={a1,a2,a3...,an},逆序链表B={bn,bn-1,
- 线性表和带头结点的双向循环链表
- 带头结点的双向循环链表
- 带头结点的双向循环链表
- 带头结点的双向循环链表
- 判断带头结点的双向循环链表L是否对称相等的算法
- 假设以带头结点的循环链表表示队列, 并且只设一个指针指向队尾元素结点(注意不设头指针) 试编写相应的队列初始化,入队列和出队列的算法
- 假设以不带头结点的循环链表表示队列,并且只设一个指针指向队尾结点,但不设头指针。试设计相应的入队和出队的算法
- 【C++数据结构学习笔记---线性表】带头结点的双向循环链表
- 双向循环链表(带头结点)
- 线性表 - 带头结点的循环单链表
- C语言实现双向非循环链表(带头结点尾结点)的基本操作
- C语言实现双向非循环链表(带头结点尾结点)的节点插入
- 3.6使用带头结点的循环链表链表表示队列
- 浙工大程序设计迎新赛预赛
- 月下湿吻,游行,私会诺奖得主:斯坦福人都这么玩!
- bzoj1559 [JSOI2009]密码(AC自动机+状压DP)
- 【运维】略谈Raid级别
- dbimage中如何装载jpg文件 2015-02-27 20:44:15| 分类: 电脑 |举报|字号 订阅 下载LOFTER我的照片书 | dbimage中如何装载jpg文
- 设以带头结点的双向循环链表表示的线性表L=(a1,a2,……,an)。
- MongoDB,分组,聚合
- 青春的痛苦
- project euler 19 Counting Sundays
- 以一种极其优雅的方式来调用Toast和Snackbar
- VS2015断点调试神坑之为引用变量赋值为null不成功?
- 九个绝招,让你戒掉旧情人
- 晓之以理,不如动之以情——新书《以大致胜》解读(下篇)
- 使用Scala 读写MySQL 数据给Spark任务执行