c语言_数据结构_双向循环链表

双向循环链表与单向循环链表的区别在于,每个节点的指针域中除了有指向下一结点的next指针外,还有指向前一结点的prev指针:

 

在链表中,中间部分结点的next指针指向其直接后继结点,prev指针指向其直接前继结点。与单向循环链表相同,末结点的next指针不再指向NULL,而是指向头结点Head,而头结点的prev则指向末结点。

c语言_数据结构_双向循环链表


将新结点new插入到p所指向的结点之后:

c语言_数据结构_双向循环链表

 

[cpp]  view plain copy
  1. ① new->prev = p;  
  2. ② new->next = p->next;  
  3. ③ p->next = new;  
  4. ④ new->next->prve = new;  

 

删除p结点:

c语言_数据结构_双向循环链表

[cpp]  view plain copy
  1. ① p->prev->next = p->next;  
  2. ② p->next->prev = p->prev;  
  3. ③ free(p);  

 

双向循环链表的实现:

功能:在链表的结点中分别存放1、2、3、4、5、6、7、8、9、10,并进行相关操作,实现奇数升序偶数降序,即1、3、5、7、9、10、8、6、4、2。

基本思路:

从末结点向前遍历,从遍历到的第二个偶数结点开始,将偶数结点移动至末结点。

c语言_数据结构_双向循环链表


[cpp]  view plain copy
  1. #include <stdio.h>  
  2. #include <stdlib.h>  
  3.   
  4. typedef int datatype;  
  5.    
  6. typedef struct node  
  7. {  
  8.    datatype data;  
  9.    struct node *prev;  
  10.    struct node *next;  
  11.    
  12. }dlistnode, *dlinklist;  
  13.    
  14. //初始化  
  15. dlinklist init_list(void)  
  16. {  
  17.    dlinklist head = (dlinklist)malloc(sizeof(dlistnode));  
  18.    head->prev = head;  
  19.    head->next = head;  
  20.    
  21.    return head;  
  22. }  
  23.    
  24. //插入新结点  
  25. void insert(dlinklist head, datatype i)  
  26. {  
  27.    dlinklist newnode = (dlinklist)malloc(sizeof(dlistnode));  
  28.   
  29.    //直接改指针,不需要遍历,不需要中间结点。  
  30.    newnode->data = i;   
  31.    
  32.    newnode->prev = head->prev;  
  33.    newnode->next = head;  
  34.    newnode->prev->next = newnode;  
  35.    head->prev = newnode;  
  36. }  
  37.    
  38. void show(dlinklist head)  
  39. {  
  40.    dlinklist p = head->next;  
  41.    
  42.    while(p != head)  
  43.    {  
  44.       printf("%d\t", p->data);  
  45.       p = p->next;  
  46.    }  
  47.   
  48.    printf("\n");  
  49. }  
  50.    
  51. //升降序操作:  
  52. void rearrange(dlinklist head)  
  53. {  
  54.    dlinklist p, q;  
  55.    int i = 0;  
  56.   
  57.    for(p=head->prev; p != head; p=p->prev)  
  58.    {  
  59.    //从末结点往前遍历,从第二个偶数开始,将偶数结点搬移到末结点  
  60.        if(p->data % 2 == 0 && i != 0)  
  61.        {  
  62.          p->prev->next = p->next;  
  63.          p->next->prev = p->prev;  
  64.    
  65.          p->prev = head->prev;  
  66.          p->next = head;  
  67.    
  68.          head->prev->next = p;  
  69.          head->prev = p;  
  70.   
  71.          //由于p所指的结点已成为末结点,为避免历遍出错,将p指向最近历遍的奇结点。  
  72.    
  73.          p = q;  
  74.       }  
  75.    //记录最近历遍奇数结点位置  
  76.    
  77.       q = p;  
  78.    
  79.       i++;  
  80.    }  
  81. }  
  82.    
  83. int main(void)  
  84. {  
  85.    dlinklist head;  
  86.    int n;  
  87.    int i;  
  88.   
  89.    head = init_list();  
  90.    scanf("%d", &n);  
  91.   
  92.    for(i=1; i<=n; i++)  
  93.    {  
  94.       insert(head, i);  
  95.    }  
  96.    
  97.    show(head);  
  98.   
  99.    rearrange(head);  
  100.   
  101.    show(head);  
  102.   
  103.    return 0;  
  104. }  


原文:http://blog.csdn.net/SahPah/article/details/38534923
  1.     
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值