1.带头结点单链表的长度计算?

 
  
  1. int ListLength(LinkList L) 
  2.    int i = 0; 
  3.    LinkList p = L->next; 
  4.    while(p){ 
  5.       ++i; 
  6.       p = p->next; 
  7.    } 
  8.    return i; 
i的初值设为0而非1,p指针设为头指针L的下一个节点,即链表除头指针之后的第一个结点,只有当p测试为非空 (while(p))之后才能增加结点数,因此此处是i = 0而不是i = 1,p是L->next而不是L.

2. 获取带头结点单链表的第i个元素?

 
  
  1. Status GetElem(LinkList L,int i,ElemType *e)    
  2.  /* L为带头结点的单链表的头指针。当第i个元素存在时,其值赋给e并返回OK,否则返回ERROR */ 
  3.   int j=1; /* j为计数器 */ 
  4.   LinkList p=L->next; /* p指向第一个结点 */ 
  5.   while(p&&j<i) /* 依次向后查找,直到p指向第i个元素或p为空 */ 
  6.   {  
  7.     p=p->next;  
  8.     j++;  
  9.   }  
  10.   if(!p||j>i) /* 第i个元素不存在 */ 
  11.     return ERROR;  
  12.   *e=p->data; /* 取第i个元素 */ 
  13.   return OK;  
  14. }//Status定义为int类型,OK 和 ERROR 定义为 1 和 0,代表状态 

     为什么这里的j设计数器j = 1而不是前一个求单链表长度问题中的0呢(i = 0)?

     因为这里我们要求的是指向第i个元素的指针。注意到在求单链表长度的代码中,当跳出循环的时候p是为NULL的,也就是说p指向的实际上是第i个元素之后的下一个元素,所以当我们要求指向第i个元素的指针的时候,我们就必须让j的初值大1,这样当退出循环的时候就能保证指针p指向的是第i个元素了。(也可以用另外的一种方式,让初始的指针小1,即令p = L而不是L->next,j的初值仍然设为0,也可以达到同样的目的,实际上这样做和前面的方法是一样的效果:保证在退出循环的时候p指向的是第i个元素而不是第i+1个元素。)

 
  
  1. template<class ElemType>  
  2. Node<ElemType> *SimpleLinkList<ElemType>::GetElemPtr(int position) const 
  3. // 操作结果:返回指向第position个结点的指针  
  4. {  
  5.     Node<ElemType> *tmpPtr = head;      // 用tmpPtr遍历线性表以查找第position个结点  
  6.     int curPosition = 0;                // tmpPtr所指结点的位置   
  7.  
  8.     while (tmpPtr != NULL && curPosition < position)  
  9.     // 顺指针向后查找,直到tmpPtr指向第position个结点  
  10.     {  
  11.         tmpPtr = tmpPtr->next;  
  12.         curPosition++;  
  13.     }  
  14.  
  15.     if (tmpPtr != NULL && curPosition == position)  
  16.     {   // 查找成功  
  17.         return tmpPtr;    
  18.     }  
  19.     else 
  20.     {   // 查找失败  
  21.         return NULL;      
  22.     }  
  23.  

 3.在带头结点的单链线性表L中第i个位置之前插入元素e ?

 
  
  1. Status ListInsert(LinkList L,int i,ElemType e)  
  2. /* 在带头结点的单链线性表L中第i个位置之前插入元素e */ 
  3.   int j=0; 
  4.   LinkList p=L,s; 
  5.   while(p&&j<i-1) /* 寻找第i-1个结点 */ 
  6.   { 
  7.     p=p->next; 
  8.     j++; 
  9.   } 
  10.   if(!p||j>i-1) /* i小于1或者大于表长 */ 
  11.     return ERROR; 
  12.   s=(LinkList)malloc(sizeof(struct LNode)); /* 生成新结点 */ 
  13.   s->data=e; /* 插入L中 */ 
  14.   s->next=p->next; 
  15.   p->next=s; 
  16.   return OK; 

      在这里能否用j = 1和 p = L->next 代替上面代码中 j = 0 和 p = L 呢?

      其实是不能的,因为插入的位置可以在第一个结点的地方,如果我们用j = 1 和 p = L->next代替之后,就不能得到 i - 1位置是头结点的情形(因为一次都不循环while的情形下我们的p【待插入结点的前一个结点】已经是指向单链表中第一个结点 了),因此这里只好令j = 0, p = L,这样就能实现在头结点和第一个链表结点之间插入一个结点s了。