c++单链表的一些操作链表的合并



c++单链表的一些操作链表的合并,单链表的一些操作,由于一些操作很类似,名字不好区分,现单列出来,可以直接在上篇文章的单链表中使用,VS2005调试通过

操作一:链表的合并

1、要求:两个单链表A和B,AB增C非增,C=A+B

注意:利用原表A和B,允许有相同元素

思想:

1、每次都插小的,大的留下继续比较

2、AB增C非增,则使用逆序插入

3、不能连续插入(每次要插入的结点总是要从原链表中截断,插入到C中)

代码:

  1. template<class Type>
  2. void LinkList<Type>::Merge(LinkList<Type>& A,LinkList<Type>& B)
  3. {
  4.     Node<Type>* currentA = A.Head->next;//currentA指向第一个结点
  5.     Node<Type>* currentB = B.Head->next;//currentB指向第一个结点
  6.     Node<Type>* currentC = A.Head;
  7.     len = A.len + B.len;
  8.     //处理C的头结点,利用A的头结点
  9.     this->Head = A.Head;
  10.     this->Head->next = NULL;
  11.     delete B.Head;
  12.     //处理之后的元素
  13.     while(currentA!=NULL && currentB!=NULL)//
  14.     {
  15.         Node<Type>* temp;
  16.         if (currentA->data > currentB->data)
  17.         {
  18.             temp = currentB;
  19.             currentB = currentB->next;
  20.             temp->next = currentC->next;
  21.             currentC->next = temp;
  22.         }
  23.         else
  24.         {
  25.             temp = currentA;
  26.             currentA = currentA->next;
  27.             temp->next = currentC->next;
  28.             currentC->next=temp;
  29.         }
  30.     }
  31.     while (currentA!=NULL)
  32.     {
  33.         Node<Type>* temp;
  34.         temp = currentA;
  35.         currentA=currentA->next;
  36.         temp->next = currentC->next;
  37.         currentC->next = temp;
  38.     }
  39.     while (currentB!=NULL)
  40.     {
  41.         Node<Type>* temp;
  42.         temp = currentB;
  43.         currentB=currentB->next;
  44.         temp->next = currentC->next;
  45.         currentC->next = temp;
  46.     }
  47. }

2、要求:两个单链表A和B,AB增C增,C=A+B

注意:利用原表A和B的空间,允许有相同元素

思想:

1、每次都插小的,大的留下继续比较

2、AB增C增,则使用正序插入

3、可以连续插入(每次要插入的结点可以先不从原链表中截断,直到遇到一个大数,不指向插入操作时,才从原链表中截断)

代码:

  1. template<class Type>
  2. void LinkList<Type>::merge(LinkList<Type>& A,LinkList<Type>& B)
  3. {
  4.     Node<Type>* currentA = A.Head->next;//currentA指向第一个结点
  5.     Node<Type>* currentB = B.Head->next;//currentB指向第一个结点
  6.     Node<Type>* currentC = A.Head;
  7.     len = A.len + B.len;
  8.     //处理C的头结点,利用A的头结点
  9.     this->Head = A.Head;
  10.     this->Head->next = NULL;
  11.     delete B.Head;
  12.     //处理之后的元素
  13.     while(currentA!=NULL && currentB!=NULL)
  14.     {
  15.         if (currentA->data > currentB->data)
  16.         {
  17.             currentC->next = currentB;
  18.             currentC = currentC->next;
  19.             currentB = currentB->next;
  20.         }
  21.         else
  22.         {
  23.             currentC->next = currentA;
  24.             currentC = currentC->next;
  25.             currentA = currentA->next;
  26.         }
  27.     }
  28.     if (currentA!=NULL)
  29.     {
  30.         currentC->next = currentA;
  31.     }
  32.     else
  33.     {
  34.         currentC->next = currentB;
  35.     }
  36. }

3、要求:两个单链表A和B,AB增C增,C=A交B

注意:

1、不能破坏原来空间(不利用原表A和B的空间)

2、AB中元素均无重复元素,但A和B中可能有相同元素 =》C中元素各不相同

思想:

1、每次都先抛弃小的,大的留下继续比较,找到相等的插入

2、AB增C增,则使用正序插入

代码:

