【问题标题】:How to write a push function that works with a linked list?如何编写与链表一起使用的推送函数?
【发布时间】:2019-11-24 20:12:59
【问题描述】:

我正在编写一个练习程序,我被告知要编写一个与链表一起使用的堆栈处理程序。代码如下:

#include <stdio.h>
#include <stdlib.h>

struct stackNode {
   char data;
   struct stackNode *nextPtr;
};

typedef struct stackNode StackNode;
typedef struct stackNode *StackNodePtr;

void push(StackNodePtr *topPtr, char value)
{
    StackNodePtr firstNode = *topPtr;
    while (1) {
        if (*topPtr == NULL) {
            *topPtr = (StackNodePtr) malloc(sizeof(StackNode));
            if (*topPtr == NULL) {
                puts("Error: Out of memory for push.");
                return;
            }
            (*topPtr)->nextPtr = NULL;
            (*topPtr)->data = value;
            break;
        }
        *topPtr = (*topPtr)->nextPtr;
    }
    *topPtr = firstNode;
}

int main()
{
   StackNodePtr stack = NULL;
   push(&stack, 'c'); // Program terminates in this function
   putchar(stack->data);
   return 0;
}

我还没有声明和实现 pop 函数,因为我对它没有任何问题。问题在于 push 函数。我希望程序将'c'字符压入堆栈然后打印它,但它终止了。你能更正我的代码吗?

【问题讨论】:

  • *topPtr = firstNode; 你先*topPtr = malloc。然后你只需break 并用初始值覆盖它。 firstNode 会发生什么?
  • 不需要特殊情况下的初始插入堆栈。分配一个新节点,将新节点的next设置为当前栈顶(可能为null),设置节点的value成员,最后将栈设置为新节点。完毕。没有循环。不相关的,在 typedef 别名中隐藏指针类型既没有帮助也没有必要。只有两种情况真正具有优势(黑盒“处理”API 和回调函数规范),而这两种情况都不是。 C 程序员想要看到星号。相信我。
  • 类型定义指针不是必需的,但我认为它可能会有所帮助。如果明确标识为指针(如 OP 在上面使用 'Ptr' 后缀所做的那样),它会避免显式双指针。我觉得这比星星的瘟疫更清晰、更干净:)

标签: c stack


【解决方案1】:

你的推送是不必要的循环,并且不必要地试图解释一个你真的不应该关心的情况(无论*topPtr是否为空):

void push(StackNode **topPtr, char value)
{
    StackNode *p = malloc(sizeof *p);
    if (p != NULL)
    {
        p->data = value;
        p->next = *topPtr;
        *topPtr = p;
    }
    else
    {
        perror("Failed to push value on stack");
    }
}

就是这样。您的原始代码看起来像是在尝试实现队列,而不是堆栈。不同的野兽。堆栈实际上更容易,因为它不需要在插入之前蹒跚到序列的另一端。

【讨论】:

  • 我知道栈和队列的区别。我对练习本想要我做的方式感到困惑。
【解决方案2】:

问题是 push 函数的最后一行将 null 分配给堆栈指针。当你调用 putchar(stack->data);它崩溃了。 尝试以下方法:

#include <stdio.h>
#include <stdlib.h>

struct stackNode {
   char data;
   struct stackNode *nextPtr;
};

typedef struct stackNode StackNode;
typedef struct stackNode *StackNodePtr;

void push(StackNodePtr *topPtr, char value)
{
    StackNodePtr firstNode = *topPtr;
    while (1) {
        if (*topPtr == NULL) {
            *topPtr = (StackNodePtr) malloc(sizeof(StackNode));
            if (*topPtr == NULL) {
                puts("Error: Out of memory for push.");
                return;
            }
            (*topPtr)->nextPtr = NULL;
            (*topPtr)->data = value;
            break;
        }
        *topPtr = (*topPtr)->nextPtr;
    }

}

int main()
{
   StackNodePtr stack = NULL;
   push(&stack, 'c'); // Program terminates in this function
   putchar(stack->data);
   return 0;
}

【讨论】:

    【解决方案3】:

    例如,如果您想将堆栈实现为数组,并使用数组加倍技术定义您的 stackNode 指针:

     // InitialSize
     static const int InitialSize = 1;
    
     typedef struct IntegerStackObj{
         int* item;         // array of IntegerStack items
         int numItems;      // number of items in this IntegerStack
         int physicalSize;  // current length of underlying array
     } IntegerStackObj;
    
    typedef struct IntegerStackObj* IntegerStack;
    
    //doubleItemArray
    // Doubles the physical size of the underlying array S->item.
    void doubleItemArray(IntegerStack S){
         int i;
         int* newArray;
         int* oldArray = S->item;
         S->physicalSize *= 2;
         newArray = calloc(S->physicalSize, sizeof(int));
         for( i=0; i<(S->numItems); i++){
         newArray[i] = oldArray[i];
         }
         S->item = newArray;
         free(oldArray);
    }
    
    // push()
    // Inserts int x into S on top of the stack
    void push(IntegerStack S, int x){
    
    if( S==NULL ){
          fprintf(stderr, "IntegerStack Error: push() called on NULL IntegerStack 
          reference");
          exit(EXIT_FAILURE);
         }
    
    // increase physical size of array if necessary
    
    if( (S->numItems)==(S->physicalSize) ){
         doubleItemArray(S);
        }
    
    S->item[S->numItems] = x;
    
    S->numItems++;
    }  
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-11-15
      • 2019-08-20
      • 1970-01-01
      • 1970-01-01
      • 2021-08-29
      • 2020-07-19
      • 1970-01-01
      • 2020-04-24
      相关资源
      最近更新 更多