删除两个双向循环链表的相同节点

转载自:http://blog.csdn.net/zhuimengzh/article/details/6803950

有两个双向循环链表A,B,知道其头指针为:pHeadA,pHeadB,请写一个函数将两链表中数值相同的节点删除。

分析:

(1) 首先把A中含有与B中相同的数据节点找出来组成一个新的链表,例如:

链表A:1 2 3 4 2 6 4

链表B:10 20 3 4 2 10

新链表C:2 3 4

(2) 遍历链表C,删除A和B的所有和C中节点值相同的节点。

  1. #include "stdafx.h"  
  2. #include <iostream>  
  3. //双向循环链表的操作  
  4. using namespace std;  
  5. typedef struct Dbnode{  
  6.     int data;      //节点数据  
  7.     Dbnode *left;  //前驱结点指针  
  8.     Dbnode *right; //后继节点指针  
  9. }Dbnode;  
  10. void Print(Dbnode *head);  
  11.   
  12. //根据数据创建节点  
  13. Dbnode *CreateNode(int data){  
  14.     Dbnode *pnode=new Dbnode;//  
  15.     if (pnode==NULL){ //如果内存申请失败,返回NULL  
  16.         return NULL;  
  17.     }  
  18.     pnode->data=data;  
  19.     pnode->left=pnode;//新节点的前驱和后继指针都指向自身  
  20.     pnode->right=pnode;  
  21.     return pnode;  
  22. }  
  23.   
  24. //在表尾插入新节点,返回表头节点  
  25. Dbnode *AppendNode(Dbnode *head,int data){  
  26.     if (head==NULL){  
  27.         return NULL;  
  28.     }  
  29.     Dbnode *phead=head;  
  30.     Dbnode *pnode=CreateNode(data);//创建一个新节点  
  31.     while (head!=phead->right){ //找到表尾  
  32.            phead=phead->right;  
  33.     }  
  34.     pnode->right=phead->right;//右连接  
  35.     head->left=pnode;  
  36.     phead->right=pnode;//左连接  
  37.     pnode->left=phead;  
  38.     return head;  
  39. }  
  40.   
  41. //双向循环链表测长  
  42. int GetLength(Dbnode *head){  
  43.     if (head==NULL)//如果指针为空则返回0  
  44.     {  
  45.         return 0;  
  46.     }  
  47.     Dbnode *phead=head->right;  
  48.     int i=1;  
  49.     while (head!=phead){  
  50.           phead=phead->right;  
  51.            i++;  
  52.     }  
  53.     return i;  
  54. }  
  55.   
  56.   
  57. //双向循环链表的节点查找  
  58. Dbnode *FindNode(Dbnode *head,int data){  
  59.     if (head==NULL){  
  60.         return NULL;  
  61.     }  
  62.     if (head->data==data){ //如果表头节点和值相等  
  63.         return head;  
  64.     }  
  65.     Dbnode *phead=head->right;  
  66.     while (head != phead && phead->data != data){  
  67.            phead=phead->right;  
  68.       }  
  69.     if (phead->data==data){//如果是值相等退出,则返回节点  
  70.         return phead;  
  71.     }  
  72.     else  //如果没有找到,则返回NULL  
  73.         return NULL;  
  74. }  
  75.   
  76.   
  77.   
  78. //获得pA链表和pB链的交集,返回一个新链表  
  79. Dbnode *GetLink(Dbnode *pA,Dbnode *pB){  
  80.     if (pA==NULL || pB==NULL){//如果为空,则返回NULL  
  81.         return NULL;  
  82.     }  
  83.     Dbnode *pC=NULL;  
  84.     Dbnode *node=NULL;  
  85.     Dbnode *phead=NULL;  
  86.     //Dbnode *pheadA=pA;  
  87.     int len_a=GetLength(pA);  
  88.     int len_b=GetLength(pB);  
  89.     int data;  
  90.     for (int i=0;i<len_a;i++){  
  91.                phead=pB;  
  92.                data=pA->data;  
  93.                if (FindNode(pC,data)!=NULL){//如果data已在pC中,则进行下次循环  
  94.                     pA=pA->right;  
  95.                    continue;  
  96.                }  
  97.             if (data==pB->data){//如果pB的头节点和data相等  
  98.                  node=new Dbnode;  
  99.                  node->data=data;  
  100.                  node->left=node->right=node;  
  101.                     if (pC==NULL){//如果pC为空,则作为头节点  
  102.                              pC=node;  
  103.                            pC->left=pC;  
  104.                           pC->right=pC;  
  105.                     }else{  
  106.                           pC->right->left=node;  
  107.                           node->right=pC->right;  
  108.                           pC->right=node;  
  109.                           node->left=pC;  
  110.                         }  
  111.         }else{//如果pB的头节点和data不相等  
  112.                phead=pB->right;  
  113.             while (pB!=phead && phead->data != data){  
  114.                 phead=phead->right;  
  115.             }  
  116.             if (phead->data == data){  
  117.                 node=new Dbnode;  
  118.                 node->data=data;  
  119.                 node->right=node;  
  120.                 node->left=node;  
  121.                 if (pC==NULL){ //如果pC为NULL  
  122.                     pC=node;  
  123.                     pC->left=pC;  
  124.                     pC->right=pC;  
  125.                 }else{  
  126.                     pC->right->left=node;  
  127.                     node->right=pC->right;  
  128.                     pC->right=node;  
  129.                     node->left=pC;  
  130.                 }  
  131.             }  
  132.         }  
  133.            pA=pA->right;  
  134.     }  
  135.     return pC;  
  136. }  
  137.   
  138. //删除节点中所有数值等于data的节点  
  139. Dbnode *DeleteNode(Dbnode *head,int data){  
  140.     if (head==NULL){//链表不存在返回NULL  
  141.         return NULL;  
  142.     }  
  143.     Dbnode *node=NULL;  
  144.     Dbnode *pdelnode=NULL;  
  145.     while(head->data==data){ //如果头节点相等,则删除  
  146.         if (head->right==head){ //如果只有一个头节点,则返回NULL  
  147.             delete head;  
  148.             return NULL;  
  149.         }  
  150.         pdelnode=head;   //保存即将删除的节点  
  151.         node=head->right;//保存head的下一个节点  
  152.         head->right->left=head->left;  
  153.         head->left->right=head->right;  
  154.         head=node;//head的下一个节点作为头节点  
  155.         delete pdelnode;//释放删除的节点  
  156.         pdelnode =NULL;  
  157.     }  
  158.     Dbnode *phead=head->right;  
  159.     while (head!=phead){  
  160.         if (phead->data==data){  
  161.             while(phead->data==data){  
  162.                 pdelnode=phead;  
  163.                 node=phead->right; //保存phead的下一个节点  
  164.                 phead->right->left=phead->left;  
  165.                 phead->left->right=phead->right;  
  166.                 phead=node;  
  167.                 delete pdelnode;  
  168.                 pdelnode=NULL;  
  169.             }  
  170.         }else  
  171.         phead=phead->right;  
  172.     }  
  173.     return head;  
  174. }  
  175.   
  176. //删除链表A和链表B中所有含相同数据的节点  
  177. void DeleteEqual(Dbnode **pA,Dbnode **pB){  
  178.     Dbnode *pheadA=*pA;  
  179.     Dbnode *pheadB=*pB;  
  180.     Dbnode *pheadC=NULL;  
  181.     if (pA==NULL || pB==NULL){ //如果指针为NULL ,返回  
  182.         return ;  
  183.     }  
  184.     if (pheadA==NULL || pheadB==NULL){//如果链表为空,返回  
  185.         return;  
  186.     }  
  187.     Dbnode *pC=GetLink(pheadA,pheadB);//获得公共集合  
  188.     if (pC==NULL){  
  189.         return;  
  190.     }  
  191.     pheadA=DeleteNode(pheadA,pC->data);//删除pheadA和pheadB中和pC的头节点值相等的所有节点  
  192.     pheadB=DeleteNode(pheadB,pC->data);  
  193.      pheadC=pC->right;  
  194.     while (pheadC!=pC){ //循环删除pheadA和pheadB中和pC的头节点值相等的所有节点  
  195.         pheadA=DeleteNode(pheadA,pheadC->data);  
  196.         pheadB=DeleteNode(pheadB,pheadC->data);  
  197.         pheadC=pheadC->right;  
  198.     }  
  199.   
  200.     *pA=pheadA;//把处理后的链表再分别赋给pA和pB  
  201.     *pB=pheadB;  
  202. }  
  203.   
  204.   
  205. //打印双向循环链表  
  206. void Print(Dbnode *head){  
  207.     if (NULL==head){ //head为NULL表示为空链表  
  208.         getchar();  
  209.         return;  
  210.     }  
  211.     cout<<head->data<<" "//先打印出表头  
  212.     Dbnode *p=head->right;  
  213.     while (head!=p){ //依次遍历,直到到达表尾  
  214.         cout<<p->data<<" ";  
  215.         p=p->right;  
  216.     }  
  217.     cout<<endl;  
  218. }  
  219. int _tmain(int argc, _TCHAR* argv[])  
  220. {  
  221.     Dbnode *pA=NULL;  
  222.     Dbnode *pB=NULL;  
  223.     Dbnode *pC=NULL;  
  224.     Dbnode *pheadC=pC;  
  225.     Dbnode *pfind=NULL;  
  226.     Dbnode *pNhead=NULL;  
  227.     Dbnode *pList=NULL;  
  228.     pA=CreateNode(0);//创建表头节点,表头节点不作为存放有意义数据的节点  
  229.     for (int i=1;i<10;i++){  
  230.         AppendNode(pA,i);  
  231.     }  
  232.     AppendNode(pA,9);  
  233.     AppendNode(pA,20);  
  234.     cout<<"pA:";  
  235.     Print(pA);  
  236.     pB=CreateNode(0);  
  237.     AppendNode(pB,3);  
  238.     AppendNode(pB,2);  
  239.     AppendNode(pB,6);  
  240.     AppendNode(pB,9);  
  241.     AppendNode(pB,9);  
  242.     AppendNode(pB,15);  
  243.     AppendNode(pB,20);  
  244.     AppendNode(pB,20);  
  245.     cout<<"pB:";  
  246.     Print(pB);  
  247.     pC=GetLink(pA,pB);  
  248.     cout<<"Subset pA and pB:";  
  249.     Print(pC);  
  250.   
  251.     DeleteEqual(&pA,&pB);  
  252.     cout<<"After DeleteEqual pA:";  
  253.     Print(pA);  
  254.     cout<<" After DeleteEqual pB:";  
  255.     Print(pB);  
  256.    system("pause");  
  257.     delete [] pA;  
  258.     delete [] pB;  
  259.     delete [] pC;  
  260.     return 0;  
  261. }  

 

 


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 下面是一个 Java 代码示例,实现了双向循环链表的逆序: ``` class Node { int data; Node next; Node prev; Node(int data) { this.data = data; } } class DoubleLinkedList { Node head; void reverseList() { Node temp = null; Node current = head; while (current != null) { temp = current.prev; current.prev = current.next; current.next = temp; current = current.prev; } if (temp != null) { head = temp.prev; } } } ``` 该代码实现了双向循环链表的逆序,每次迭代,它交换当前节点的 `next` 和 `prev` 指针。最后,如果有存在缓存的前驱节点,则把链表的头更新为该前驱节点的前驱。 ### 回答2: 双向循环链表是一种链表数据结构,其中每个节点除了指向下一个节点外,还额外指向前一个节点。实现双向循环链表的逆序操作,我们可以按照以下步骤进行: 1. 首先判断链表是否为空,若为空则直接返回原链表。 2. 定义两个指针,分别指向链表的头部和尾部节点。 3. 循环遍历链表,将头部指针的前驱节点设为原链表的后继节点,尾部指针的后继节点设为原链表的前驱节点。 4. 交换头部和尾部指针,完成一次逆序操作。 5. 继续重复步骤3和步骤4直到遍历完整个链表。 以下是使用Python语言实现双向循环链表逆序的代码示例: ```python class ListNode: def __init__(self, value): self.value = value self.next = None self.prev = None def reverse_doubly_linked_list(head): if not head: return head # 定义头部和尾部指针 start = head end = head.prev # 循环遍历链表逆序 while start != end: # 交换头部和尾部指针的前驱和后继节点 start.prev, start.next, end.prev, end.next = end.prev, end.next, start.next, start.prev # 更新头部和尾部指针 start, end = end, start return end # 返回逆序后的链表头部指针 ``` 以上代码通过交换头部和尾部指针的前驱和后继节点来实现链表逆序。在每次交换后,更新头部和尾部指针,直到头尾指针相遇,完成整个逆序操作。最后返回逆序后的链表头部指针。 ### 回答3: 双向循环链表是一种数据结构,其每个节点都包含一个数据元素,同时拥有指向前一个节点和后一个节点的指针。为了实现双向循环链表的逆序,我们可以按照以下步骤进行: 1. 首先,定义一个双向循环链表节点类,包含一个数据元素和两个指针:prev指向前一个节点,next指向后一个节点。 ```python class Node: def __init__(self, data): self.data = data self.prev = None self.next = None ``` 2. 然后,创建一个双向循环链表的类,包含以下方法: - `__init__()`:初始化链表为空。 - `add()`:添加节点到链表末尾。 - `reverse()`:逆序双向循环链表。 ```python class DoublyLinkedList: def __init__(self): self.head = None def add(self, data): new_node = Node(data) if self.head is None: self.head = new_node self.head.prev = self.head self.head.next = self.head else: current = self.head while current.next != self.head: current = current.next current.next = new_node new_node.prev = current new_node.next = self.head self.head.prev = new_node def reverse(self): if self.head is None: return current = self.head while current.next != self.head: temp = current.next current.next = current.prev current.prev = temp current = current.prev temp = current.next current.next = current.prev current.prev = temp self.head = current ``` 3. 最后,可以创建一个双向循环链表的对象,添加节点,并调用`reverse()`方法进行逆序。 ```python dllist = DoublyLinkedList() dllist.add(1) dllist.add(2) dllist.add(3) dllist.add(4) dllist.reverse() ``` 这样就完成了双向循环链表的逆序操作。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值