插入堆栈头部的第N个位置

时间:2015-07-12 06:55:42

标签: c linked-list stack

我正试图解决我的insertIntoS功能问题。我试图从堆栈的头点插入一个值到链表或堆栈。但是,我这样做,它崩溃了。它从我的顶点开始工作,我觉得它是因为头点指向NULL。这是我的问题吗?我如何解决这个问题才能从头部插入第n个位置?

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

typedef struct node{
    int data;
    struct node *next;
} Node;

typedef struct elem {
    int data;
    struct elem *next;
} Element;

Node *top = NULL;
Node *head = NULL;
Element *rear = NULL;
Element *front = NULL;
void pop();
void display();
void push (int num);
void dequeue();
void displayQ();
void insertIntoS(int data, int index);
void insertIntoQ(int data, int index);
void enqueue(int num);

int main(){
    int choice, num, index;

    while(1) {
        printf("\n 1 - Push");
        printf("\n 2 - Pop");
        printf("\n 3 - display stack");
        printf("\n 4 - Enqueue");
        printf("\n 5 - Dequeue ");
        printf("\n 6 - Show Queue ");
        printf("\n 7 - Insert Into Queue ");
        printf("\n 8 - Insert Into Stack ");
        printf("\n 9 - Exit ");
        printf("\n Please enter your choice");
        scanf("%d",&choice);
        switch (choice) {
            case 1:
                printf("Enter Data : ");
                scanf("%d", &num);
                push(num);
                break;
            case 2:
                pop();
                break;
            case 3:
                display();
                break;
            case 4:
                printf("Enter Data: ");
                scanf("%d", &num);
                enqueue(num);
                break;
            case 5:
                dequeue();
                break;
            case 6:
                displayQ();
                break;
            case 7:
                printf("Enter Data: ");
                scanf("%d", &num);
                printf("Enter the index: ");
                scanf("%d", &index);
                insertIntoQ(num, index);
                break;
            case 8:
                printf("Enter Data: ");
                scanf("%d", &num);
                printf("Enter the index: ");
                scanf("%d", &index);
                insertIntoS(num, index);
                break;
            case 9:
                exit(0);
            default:
                break;
        }
    }
}

void push (int num){
    Node *temp = (Node*) malloc(sizeof(Node));
    if(temp == NULL){
        printf("Stack OVERFLOW");
        return;
    }

    if(head == NULL) {
         temp->data = num;
        temp->next = NULL;
        head = temp;
        printf("Value of the head after push : %d \n", head->data);
    }
    temp->data = num;
    temp->next = top;
    top = temp;
}

void pop(){
    Node *temp;
    if(top == NULL){
        printf("You are trying to pop from a stack that is empty");
        return;
    }
    temp = top;
    top = top->next;
    free(temp);
}

void display(){
    Node *p;
    if(top == NULL){
        printf("Empty Stack");
        return;
    }
    printf("\n Stack : \n");
    p=top;
    while(p != NULL){
        printf("%d\n", p->data);
        p=p->next;
    }
}

void displayQ(){
    Element *p = front;
    if(p == NULL){
        printf("Empty stack\n");
        return;
    }else{
        printf("Queue: \n");
        while(p != NULL){
            printf("%d\n", p->data);
            p=p->next;
        }
    }
}

void dequeue(){
    Element *temp = front;
    if(front == NULL){
        printf("Queue is empty");
        return;
    }
    if(front == rear){
        front = rear = temp;
    }else{
        front = front->next;
    }
    free(temp);
}

void enqueue(int num){
    Element *temp = (Element*) malloc(sizeof(Element));
    if(temp == NULL){
        printf("Stack OVERFLOW");
        return;
    }
    temp->data = num;
    temp->next = NULL;
    if(front == NULL && rear == NULL){
        front = rear = temp;
    }
    rear->next = temp;
    rear = temp;
    printf("value of rear in enque: %d\n", rear->data);
}

void insertIntoQ(int data, int index){
    int i;
    Element *temp = (Element*) malloc(sizeof(Element));
    temp->data = data;
    temp->next = NULL;
    if(index == 1){
        temp->next = rear;
        rear = temp;
        return;
    }
    Element *temp1 = rear;
    for(i = 0; i<index;i++){
        temp1 = temp1->next;
    }
    temp->next = temp1->next;
    temp1->next = temp1;
}

void insertIntoS(int data, int index){
    int i;
    Node *temp1 = (Node*) malloc(sizeof(Node));
    temp1->data = data;
    temp1->next = NULL;
    if(index == 1){
        temp1->next = head;
        head = temp1;
        return;
    }

    printf("Value of head in insert %d\n", head->data);
    Node *temp2 = head;

    for(i = 0; i<index;i++){
        temp2 = temp2->next;
        printf("i count : %d\n", i);
    }
    temp1->next = temp2->next;
    temp2->next = temp1;
}

