数据结构面试之一——单链表常见操作

来源:互联网 发布:剑灵地狱之歌捏脸数据 编辑:程序博客网 时间:2024/06/05 04:08

数据结构面试之一——单链表常见操作

题注:《程序员面试宝典》有相关习题,但思路相对不清晰,排版有错误,本文对此参考相关书籍和自己观点进行了重写,供大家参考。

1.查找链表元素

Step1:置查找标记bfound=false;判断链表是否为空,是,提示“不能查找空链表”;否,进入step2。

Step2:从链表头开始查找,判断(当前点的info是否与待查找元素值相等&&指针未指向末尾),是,“查找结束,bfound=true”,否,继续查找。

Step3:判断bfound= = true,是,“提示查找成功”,否,“提示查找失败”。

[cpp] view plaincopy
  1. /查找单链表元素  
  2. template<typename Type>  
  3. void linkedlistType<Type>::search(const Type& searchItem)  
  4. {  
  5.        nodeType<Type> *current;  
  6.        bool found = false;  
  7.    
  8.        if(first == NULL)                                          //1.空链表  
  9.        {  
  10.               cout << "WARNING: Can not search an empty list!" << endl;  
  11.               return;  
  12.        }  
  13.        else  
  14.        {  
  15.               current = first;  
  16.               while(!found && current != NULL)  
  17.               {  
  18.                      if(current->info == searchItem)  
  19.                      {  
  20.                             found = true;  
  21.                             break;  
  22.                      }  
  23.                      else  
  24.                      {  
  25.                             current = current->link;  
  26.                      }  
  27.               }  
  28.               if(found)  
  29.               {  
  30.                      cout << searchItem << " was found in the List! " << endl;  
  31.               }  
  32.               else  
  33.               {  
  34.                      cout << searchItem << " was not found in the List! " << endl;  
  35.               }  
  36.        }  
  37. }  

2.删除链表元素值

Step1:置查找标记bfound=false; 判断链表是否为空,是,提示“不能对空链表进行删除操作”;否,进入step2。

Step2:判断待删除元素值是否与头节点元素值相等,是,调整头节点指针;否,进入step3。

Step3:判断链表中是否存在该元素,否,“提示元素不存在”;是,进入step4。

Step4:判定要删除元素是否与末尾节点元素值相等,是,调整末尾last指针;否,此时为中间节点,需要调整trailCurrent和Current指针的指向。

[cpp] view plaincopy
  1. //删除单链表元素  
  2. template<typename Type>  
  3. void linkedlistType<Type>::deleteNode(const Type& deleteItem)  
  4. {  
  5.        nodeType<Type> *tempNode = new nodeType<Type>;  
  6.        nodeType<Type> *current = new nodeType<Type>;  
  7.        nodeType<Type> *trailCurrent = new nodeType<Type>;  
  8.        bool found;  
  9.         
  10.        //链表为空 case1  
  11.        if(first == NULL)  
  12.        {  
  13.               cout << "Can not delete an empty List!" << endl;  
  14.        }  
  15.        else  
  16.        {  
  17.               if( first->info == deleteItem )  
  18.               {  
  19.                      //要删除的也是第一个节点(仅一个节点,或不止一个节点) case2  
  20.                      tempNode = first;  
  21.                      first = first->link;  
  22.                      if(first == NULL)  
  23.                      {  
  24.                             last = NULL;  
  25.                      }                           
  26.                      delete tempNode;  
  27.               }  
  28.               else  
  29.               {  
  30.                      //先查找,后判断... case3  
  31.                      found = false;  
  32.                      trailCurrent = first;  
  33.                      current = first->link;  
  34.    
  35.                      while((!found) && (current != NULL))  
  36.                      {  
  37.                             if(deleteItem  != current->info)  
  38.                             {  
  39.                                    trailCurrent = current;  
  40.                                    current = current->link;  
  41.                             }  
  42.                             else  
  43.                             {  
  44.                                    found = true;  
  45.                             }  
  46.                      }  
  47.    
  48.                      if(found)  
  49.                      {  
  50.                             //能找到...  
  51.                             trailCurrent ->link = current->link;  
  52.    
  53.                             if(current == last)  
  54.                             {  
  55.                                    last = trailCurrent; //case 3a  
  56.                             }  
  57.                             delete current;         //case 3b  
  58.                      }  
  59.                      //不存在该点...case4  
  60.                      else  
  61.                      {  
  62.                             cout << "The deleteItem is not Exist in the List! " << endl;  
  63.                      } //end else  
  64.               }//end else  
  65.        }//end else  
  66.         
  67. }// end deleteNode  

3.单链表逆置[迭代实现]

