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

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

分类: Data Structure 面试题集   1242人阅读  评论(1)  收藏  举报

   有两个双向循环链表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中节点值相同的节点。

[cpp]  view plain copy
  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. }  

 

 

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值