3 个答案:

答案 0 :(得分:2)

tophead之间有什么区别? head仅在第一次推送后被分配,因此它始终指向堆栈的底部(最旧的节点); top始终指向堆栈的顶部(最近的节点)。这看起来有点傻。 insertIntoShead开始,并尝试向前转移index个元素,但它已经在您的堆栈列表的末尾...您崩溃了。

似乎你做了两个变量tophead应该是同一个东西,并且你只在不同的地方使用了一个或另一个,所以它们的使用和价值是不一致的。或者,你有一些想法,两者都不同,并使用其中两个错误。

对我来说,head似乎不应该存在,top就是你要在整个过程中使用的。

更详细:

我假设您正在输入序列“按1,按2,按3,按4,按5,在索引3处插入9”。

push()中,当{且仅仅head时,您指定NULL。因此,在第一次推送价值1时,head指向节点{.data = 1}。 top也指向同一个节点{.data = 1}。

第二个上向后推,head != NULL,以便跳过if语句。 head不会更改,它会一直指向节点{.data = 1}处的堆栈底部!但top始终指向最新的Node。

所以在你的推动结束时,你有:

5    4    3    2    1
^                   ^
top                 head

现在你调用insertIntoS(9,3)。

首先分配temp2 = head,现在temp2指向节点{.data = 1}的堆栈底部。在for循环(i = 0)中,您指定temp2 = temp2->next ...所以现在temp2NULL(因为1后没有任何内容)。

在下一个for循环迭代(i = 1)中,您尝试访问temp2->nexttemp2NULL ...您尝试取消引用空指针并崩溃。< / p>

insertIntoS应该从堆栈开头的5开始(即top),对吗?这个head变量看起来有点不稳定。

答案 1 :(得分:1)

如果我理解正确,你必须写两个容器:Stack and Queue。

实际上,您可以为两个容器使用相同的结构Node。然而,在演示程序中,我对Stack的节点和Queue的节点使用了两种不同的结构,并将这些结构封装在结构Stack和structure Queue中。

以Stack的实现为模板,您需要自己编写Queue的实现。

这是示范性计划。

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

struct Stack
{
    struct Node
    {
        int data;
        struct Node *next;
    } *top;
} stack;

void push ( int data )
{
    struct Node *tmp = malloc( sizeof( struct Node ) );
    tmp->data = data;
    tmp->next = stack.top;
    stack.top = tmp;

    printf( "Value on the top of the stack after push: %d \n", stack.top->data );
}    

void pop()
{
    if ( stack.top == NULL )
    {        
        printf( "You are trying to pop from a stack that is empty" );
    }
    else
    {
        struct Node *tmp = stack.top;
        stack.top = stack.top->next;
        printf( "The popped value from the stack: %d \n",  tmp->data );
        free( tmp );
    }
}    

_Bool is_stack_empty()
{
    return stack.top == NULL;
}

void clear_stack()
{
    while ( stack.top != NULL )
    {
        struct Node *tmp = stack.top;
        stack.top = stack.top->next;
        free( tmp );
    }
}

void insert_into_stack( int data, size_t index )
{
    struct Node *tmp = malloc( sizeof( struct Node ) );
    tmp->data = data;

    struct Node *after = NULL, *before = stack.top;
    size_t i = 0;

    for ( ; before != NULL && i < index; i++ )
    {
        after = before;
        before = before->next;
    } 

    tmp->next = before;
    if ( after == NULL )
    {
        stack.top = tmp;
    }
    else
    {
        after->next = tmp;
    }        

    printf( "Value %d is inserted at position %zu\n", tmp->data, i );
}    

void display_stack()
{
    if ( is_stack_empty() )
    {
        puts( "Stack is empty" );
    }
    else
    {
        printf( "\nStack:" );
        for ( struct Node *tmp = stack.top; tmp != NULL; tmp = tmp->next )
        {
            printf( " %d", tmp->data );
        }
        printf( "\n" );
    }
}

struct Queue
{
    struct Elem
    {
        int data;
        struct Elem *next;
    } *head, *tail;
} queue;

int main( void )
{
    int choice;

    do 
    {
        printf("\n  1 - Push");
        printf("\n  2 - Pop");
        printf("\n  3 - Insert Into Stack ");
        printf("\n  4 - Display Stack");
        printf("\n  5 - clear Stack");
        printf("\n  6 - Enqueue");
        printf("\n  7 - Dequeue ");
        printf("\n  8 - Insert Into Queue ");
        printf("\n  9 - Display Queue ");
        printf("\n 10 - Display Queue ");
        printf("\n 11 - Clear Queue ");
        printf("\n  0 - Exit ");
        printf("\n\n Please enter your choice: ");

        choice = 0;                  
        scanf( "%d", &choice );

        switch ( choice ) 
        {
            case 1:
            {
                int data = 0;
                printf("Enter Data : ");
                scanf( "%d", &data );
                push( data );
                break;
            }                
            case 2:
            {                
                pop();
                break;
            }                
            case 3:
            {
                int data = 0;
                printf("Enter Data : ");
                scanf( "%d", &data );
                size_t index = 0;
                printf( "Enter the index: " );
                scanf( "%zu", &index );
                insert_into_stack( data, index );
                break;
            }                
            case 4:
            {                
                display_stack();
                break;
            }                
            case 5:
            {                
                clear_stack();
                break;
            }                
            case 6: case 7: case 8: case 9: case 10:
            {                
                puts( "\nWrite it yourself\n" );
                break;
            }                
            default:
            {
                if ( choice != 0 ) 
                {                   
                    puts( "\nInvalid input. Try again.\n" );
                }
                else
                {
                    if ( !is_stack_empty() ) clear_stack();
                    //if ( !is_queue_empty() ) clear_queue();
                }                    
                break;
            }
        }                
    } while ( choice != 0 );                
}    

可能有以下输出

  1 - Push
  2 - Pop
  3 - Insert Into Stack 
  4 - Display Stack
  5 - clear Stack
  6 - Enqueue
  7 - Dequeue 
  8 - Insert Into Queue 
  9 - Display Queue 
 10 - Display Queue 
 11 - Clear Queue 
  0 - Exit 

 Please enter your choice: 1
 Enter Data : 1
 Value on the top of the stack after push: 1 

  1 - Push
  2 - Pop
  3 - Insert Into Stack 
  4 - Display Stack
  5 - clear Stack
  6 - Enqueue
  7 - Dequeue 
  8 - Insert Into Queue 
  9 - Display Queue 
 10 - Display Queue 
 11 - Clear Queue 
  0 - Exit 

 Please enter your choice: 1
 Enter Data : 2
 Value on the top of the stack after push: 2 

  1 - Push
  2 - Pop
  3 - Insert Into Stack 
  4 - Display Stack
  5 - clear Stack
  6 - Enqueue
  7 - Dequeue 
  8 - Insert Into Queue 
  9 - Display Queue 
 10 - Display Queue 
 11 - Clear Queue 
  0 - Exit 

 Please enter your choice: 4
 Stack: 2 1

  1 - Push
  2 - Pop
  3 - Insert Into Stack 
  4 - Display Stack
  5 - clear Stack
  6 - Enqueue
  7 - Dequeue 
  8 - Insert Into Queue 
  9 - Display Queue 
 10 - Display Queue 
 11 - Clear Queue 
  0 - Exit 

 Please enter your choice: 3
 Enter Data : 3
 Enter the index: 1
 Value 3 is inserted at position 1

  1 - Push
  2 - Pop
  3 - Insert Into Stack 
  4 - Display Stack
  5 - clear Stack
  6 - Enqueue
  7 - Dequeue 
  8 - Insert Into Queue 
  9 - Display Queue 
 10 - Display Queue 
 11 - Clear Queue 
  0 - Exit 

 Please enter your choice: 4
 Stack: 2 3 1

  1 - Push
  2 - Pop
  3 - Insert Into Stack 
  4 - Display Stack
  5 - clear Stack
  6 - Enqueue
  7 - Dequeue 
  8 - Insert Into Queue 
  9 - Display Queue 
 10 - Display Queue 
 11 - Clear Queue 
  0 - Exit 

 Please enter your choice: 0

答案 2 :(得分:0)

以下代码

1) compiles cleanly, 
2) contains several comments indicating probable problem areas
3) checks for errors in system calls (I.E. malloc)