[cpp] view plaincopy


  1. template<class Type>
  2. void LinkList<Type>::Intersect(const LinkList<Type>& A,const LinkList<Type>& B)
  3. {
  4.     Head = new Node<Type>;//为链表建立头结点
  5.     Head->next = NULL;
  6.     last = NULL;
  7.     len =0;
  8.     //定义处理指针,C指向最后一个元素,AB指向待处理的元素
  9.     Node<Type>* currentA = A.Head->next;//currentA指向第一个结点
  10.     Node<Type>* currentB = B.Head->next;//currentB指向第一个结点
  11.     Node<Type>* currentC = Head;
  12.     //处理之后的元素
  13.     while(currentA!=NULL && currentB!=NULL) //每次都是先抛弃小的,找到相等的,就使用正序插入.
  14.     {
  15.         if (currentA->data > currentB->data)
  16.         {
  17.             currentB = currentB->next;
  18.         }
  19.         else if(currentA->data < currentB->data)
  20.         {
  21.             currentA = currentA->next;
  22.         }
  23.         else
  24.         {
  25.             Node<int>* newNode = new Node<int>;
  26.             newNode->data = currentA->data;
  27.             currentC->next=newNode;
  28.             currentC = currentC->next;
  29.             currentA = currentA->next;
  30.             currentB = currentB->next;
  31.             len++;
  32.         }
  33.     }
  34.     currentC->next = NULL;
  35. }

4、要求:两个单链表A和B,AB增C增,C=A交B,C中元素各不相同

注意:

1、不能破坏原来空间(不利用原表A和B)

2、AB中元素 可能有 重复元素,但要求C中元素各不相同

思想:

1、每次都先抛弃小的,大的留下继续比较,找到相等的插入

2、元素相等插入时,必须还要比较之前插入元素是不是和即将插入的元素相等

3、AB增C增,则使用正序插入

代码:

  1. template<class Type>
  2. void LinkList<Type>::Intersect(const LinkList<Type>& A,const LinkList<Type>& B)
  3. {
  4.     bool isFirst = true;//标志位,是不是第一次插入
  5.     //为链表建立头结点
  6.     Head = new Node<Type>;
  7.     Head->next = NULL;
  8.     last = NULL;
  9.     len =0;
  10.     //定义处理指针,C指向最后一个元素,AB指向待处理的元素
  11.     Node<Type>* currentA = A.Head->next;//currentA指向第一个结点
  12.     Node<Type>* currentB = B.Head->next;//currentB指向第一个结点
  13.     Node<Type>* currentC = Head;
  14.     //处理之后的元素
  15.     while(currentA!=NULL && currentB!=NULL) //每次都是先抛弃小的,找到相等的,就使用正序插入.
  16.     {
  17.         if (currentA->data > currentB->data)
  18.         {
  19.             currentB = currentB->next;
  20.         }
  21.         else if(currentA->data < currentB->data)
  22.         {
  23.             currentA = currentA->next;
  24.         }
  25.         else
  26.         {
  27.             if (isFirst)
  28.             {
  29.                 Node<int>* newNode = new Node<int>;
  30.                 newNode->data = currentA->data;
  31.                 currentC->next=newNode;
  32.                 currentC = currentC->next;
  33.                 isFirst=false;
  34.                 len++;
  35.             }
  36.             else
  37.             {
  38.                 if (currentC->data != currentA->data)
  39.                 {
  40.                     Node<int>* newNode = new Node<int>;
  41.                     newNode->data = currentA->data;
  42.                     currentC->next=newNode;
  43.                     currentC = currentC->next;
  44.                     len++;
  45.                 }
  46.             }
  47.             currentA = currentA->next;
  48.             currentB = currentB->next;
  49.         }
  50.     }
  51.     currentC->next = NULL;
  52. }

5、要求:两个单链表A和B,AB增C增,B=B-A,A中无重复,B中无重复

注意:

1、不能破坏A空间(不利用A),但是直接在B表中修改

思想:

1、每次都先抛弃小的,大的留下继续比较,找到相等的,则直接在原表删除

代码:

  1. template<class Type>
  2. void LinkList<Type>::Difference(const LinkList<Type>& A)//元素可以有重复的 B-A  —没有设置尾指针
  3. {
  4.     //定义处理指针,C指向最后一个元素,AB指向待处理的元素
  5.     Node<Type>* currentA = A.Head->next;//currentA指向第一个结点
  6.     Node<Type>* currentC = Head->next;
  7.     Node<Type>* trailCurrent = Head;
  8.     //处理之后的元素
  9.     while(currentA!=NULL && currentC!=NULL) //每次都是先抛弃小的,找到相等的,则直接在原表删除
  10.     {
  11.         if (currentA->data > currentC->data)
  12.         {
  13.             trailCurrent = currentC;
  14.             currentC = currentC->next;
  15.         }
  16.         else if(currentA->data < currentC->data)
  17.         {
  18.             currentA = currentA->next;
  19.         }
  20.         else
  21.         {
  22.             trailCurrent->next = currentC->next;
  23.             delete currentC;
  24.             currentC = trailCurrent->next;
  25.             len–;
  26.         }
  27.     }
  28.     if (currentC==NULL)
  29.     {
  30.         trailCurrent->next = NULL;
  31.     }
  32. }