Step1:判断链表是否为空,是,提示“不能对空链表进行逆置操作“;否,进入Step2;

Step2:从第2个节点开始,依次将每个节点插入到第一个节点的前面,判断指针是否指向了链表尾部,是,返回头指针结束;否,继续迭代后面的链表元素。

[cpp] view plaincopy
  1. template<typename Type>  
  2. nodeType<Type>* linkedlistType<Type>::reverseList()   //逆置单链表  
  3. {  
  4.        if(first == NULL)  
  5.        {  
  6.               cout << "Can't reverse empty List!" << endl;  
  7.        }  
  8.        else  
  9.        {  
  10.               nodeType<Type>* p = first;  
  11.               nodeType<Type>* q = p->link;  
  12.    
  13.               while(q != NULL)  
  14.               {  
  15.                      p->link = q->link;  
  16.                      q->link = first;  
  17.                      first = q;  
  18.                      q = p->link;  
  19.               }  
  20.        }  
  21.        return first;  
  22. }  

4.单链表排序[直接插入排序]

思路:分为以下几种情况:

1)  单链表为空;

2)  单链表非空,但仅含一个元素,无需排序已经有序;

3)  待插入元素小于头结点的元素;

4)  待插入元素为前已有序的中间的元素值;

5)  待插入的元素前所有元素都比其小,直接插到末尾。

分别用lastInOrder记录已经有序的最后一个节点,firstOutOfOrder第一个尚未排序(正待参与)排序的节点。current用于记录循环的节点,trailCurrent记录current前的节点。

[cpp] view plaincopy
  1. template<typename Type>  
  2. void linkedlistType<Type>::sortList()     //单链表排序  
  3. {  
  4.        nodeType<Type>* current;  
  5.        nodeType<Type>* trailCurrent;  
  6.        nodeType<Type>* lastInOrder;  
  7.        nodeType<Type>* firstOutOfOrder;  
  8.    
  9.        lastInOrder = first;  
  10.    
  11.        //case1,表为空.  
  12.        if(first == NULL)  
  13.        {  
  14.               cout << "Can't Sort of empty List!" << endl;  
  15.               return;  
  16.        }  
  17.    
  18.        //case2,表不为空,但表长为1,仅含1个元素.  
  19.        if(first->link == NULL)  
  20.        {  
  21.               cout << "The List Was Already ordered!" << endl;  
  22.               return;  
  23.        }  
  24.    
  25.        while(lastInOrder->link != NULL)  
  26.        {  
  27.               firstOutOfOrder = lastInOrder->link;      
  28.               //case3,要插入的元素小于第1个元素.  
  29.               if(firstOutOfOrder->info < first->info)  
  30.               {  
  31.                      lastInOrder->link = firstOutOfOrder->link;  
  32.                      firstOutOfOrder->link = first;  
  33.                      first = firstOutOfOrder;  
  34.               }  
  35.               else  
  36.               {      
  37.                      trailCurrent = first;  
  38.                      current = first->link;  
  39.                      while(current->info < firstOutOfOrder->info)  
  40.                      {  
  41.                             trailCurrent = current;  
  42.                             current = current->link;  
  43.                      }  
  44.    
  45.                      //case4,要插入的元素在前已有序元素的中间.  
  46.                      if(trailCurrent != lastInOrder)  
  47.                      {  
  48.                             lastInOrder->link = firstOutOfOrder->link;  
  49.                             firstOutOfOrder->link = current;  
  50.                             trailCurrent->link = firstOutOfOrder;  
  51.                      }  
  52.                      else  
  53.                      {  
  54.                             //case5,要插入的元素大于最后一个已经有序的元素.  
  55.                             lastInOrder = lastInOrder->link;  
  56.                      }//end else  
  57.               }//end else  
  58.        }//end while  
  59. }  

5.单链表在不知道链表长度的前提下求链表中间节点的值。

思路:分以下几种情况:

1)  链表为空;

2)  链表非空,但仅有一个或两个节点;可以直接返回第一个节点的元素值。

3)  链表非空,但含有三个或三个以上的节点,可以通过定义两个指针,一个指针的跳步为2次的时候,另一个指针的跳步为1次,当跳至结尾时,另一个节点恰好在中间位置。

//不知道表长的前提下求单链表中间元素