发布的代码正在尝试创建/操作循环队列 并尝试创建/操作链表

两个活动都存在逻辑错误,我不确定哪个活动包含您找到的问题。

在退出程序之前,发布的代码(以及此代码)无法将所有malloc内存传递给free()。​​

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

typedef struct node{
    int data;
    struct node *next;
} Node;

typedef struct elem {
    int data;
    struct elem *next;
} Element;

Node *top = NULL;
Node *head = NULL;

Element *rear = NULL;
Element *front = NULL;

void pop( void );
void display( void );
void push (int num);
void dequeue( void );
void displayQ( void );
void insertIntoS(int data, int index);
void insertIntoQ(int data, int index);
void enqueue(int num);

int main()
{
    int choice;
    int num;
    int index;

    while(1)
    {
        printf("\n 1 - Push");
        printf("\n 2 - Pop");
        printf("\n 3 - display stack");
        printf("\n 4 - Enqueue");
        printf("\n 5 - Dequeue ");
        printf("\n 6 - Show Queue ");
        printf("\n 7 - Insert Into Queue ");
        printf("\n 8 - Insert Into Stack ");
        printf("\n 9 - Exit ");
        printf("\n Please enter your choice");

        if( 1 != scanf("%d",&choice) )
        { // then scanf failed
            perror( "scanf for menu choice failed");
            exit( EXIT_FAILURE);
        }

        // immplied else, scanf successful

        switch (choice)
        {
            case 1:
                printf("Enter Data : ");
                scanf("%d", &num);
                push(num);
                break;

            case 2:
                pop();
                break;

            case 3:
                display();
                break;

            case 4:
                printf("Enter Data: ");
                scanf("%d", &num);
                enqueue(num);
                break;

            case 5:
                dequeue();
                break;

            case 6:
                displayQ();
                break;

            case 7:
                printf("Enter Data: ");
                scanf("%d", &num);
                printf("Enter the index: ");
                scanf("%d", &index);
                insertIntoQ(num, index);
                break;

            case 8:
                printf("Enter Data: ");
                scanf("%d", &num);
                printf("Enter the index: ");
                scanf("%d", &index);
                insertIntoS(num, index);
                break;

            case 9:
                exit(0);

            default:
                printf( "invalid value entered, valid values 0...9\n");
                break;
        } // end switch
    } // end while
} // end function: main


