添加到链表的尾部而不使用if

时间:2013-01-02 01:55:50

标签: c data-structures linked-list

这是一个面试问题,我想我会和你们其他人分享。

  

如何在不使用“if”的情况下有效地添加到链表的尾部?

从此功能中删除if。 (?仍为if)。

typedef struct tNode_ tNode;

struct tNode_ {
  tNode* pNext;
  int data;
};

tNode* pHead = NULL;
tNode* pTail = NULL;   

AddTail(tNode* pNode){
  if(!pTail) {
    pHead = pNode;
  }
  else {
    pTail->pNext = pNode;
  }
  pTail = pNode;
  pTail->pNext = NULL;
}

4 个答案:

答案 0 :(得分:2)

执行此操作的一种方法(使用愚蠢的方法)是使用短路逻辑运算符&&||的行为。例如,您可以这样做:

  AddTail(tNode* pNode){
      pTail || (pHead = pNode);
      !pTail || (pTail->pNext = pNode);

      pTail = pNode;
      pTail->pNext = NULL;
 }

这是有效的,因为如果ptail为null,则第一个语句的第一部分将计算为false,从而强制评估||语句的后半部分。如果它是非null,则不会评估语句的后半部分。类似的逻辑适用于下一个陈述。

那就是说,这是一个非常愚蠢的面试问题,老实说,我不知道他们会得到什么。就个人而言,我会质疑某人试图评估你编写这样代码的能力的智慧。

希望这有帮助!

答案 1 :(得分:1)

typedef struct tNode_ tNode;

struct tNode_ {
  tNode* pNext;
  int data;
};

/* normal initialization for pHead */

tNode* pHead = NULL;

/* the trick is to point at where you want the next pointer to go
 * instead of saving a pointer to the node.
 */
tNode** ppTail = &pHead;

AddTail(tNode* pNode){
  pNode->pNext = NULL;
  /* update the next pointer */
  *ppTail = pNode;
  /* save the address of the next pointer */
  ppTail = &pNode->pNext;
}

main(){
  int cnt;

  tNode* pNew;

  for(cnt=0; cnt<10; cnt++){
    pNew = malloc(sizeof(tNode));
    pNew->data = cnt;
    AddTail(pNew);
  }

  for(pNew = pHead; pNew; pNew = pNew->pNext){
    printf("%d\n", pNew->data);
  }
}

答案 2 :(得分:1)

我会为每个列表使用一个虚拟元素(或称为sentinel node)。附加到头部会附加到虚拟对象,附加到尾部只是附加到最后一个元素,然后根据定义存在。

typedef struct tNode_ tNode;

struct tNode_ {
  tNode* pNext;
  int data;
};

// The Remove operation must never remove this dummy!
tNode* pDummy = (tNode*)calloc(1, sizeof(tNode));
tNode* pHead = pDummy;
tNode* pTail = pDummy;

AddTail(tNode* pNode){
  pTail->pNext = pNode;
  pTail = pNode;
  pTail->pNext = NULL;
}

答案 3 :(得分:1)

tNode pHead;
tNode pTail;

void init() {
  pHead.pNext = &pTail;
  pTail.pNext = &pHead;
}

AddTail(tNode* pNode){
  pTail.pNext->pNext = pNode;
  pNode->pNext = &pHead;
  pTail.pNext = pNode;
}