我正试图解决我的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;
}
答案 0 :(得分:2)
top
和head
之间有什么区别? head
仅在第一次推送后被分配,因此它始终指向堆栈的底部(最旧的节点); top
始终指向堆栈的顶部(最近的节点)。这看起来有点傻。 insertIntoS
从head
开始,并尝试向前转移index
个元素,但它已经在您的堆栈列表的末尾...您崩溃了。
似乎你做了两个变量top
和head
应该是同一个东西,并且你只在不同的地方使用了一个或另一个,所以它们的使用和价值是不一致的。或者,你有一些想法,两者都不同,并使用其中两个错误。
对我来说,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
...所以现在temp2
是NULL
(因为1后没有任何内容)。
在下一个for循环迭代(i = 1)中,您尝试访问temp2->next
但temp2
为NULL
...您尝试取消引用空指针并崩溃。< / 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