【问题标题】:Linked list: how to make sorter checker in C?链表:如何在 C 中制作分拣机检查器?
【发布时间】:2017-09-04 23:59:01
【问题描述】:

我认为这应该可以正常工作...我不确定它有什么问题?这是我的代码的 sn-p。如果给定的整数列表不是升序,则假设返回 0,如果是升序,则返回 1。

 struct Node{
    int data;
    Node *pNext;
 };

 int isItSorted(Node *pHead){
    while(pHead != NULL){
       if(pHead->data > pHead->pNext->data) 
          return 0;
       else
          return 1;
       pHead = pHead->pNext;
    }
    return 1;
 }

【问题讨论】:

  • 您的代码将遇到未定义的行为,因为您在取消引用之前没有验证pHead->pNext != NULL。这可能是您的问题的原因。
  • 另外,请发布您创建列表的代码 - 您可能没有正确初始化字段(例如在适当时将pNext 明确设置为NULL)。
  • 你的代码永远不会执行超过一次的循环迭代,因为循环体中有一个无条件的return
  • 您的代码在比较两个节点后返回,正如if(pHead->data > pHead->pNext->data) return 0; else return 1; 所期望的那样...无论是否在循环内,这将比较两个节点并返回。如果您不希望它返回,请删除 return 关键字(提示:您确实想在这些分支的 一个中使用 return,但是 不是另一个);你需要把一些其他逻辑放在那里... 你的书呢?

标签: c data-structures linked-list nodes


【解决方案1】:

正如@Dai 所说,当您在没有首先检查pHead->pNext != NULL 的情况下执行pHead->pNext->data 时,您会调用未定义的行为。此外,正如@JohnBollinger 所说,您在while 中有一个return 1 inside,因此它会在检查list[0] < list[1] 后返回,而不是遍历整个过程。

struct Node{
    int data;
    Node *pNext;
};

int isItSorted(Node *pHead){
   while(pHead != NULL && pHead->pNext != NULL) { // 0 and 1 element lists are always sorted, so this is fine.
      if(pHead->data > pHead->pNext->data) 
          return 0; // Break out and return
      else
          pHead = pHead->pNext; // Or keep going
   }
   return 1; // Lift out end case from loop
}

这也是一个尾递归版本:(编辑:clanggcc 似乎都不够聪明,无法注意到尾递归,即使是 -O3。哦,好吧。)

int isSorted(Node *list) {
  return list == NULL // [] is sorted
      || list->pNext == NULL // [x] is sorted
      || list->data <= list->pNext->data && isSorted(list->pNext); // x:y:z is sorted if x < y and y:z is sorted
}

【讨论】:

    【解决方案2】:

    这是你的(主要)问题:

    if(pHead->data > pHead->pNext->data) 
       return 0;
    else
       return 1;
    

    在循环中执行此操作将立即返回一个或零,仅基于前两项的比较。那是假设你 至少有两个项目,否则你有未定义的行为,因为你取消引用空指针。

    我将按如下方式实现它(伪代码),预先进行简单检查以捕捉边缘情况(少于两个项目),并继续检查项目以进行订购,而不是在之后返回一次检查:

    def isSorted(head):
        # Less than two items means sorted no matter what the data is.
    
        if head == NULL:
            return true
    
        if head.next == NULL:
            return true
    
        # Continue while there are at least two items to check.
    
        node = head
        while node.next != NULL:
            # If those two items out of order, it'snot sorted.
            # If they are in order, advance and keep checking.
    
            if node.data > node.next.data:
                return false
            node = node.next
    
        # Reaching here means all items were in order.
    
        return true
    

    【讨论】:

      【解决方案3】:

      您的代码中只有一个错误:

      struct Node{
          int data;
          Node *pNext;
       };
      
       int isItSorted(Node *pHead){
          while(pHead != NULL){
             if(pHead->next != NULL && pHead->data > pHead->pNext->data) {
                return 0;
             }
             pHead = pHead->pNext;
          }
          return 1;
       }
      

      在处理循环时,请务必检查退出条件。 例如,在您的代码中,如果它不进入 IF 块,那么它必然会返回 1。并且您的循环迭代将永远不会重复。

      就是这样。确保在处理循环时考虑 EXIT 条件。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-04-21
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多