C 程序与链表到 add/delete 整数并计算平均值
C program with linked list to add/delete integers & calculate avg
我正在尝试修改此代码以使用符号“+”将新数字添加到列表中并使用符号“-”删除。如果输入的数字是偶数,则应将数字插入列表的开头,如果是奇数,则应将其插入列表的末尾。程序将在输入 0(+0 或 -0)后结束。这是我的代码:
#include <stdio.h>
#include <stdlib.h>
typedef struct node{
int data;
struct node *ptr;
} node;
node * insert(node *head, int num)
{
node *temp = malloc(sizeof(node));
temp->data = num;
if (head == NULL || head->data > num)
{
temp->ptr = head;
head = temp;
}
else
{
node *current = head;
while ((current->ptr != NULL) && !(num < current->ptr->data))
{
current = current->ptr;
}
temp->ptr = current->ptr;
current->ptr = temp;
}
return head;
}
node * delete_if_less( node *head, int data )
{
while ( head != NULL && head->data < data )
{
node *temp = head;
head = head->ptr;
free( temp );
}
if ( head != NULL )
{
for ( node *current = head; current->ptr != NULL; )
{
if ( current->ptr->data < data )
{
node *temp = current->ptr;
current->ptr = current->ptr->ptr;
free( temp );
}
else
{
current = current->ptr;
}
}
}
return head;
}
void free_list(node *head) {
node *prev = head;
node *cur = head;
while(cur) {
prev = cur;
cur = prev->ptr;
free(prev);
}
}
int main(){
int num, min;
node *head, *p;
head = NULL;
do {
printf("Enter a number: ");
scanf("%d",&num);
if(num) {
head = insert(head, num);
for ( p = head; p != NULL; p = p->ptr )
{
printf("%d ", p->data);
}
printf("\n");
}
} while(num);
p = head;
printf("\nThe entered numbers are:\n");
while(p) {
printf("%d ", p->data);
p = p->ptr;
}
free_list(head);
head = delete_if_less( head, num );
if ( num != 0 ) {
printf( "There are deleted %zu nodes.\n", num );
}
printf("\nEnter minimum: ");
scanf("%d", & min);
return 0;
}
然后我希望它计算 1) 所有添加的整数的总和 2) 所有删除的整数的总和 3) 列表中剩余数字的总和 4) 剩余整数的数量 5)剩余数的算术平均数。输入应如下所示:
Enter +/- to add/del a number: +1
1
Enter +/- to add/del a number: +2
2 1
Enter +/- to add/del a number: +3
2 1 3
Enter +/- to add/del a number: +1
2 1 3 1
Enter +/- to add/del a number: +5
2 1 3 1 5
Enter +/- to add/del a number: -4
Numbers not in list.
2 1 3 1 5
Enter +/- to add/del a number: -3
2 1 1 5
Enter +/- to add/del a number: -1
2 1 5
Enter +/- to add/del a number: +0
2 1 5
add sum: 13
del sum: 5
total sum: 8
elements: 3
average: 2.67
谁能帮我解决这个问题?我会很感激。 :)
这是我对您的代码的处理方法!
我使用带哨兵的链表来优化一下。此外,由于在您的示例中您想保留有关已删除值的信息,因此程序中实际上有两个链表,一个用于 present 值,另一个用于 bin 个值。
它的工作原理与您在输入部分中描述的完全一样,尽管我添加了更多功能。
以下是可能的输入:
其中n是0到9的整数
+on -> 添加 n 到链表
-on -> 如果存在则从链表中删除 n,如果 n 不存在则打印错误消息
-an -> 从链表中删除所有出现的 n,如果 n 不存在则打印错误消息
+m -> 删除链表的最大值
-m -> 删除链表的最小值
0 -> 终止函数
当然你可以用不同的方式解析它以包含更大的 int 值,但我想我会把那部分留给你!
在每次操作时,两个链表将在终端上打印出来,这样您就可以看到您的操作结果和两个链表的当前状态。如果您的消息与解析不匹配,则会引发错误并将打印在终端上。删除链表中不存在的值也是如此。
输入 0 后,程序将根据您在示例中提出的要求计算列表的不同属性。
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
#include <err.h>
#include <errno.h>
#include <string.h>
#include <limits.h>
typedef struct node
{
int value;
struct node *next;
} node;
// Prints a string of characters.
static inline void print(const char* f, ...)
{
va_list args;
va_start(args, f);
vprintf(f, args);
va_end(args);
}
// Prints a string of characters followed by a new line.
static inline void println(const char* f, ...)
{
va_list args;
va_start(args, f);
vprintf(f, args);
va_end(args);
printf("\n");
}
static inline void* mem_alloc(size_t size)
{
void* p = malloc(size);
if (p == NULL)
{
err(EXIT_FAILURE, "Problem with malloc().");
}
return p;
}
// Verify if node is empty
int node_is_empty(node * head)
{
return head == NULL;
}
// Verify if node is not empty
int node_is_not_empty(node * head)
{
return head != NULL;
}
//Builds the sentinell of the node structure
node* node_build_sentinel()
{
// Creates the sentinel.
node* head = mem_alloc(sizeof(node));
head->value = 0;
head->next = NULL;
// Returns the head of the node which is the sentinell.
return head;
}
//Prints the contents of a node
void node_print(node* head)
{
print("{");
while(head->next)
{
head = head->next;
print(" %d", head->value);
}
println(" }");
}
//Frees the allocated node
void node_free(node* head)
{
node* previous;
while (head)
{
previous = head;
head = head->next;
free(previous);
}
}
// Inserts a value right after the head
/*
HEAD -> 1 -> 2 -> ..... -> 8
node_insert_beg(node* HEAD, int 42);
HEAD -> 42 -> 1 -> 2 -> ..... -> 8
*/
void node_insert_beg(node* head, int value)
{
node* tmp = mem_alloc(sizeof(node));
tmp->value = value;
tmp->next = head->next;
head->next = tmp;
}
// Inserts a value right after the head
/*
HEAD -> 1 -> 2 -> ..... -> 8
node_insert_end(node* HEAD, int 42);
HEAD -> 1 -> 2 -> ..... -> 8 -> 42
*/
void node_insert_end(node* head, int value)
{
node* tmp = mem_alloc(sizeof(node));
for (; node_is_not_empty(head->next); head = head->next)
{
//This loop runs to the last node and quits with head being that last node
continue;
}
tmp->value = value;
tmp->next = head->next;
head->next = tmp;
}
//Inserts odd values to the end and even values to the beginning
void node_insert_num(node* head, int value)
{
//odd
if(value % 2)
{
node_insert_end(head, value);
}
//even
else
{
node_insert_beg(head, value);
}
}
//Extracts the minimum value of the node (in other words deletes it from the node)
void node_extract_min(node* list,node *sup)
{
node *before_min = list;
while (list->next != NULL)
{
if (list->next->value < before_min->next->value)
{
before_min = list;
}
list = list->next;
}
node *output = before_min->next;
before_min->next = before_min->next->next;
output->next = NULL;
while (sup->next!=NULL)
{
sup = sup->next;
}
sup->next = output;
}
//Extracts the maximum value of the node (in other words deletes it from the node)
void node_extract_max(node* list, node* sup)
{
node *before_max = list;
while (list->next != NULL)
{
if (list->next->value > before_max->next->value)
{
before_max = list;
}
list = list->next;
}
node *output = before_max->next;
before_max->next = before_max->next->next;
output->next = NULL;
while (sup->next!=NULL)
{
sup = sup->next;
}
sup->next = output;
}
//Deletes the first occurence of value in node
int node_delete_first_occurence(node* head, node* sup, int value)
{
int seen = 0;
node *tmp = head;
while (head->next != NULL)
{
if (head->next->value == value)
{
tmp = head;
seen+=1;
break;
}
head = head->next;
}
if(seen == 0)
{
return seen;
}
node *output = head->next;
tmp->next = tmp->next->next;
output->next = NULL;
while (sup->next!=NULL)
{
sup = sup->next;
}
sup->next = output;
return seen;
}
//Deletes all occurences of value in node
int node_delete_all_occurences(node* head, node* sup, int value)
{
int seen = 0;
node *tmp = head;
while (head->next != NULL)
{
if (head->next->value == value)
{
seen+=1;
tmp = head;
node *output = head->next;
tmp->next = tmp->next->next;
output->next = NULL;
while (sup->next!=NULL)
{
sup = sup->next;
}
sup->next = output;
continue;
}
head = head->next;
}
return seen;
}
//Get a node at index if index invalid return NULL
//DOES NOT DELETE THE NODE
node * node_get_at(node* node, unsigned long index)
{
while (node != NULL && index > 0)
{
node = node->next;
index--;
}
if (node != NULL)
{
node = node->next;
}
return node;
}
int* node_sum(node * head)
{
int * sum_elem = malloc(sizeof(int)*2);
int sum = 0;
int elements = 0;
while (head->next != NULL)
{
elements+=1;
sum += head->next->value;
head = head->next;
}
sum_elem[0] = sum;
sum_elem[1] = elements;
return sum_elem;
}
int main()
{
node * present_node = node_build_sentinel();
node * deleted_nodes = node_build_sentinel();
char message[4];
while (1)
{
printf("Enter +/- followed by type (o = one/a = all/m = min or max) followed by the number to add/del a number or 0 to quit the app:");
scanf("%3s",message);
if(message[0] == '+')
{
if(message[1] == 'o')
{
node_insert_num(present_node,message[2] - '0');
node_print(present_node);
node_print(deleted_nodes);
continue;
}
if(message[1] == 'm')
{
node_extract_max(present_node,deleted_nodes);
node_print(present_node);
node_print(deleted_nodes);
continue;
}
if(message[1] == 'a')
{
printf("Invalid syntax on opperand 2 after + (no a is possible) please try again!\n");
}
else
{
printf("Invalid syntax on opperand 2 after + please try again!\n");
}
continue;
}
if(message[0] == '-')
{
if(message[1] == 'o')
{
int err = node_delete_first_occurence(present_node,deleted_nodes,message[2] - '0');
if(err == 0)
{
printf("The number to delete was not present in the node!\n");
}
node_print(present_node);
node_print(deleted_nodes);
continue;
}
if(message[1] == 'a')
{
int err = node_delete_all_occurences(present_node,deleted_nodes,message[2] - '0');
if(err == 0)
{
printf("The number to delete was not present in the node!\n");
}
node_print(present_node);
node_print(deleted_nodes);
continue;
}
if(message[1] == 'm')
{
node_extract_min(present_node,deleted_nodes);
node_print(present_node);
node_print(deleted_nodes);
continue;
}
else
{
printf("Invalid syntax on opperand 2 after - please try again!\n");
}
continue;
}
if(message[0] == '0')
{
break;
}
else
{
printf("Invalid syntax on opperand 1 please try again!\n");
}
}
int * present_sum_elem = node_sum(present_node);
printf("The sum of present node: %d \n",present_sum_elem[0]);
printf("The number of elements in present node: %d\n",present_sum_elem[1]);
if(present_sum_elem[1]!=0)
{
printf("The average of the present node %4f \n", (float)present_sum_elem[0]/(float)present_sum_elem[1]);
}
int * deleted_sum_elem = node_sum(deleted_nodes);
printf("The sum of deleted node: %d \n",deleted_sum_elem[0]);
printf("The number of elements in deleted node: %d\n",deleted_sum_elem[1]);
if(deleted_sum_elem[1] != 0)
{
printf("The average of the deleted node %4f \n", (float)deleted_sum_elem[0]/(float)deleted_sum_elem[1]);
}
free(present_sum_elem);
free(deleted_sum_elem);
node_free(present_node);
node_free(deleted_nodes);
return 0;
}
我正在尝试修改此代码以使用符号“+”将新数字添加到列表中并使用符号“-”删除。如果输入的数字是偶数,则应将数字插入列表的开头,如果是奇数,则应将其插入列表的末尾。程序将在输入 0(+0 或 -0)后结束。这是我的代码:
#include <stdio.h>
#include <stdlib.h>
typedef struct node{
int data;
struct node *ptr;
} node;
node * insert(node *head, int num)
{
node *temp = malloc(sizeof(node));
temp->data = num;
if (head == NULL || head->data > num)
{
temp->ptr = head;
head = temp;
}
else
{
node *current = head;
while ((current->ptr != NULL) && !(num < current->ptr->data))
{
current = current->ptr;
}
temp->ptr = current->ptr;
current->ptr = temp;
}
return head;
}
node * delete_if_less( node *head, int data )
{
while ( head != NULL && head->data < data )
{
node *temp = head;
head = head->ptr;
free( temp );
}
if ( head != NULL )
{
for ( node *current = head; current->ptr != NULL; )
{
if ( current->ptr->data < data )
{
node *temp = current->ptr;
current->ptr = current->ptr->ptr;
free( temp );
}
else
{
current = current->ptr;
}
}
}
return head;
}
void free_list(node *head) {
node *prev = head;
node *cur = head;
while(cur) {
prev = cur;
cur = prev->ptr;
free(prev);
}
}
int main(){
int num, min;
node *head, *p;
head = NULL;
do {
printf("Enter a number: ");
scanf("%d",&num);
if(num) {
head = insert(head, num);
for ( p = head; p != NULL; p = p->ptr )
{
printf("%d ", p->data);
}
printf("\n");
}
} while(num);
p = head;
printf("\nThe entered numbers are:\n");
while(p) {
printf("%d ", p->data);
p = p->ptr;
}
free_list(head);
head = delete_if_less( head, num );
if ( num != 0 ) {
printf( "There are deleted %zu nodes.\n", num );
}
printf("\nEnter minimum: ");
scanf("%d", & min);
return 0;
}
然后我希望它计算 1) 所有添加的整数的总和 2) 所有删除的整数的总和 3) 列表中剩余数字的总和 4) 剩余整数的数量 5)剩余数的算术平均数。输入应如下所示:
Enter +/- to add/del a number: +1
1
Enter +/- to add/del a number: +2
2 1
Enter +/- to add/del a number: +3
2 1 3
Enter +/- to add/del a number: +1
2 1 3 1
Enter +/- to add/del a number: +5
2 1 3 1 5
Enter +/- to add/del a number: -4
Numbers not in list.
2 1 3 1 5
Enter +/- to add/del a number: -3
2 1 1 5
Enter +/- to add/del a number: -1
2 1 5
Enter +/- to add/del a number: +0
2 1 5
add sum: 13
del sum: 5
total sum: 8
elements: 3
average: 2.67
谁能帮我解决这个问题?我会很感激。 :)
这是我对您的代码的处理方法!
我使用带哨兵的链表来优化一下。此外,由于在您的示例中您想保留有关已删除值的信息,因此程序中实际上有两个链表,一个用于 present 值,另一个用于 bin 个值。
它的工作原理与您在输入部分中描述的完全一样,尽管我添加了更多功能。
以下是可能的输入: 其中n是0到9的整数
+on -> 添加 n 到链表
-on -> 如果存在则从链表中删除 n,如果 n 不存在则打印错误消息
-an -> 从链表中删除所有出现的 n,如果 n 不存在则打印错误消息
+m -> 删除链表的最大值
-m -> 删除链表的最小值
0 -> 终止函数
当然你可以用不同的方式解析它以包含更大的 int 值,但我想我会把那部分留给你!
在每次操作时,两个链表将在终端上打印出来,这样您就可以看到您的操作结果和两个链表的当前状态。如果您的消息与解析不匹配,则会引发错误并将打印在终端上。删除链表中不存在的值也是如此。
输入 0 后,程序将根据您在示例中提出的要求计算列表的不同属性。
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
#include <err.h>
#include <errno.h>
#include <string.h>
#include <limits.h>
typedef struct node
{
int value;
struct node *next;
} node;
// Prints a string of characters.
static inline void print(const char* f, ...)
{
va_list args;
va_start(args, f);
vprintf(f, args);
va_end(args);
}
// Prints a string of characters followed by a new line.
static inline void println(const char* f, ...)
{
va_list args;
va_start(args, f);
vprintf(f, args);
va_end(args);
printf("\n");
}
static inline void* mem_alloc(size_t size)
{
void* p = malloc(size);
if (p == NULL)
{
err(EXIT_FAILURE, "Problem with malloc().");
}
return p;
}
// Verify if node is empty
int node_is_empty(node * head)
{
return head == NULL;
}
// Verify if node is not empty
int node_is_not_empty(node * head)
{
return head != NULL;
}
//Builds the sentinell of the node structure
node* node_build_sentinel()
{
// Creates the sentinel.
node* head = mem_alloc(sizeof(node));
head->value = 0;
head->next = NULL;
// Returns the head of the node which is the sentinell.
return head;
}
//Prints the contents of a node
void node_print(node* head)
{
print("{");
while(head->next)
{
head = head->next;
print(" %d", head->value);
}
println(" }");
}
//Frees the allocated node
void node_free(node* head)
{
node* previous;
while (head)
{
previous = head;
head = head->next;
free(previous);
}
}
// Inserts a value right after the head
/*
HEAD -> 1 -> 2 -> ..... -> 8
node_insert_beg(node* HEAD, int 42);
HEAD -> 42 -> 1 -> 2 -> ..... -> 8
*/
void node_insert_beg(node* head, int value)
{
node* tmp = mem_alloc(sizeof(node));
tmp->value = value;
tmp->next = head->next;
head->next = tmp;
}
// Inserts a value right after the head
/*
HEAD -> 1 -> 2 -> ..... -> 8
node_insert_end(node* HEAD, int 42);
HEAD -> 1 -> 2 -> ..... -> 8 -> 42
*/
void node_insert_end(node* head, int value)
{
node* tmp = mem_alloc(sizeof(node));
for (; node_is_not_empty(head->next); head = head->next)
{
//This loop runs to the last node and quits with head being that last node
continue;
}
tmp->value = value;
tmp->next = head->next;
head->next = tmp;
}
//Inserts odd values to the end and even values to the beginning
void node_insert_num(node* head, int value)
{
//odd
if(value % 2)
{
node_insert_end(head, value);
}
//even
else
{
node_insert_beg(head, value);
}
}
//Extracts the minimum value of the node (in other words deletes it from the node)
void node_extract_min(node* list,node *sup)
{
node *before_min = list;
while (list->next != NULL)
{
if (list->next->value < before_min->next->value)
{
before_min = list;
}
list = list->next;
}
node *output = before_min->next;
before_min->next = before_min->next->next;
output->next = NULL;
while (sup->next!=NULL)
{
sup = sup->next;
}
sup->next = output;
}
//Extracts the maximum value of the node (in other words deletes it from the node)
void node_extract_max(node* list, node* sup)
{
node *before_max = list;
while (list->next != NULL)
{
if (list->next->value > before_max->next->value)
{
before_max = list;
}
list = list->next;
}
node *output = before_max->next;
before_max->next = before_max->next->next;
output->next = NULL;
while (sup->next!=NULL)
{
sup = sup->next;
}
sup->next = output;
}
//Deletes the first occurence of value in node
int node_delete_first_occurence(node* head, node* sup, int value)
{
int seen = 0;
node *tmp = head;
while (head->next != NULL)
{
if (head->next->value == value)
{
tmp = head;
seen+=1;
break;
}
head = head->next;
}
if(seen == 0)
{
return seen;
}
node *output = head->next;
tmp->next = tmp->next->next;
output->next = NULL;
while (sup->next!=NULL)
{
sup = sup->next;
}
sup->next = output;
return seen;
}
//Deletes all occurences of value in node
int node_delete_all_occurences(node* head, node* sup, int value)
{
int seen = 0;
node *tmp = head;
while (head->next != NULL)
{
if (head->next->value == value)
{
seen+=1;
tmp = head;
node *output = head->next;
tmp->next = tmp->next->next;
output->next = NULL;
while (sup->next!=NULL)
{
sup = sup->next;
}
sup->next = output;
continue;
}
head = head->next;
}
return seen;
}
//Get a node at index if index invalid return NULL
//DOES NOT DELETE THE NODE
node * node_get_at(node* node, unsigned long index)
{
while (node != NULL && index > 0)
{
node = node->next;
index--;
}
if (node != NULL)
{
node = node->next;
}
return node;
}
int* node_sum(node * head)
{
int * sum_elem = malloc(sizeof(int)*2);
int sum = 0;
int elements = 0;
while (head->next != NULL)
{
elements+=1;
sum += head->next->value;
head = head->next;
}
sum_elem[0] = sum;
sum_elem[1] = elements;
return sum_elem;
}
int main()
{
node * present_node = node_build_sentinel();
node * deleted_nodes = node_build_sentinel();
char message[4];
while (1)
{
printf("Enter +/- followed by type (o = one/a = all/m = min or max) followed by the number to add/del a number or 0 to quit the app:");
scanf("%3s",message);
if(message[0] == '+')
{
if(message[1] == 'o')
{
node_insert_num(present_node,message[2] - '0');
node_print(present_node);
node_print(deleted_nodes);
continue;
}
if(message[1] == 'm')
{
node_extract_max(present_node,deleted_nodes);
node_print(present_node);
node_print(deleted_nodes);
continue;
}
if(message[1] == 'a')
{
printf("Invalid syntax on opperand 2 after + (no a is possible) please try again!\n");
}
else
{
printf("Invalid syntax on opperand 2 after + please try again!\n");
}
continue;
}
if(message[0] == '-')
{
if(message[1] == 'o')
{
int err = node_delete_first_occurence(present_node,deleted_nodes,message[2] - '0');
if(err == 0)
{
printf("The number to delete was not present in the node!\n");
}
node_print(present_node);
node_print(deleted_nodes);
continue;
}
if(message[1] == 'a')
{
int err = node_delete_all_occurences(present_node,deleted_nodes,message[2] - '0');
if(err == 0)
{
printf("The number to delete was not present in the node!\n");
}
node_print(present_node);
node_print(deleted_nodes);
continue;
}
if(message[1] == 'm')
{
node_extract_min(present_node,deleted_nodes);
node_print(present_node);
node_print(deleted_nodes);
continue;
}
else
{
printf("Invalid syntax on opperand 2 after - please try again!\n");
}
continue;
}
if(message[0] == '0')
{
break;
}
else
{
printf("Invalid syntax on opperand 1 please try again!\n");
}
}
int * present_sum_elem = node_sum(present_node);
printf("The sum of present node: %d \n",present_sum_elem[0]);
printf("The number of elements in present node: %d\n",present_sum_elem[1]);
if(present_sum_elem[1]!=0)
{
printf("The average of the present node %4f \n", (float)present_sum_elem[0]/(float)present_sum_elem[1]);
}
int * deleted_sum_elem = node_sum(deleted_nodes);
printf("The sum of deleted node: %d \n",deleted_sum_elem[0]);
printf("The number of elements in deleted node: %d\n",deleted_sum_elem[1]);
if(deleted_sum_elem[1] != 0)
{
printf("The average of the deleted node %4f \n", (float)deleted_sum_elem[0]/(float)deleted_sum_elem[1]);
}
free(present_sum_elem);
free(deleted_sum_elem);
node_free(present_node);
node_free(deleted_nodes);
return 0;
}