void push (int num)
{
    Node *temp = malloc(sizeof(Node));
    if(temp == NULL)
    {
        perror( "malloc for new stack node failed");
        exit( EXIT_FAILURE);
    }

    // implied else, malloc successful

    if(NULL == head )
    {
        temp->data = num;
        temp->next = NULL;
        head = temp;
        printf("Value of the head after push : %d \n", head->data);
    }

    else
    {
        temp->data = num;
        temp->next = top;
        top = temp;
    }
} // end function: push


void pop()
{
    Node *temp;
    if(NULL == top)
    {
        printf("You are trying to pop from a stack that is empty");
        return;
    }

    temp = top;
    top = top->next;
    free(temp);
} // end function: pop


void display()
{
    Node *p;

    if(top == NULL)
    {
        printf("Empty Stack");
        return;
    }

    printf("\n Stack : \n");
    p=top;

    while(p != NULL)
    {
        printf("%d\n", p->data);
        p=p->next;
    }
} // end function: display


void displayQ()
{
    Element *p = front;

    if(p == NULL)
    {
        printf("Empty stack\n");
        return;
    }

    else
    {
        printf("Queue: \n");

        while(p != NULL){
            printf("%d\n", p->data);
            p=p->next;
        }
    }
} // end function: displayQ


void dequeue()
{
    Element *temp = front;

    if(NULL == front)
    {
        printf("Queue is empty");
        return;
    }

    // nonsence code block
    if(front == rear)
    {
        front = rear = temp;
    }

    else
    {
        front = front->next;
    }

    free(temp);
} // end funtion: dequeue


void enqueue(int num)
{
    Element *temp = malloc(sizeof(Element));
    if(NULL == temp )
    {
        perror( "malloc for new element failed");
        exit( EXIT_FAILURE);
    }

    // implied else, malloc successful

    temp->data = num;
    temp->next = NULL;

    if(front == NULL && rear == NULL){
        front = rear = temp;
    }

    else
    {
    rear->next = temp;
    rear = temp;  // probably incorrect
    }

    printf("value of rear in enque: %d\n", rear->data);
} // end function: enqaueue


void insertIntoQ(int data, int index)
{
    int i;
    Element *temp = malloc(sizeof(Element));
    if( NULL == temp)
    { // then malloc failed
        perror( "malloc for new Element failed");
        exit( EXIT_FAILURE );
    }

    // implied else, malloc successful

    temp->data = data;
    temp->next = NULL;

    // probably incorrect
    if(index == 1){
        temp->next = rear;
        rear = temp;
        return;
    }

    Element *temp1 = rear;
    for(i = 0; i<index;i++)
    {
        temp1 = temp1->next;
    }

    temp->next = temp1->next;
    temp1->next = temp1; // probably should be: templ->next = temp;
}

void insertIntoS(int data, int index)
{
    int i;
    Node *temp1 = malloc(sizeof(Node));
    if( NULL == temp1)
    { // then malloc failed
        perror( "malloc for new Node failed");
        exit( EXIT_FAILURE);
    }

    // implied else, malloc successful

    temp1->data = data;
    temp1->next = NULL;

    // probably incorrect as loses all other nodes
    if(index == 1)
    {
        temp1->next = head;
        head = temp1;
        return;
    }

    printf("Value of head in insert %d\n", head->data);
    Node *temp2 = head;

    for(i = 0; i<index;i++)
    {
        temp2 = temp2->next;
        printf("i count : %d\n", i);
    }

    // following 2 lines probably incorrect
    temp1->next = temp2->next;
    temp2->next = temp1;
} // end function: insertIntoS