[cpp] view plaincopy
  1. template<typename Type>  
  2. Type linkedlistType<Type>::midValOfList()           
  3. {  
  4.        nodeType<Type> *current;  
  5.        nodeType<Type> *halfCurrent;  
  6.    
  7.        if(first == NULL)                                //case1,没有节点  
  8.        {  
  9.               cout << "链表为空!" << endl;  
  10.               return -1;  
  11.        }  
  12.        else if(first->link == NULL || first->link->link == NULL) //case2,仅一个节点或两个节点.  
  13.        {  
  14.               return first->info;  
  15.        }  
  16.        else                                   //case3,含有三个或三个以上的节点.  
  17.        {  
  18.               current = first;  
  19.               halfCurrent = current;  
  20.    
  21.               while(current->link != NULL)  
  22.               {  
  23.                      current = current->link;  
  24.                      if(current->link != NULL)  
  25.                      {  
  26.                             if(current->link != NULL)  
  27.                             {  
  28.                                    halfCurrent = halfCurrent->link;  
  29.                                    current = current->link;  
  30.                             }//end if  
  31.                      }  
  32.               }//end while  
  33.               return halfCurrent->info;  
  34.        }//end else  
  35. }  

6.单链表建立

思路:单链表的建立可分为根据插入新节点的位置的不同而分为两种,1:在链表末尾插入元素的建立方式;2:在链表前面插入元素建立链表的方式。

对应1末尾插入分为两步:

Step1:如果当前链表为空,则置first=last=newNode;否则,进入Step2

Step2:插入新结点元素,修改last指针。

对于2链表first指针前插入:主要需要保证插入元素后,修正first节点即可。

[cpp] view plaincopy
  1. //正向末尾插入  
  2. template<typename Type>  
  3. nodeType<Type>* linkedlistType<Type>::buildListForward()  
  4. {  
  5.        nodeType<Type>  *newNode;  
  6.    
  7.        int num;  
  8.        cout << " Enter a list of integer end with -999. " << endl;  
  9.        cin >> num;  
  10.        while(num != -999)  
  11.        {  
  12.               //..add  
  13.               newNode = new nodeType<Type>;  
  14.               newNode->info = num;  
  15.               newNode->link = NULL;  
  16.    
  17.               if(first==NULL)  
  18.               {  
  19.                      first = newNode;  
  20.                      last = newNode;  
  21.               }  
  22.               else  
  23.               {  
  24.                      last->link = newNode;  
  25.                      last = newNode;  
  26.               }  
  27.               cin >> num;  
  28.        }  
  29.        return first;  
  30. }  
  31.    
  32. //反向表头插入,从前面插入...  
  33. template<typename Type>  
  34. nodeType<Type>* linkedlistType<Type>::buildListBackward()  
  35. {  
  36.        nodeType<Type>  *newNode;  
  37.    
  38.        int num;  
  39.        cout << " Enter a list of integer end with -999. " << endl;  
  40.        cin >> num;  
  41.        while(num != -999)  
  42.        {  
  43.               //..add  
  44.               newNode = new nodeType<Type>;  
  45.               newNode->info = num;  
  46.               newNode->link = first;  
  47.               first = newNode;  
  48.               cin >> num;  
  49.        }  
  50.        return first;  
  51. }  

7.单链表的测量长度

思路:链表的长度等效为节点个数,指针非空则循环判断即可。

[cpp] view plaincopy
  1. //求解链表长度  
  2. template<typename Type>  
  3. int linkedlistType<Type>::length()  
  4. {  
  5.        int count = 0;  
  6.        nodeType<Type> *current;  
  7.        current = first;  
  8.    
  9.        while(current != NULL)  
  10.        {  
  11.               count++;  
  12.               current = current->link;  
  13.        }  
  14.        return count; //节点个数等效为长度.  
  15. }  

8.单链表的插入

思路:链表的插入也同链表的建立一样分为前向、后向插入两种形式,注意firstlast指针的指向问题。

[cpp] view plaincopy
  1. //在前面插入  
  2. template<typename Type>  
  3. void linkedlistType<Type>::insertFirst(const Type& newItem)  
  4. {  
  5.        //last no use.  
  6.        nodeType<Type> *newNode = new nodeType<Type>;  
  7.        newNode->info = newItem;  
  8.        newNode->link = first;   //在前面加入...  
  9.        first = newNode;  
  10. }  
  11.    
  12. //在后面插入元素...  
  13. template<typename Type>  
  14. void linkedlistType<Type>::insertLast(const Type& newItem)  
  15. {  
  16.        nodeType<Type> *newNode = new nodeType<Type>;  
  17.        newNode->info = newItem;  
  18.        newNode->link = NULL;   //在后面加入...  
  19.    
  20.        if(first == NULL)  
  21.        {  
  22.               first = newNode;  
  23.               last = newNode;  
  24.        }  
  25.        else  
  26.        {  
  27.               last->link = newNode;  
  28.               last = newNode;  
  29.        }  
  30. }  

0 0
原创粉丝点击