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

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

 

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

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


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

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

 

① new->prev = p;
② new->next = p->next;
③ p->next = new;
④ new->next->prve = new;

 

删除p结点:

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

① p->prev->next = p->next;
② p->next->prev = p->prev;
③ free(p);

 

双向循环链表的实现:

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

基本思路:

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

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


#include <stdio.h>
#include <stdlib.h>

typedef int datatype;
 
typedef struct node
{
   datatype data;
   struct node *prev;
   struct node *next;
 
}dlistnode, *dlinklist;
 
//初始化
dlinklist init_list(void)
{
   dlinklist head = (dlinklist)malloc(sizeof(dlistnode));
   head->prev = head;
   head->next = head;
 
   return head;
}
 
//插入新结点
void insert(dlinklist head, datatype i)
{
   dlinklist newnode = (dlinklist)malloc(sizeof(dlistnode));

   //直接改指针,不需要遍历,不需要中间结点。
   newnode->data = i; 
 
   newnode->prev = head->prev;
   newnode->next = head;
   newnode->prev->next = newnode;
   head->prev = newnode;
}
 
void show(dlinklist head)
{
   dlinklist p = head->next;
 
   while(p != head)
   {
      printf("%d\t", p->data);
      p = p->next;
   }

   printf("\n");
}
 
//升降序操作:
void rearrange(dlinklist head)
{
   dlinklist p, q;
   int i = 0;

   for(p=head->prev; p != head; p=p->prev)
   {
   //从末结点往前遍历,从第二个偶数开始,将偶数结点搬移到末结点
       if(p->data % 2 == 0 && i != 0)
       {
         p->prev->next = p->next;
         p->next->prev = p->prev;
 
         p->prev = head->prev;
         p->next = head;
 
         head->prev->next = p;
         head->prev = p;

         //由于p所指的结点已成为末结点,为避免历遍出错,将p指向最近历遍的奇结点。
 
         p = q;
      }
   //记录最近历遍奇数结点位置
 
      q = p;
 
      i++;
   }
}
 
int main(void)
{
   dlinklist head;
   int n;
   int i;

   head = init_list();
   scanf("%d", &n);

   for(i=1; i<=n; i++)
   {
      insert(head, i);
   }
 
   show(head);

   rearrange(head);

   show(head);

   return 0;
}
  




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值