寻找不同的逻辑
Looking for a different logic
所以我写了这个未完成但可以工作的代码。我是编程的新手,我认为我的逻辑是错误的(尽管代码 运行 正确)因为有太多 "ifs and elses" 我想不出另一种工作逻辑来将数据插入到的任何位置链表并输出数据 + 如果位置无效则进行错误处理 我正在尝试发展计算思维
有些东西告诉我这段代码可以写得更好
#include <stdio.h>
#include <stdlib.h>
struct node {
int data;
struct node* next;
};
struct node* head = NULL;
void Insert(int c ,int e)
{
int i;
static int p = 1;
struct node* temp = malloc(sizeof(struct node));
temp -> data = c;
temp -> next = NULL;
struct node* temp1 = head;
if (e > p+1)
{
printf("Invalid Position");
return;
}
else if (head == NULL)
{
head = temp;
return;
}
else if (e <= 1)
{
temp -> next = head;
head = temp;
return;
}
else if (e == 2)
{
if (temp1 -> next != NULL)
{
temp -> next = temp1 -> next;
temp1 -> next = temp;
}
else
{
temp1 -> next = temp;
}
}
else
{
for (i = 0;i<e-2;i++)
{
temp1 = temp1 -> next;
}
temp -> next = temp1 -> next;
temp1 -> next = temp;
}
p++;
}
void print() {
struct node* temp = head;
printf("list is: \n");
while (temp != NULL) {
printf( "%d ,",temp->data);
temp = temp->next;
}
}
int main () {
printf("How Many Numbers?\n");
int a ,b ,c, e;
scanf("%d" , &b);
for(a = 0;a<b;a++) {
printf("Enter the numbers \n");
scanf("%d",&c);
printf("Enter position \n");
scanf("%d",&e);
Insert(c , e);
print();
}
return 0;
}
是的,您可以通过将两个条件合并为一个来将深度降低一级:
if (e > p + 1) {
printf("Invalid Position");
return;
}
else if (head == NULL) {
head = temp;
return;
}
else if (e <= 1) {
temp->next = head;
head = temp;
return;
}
else if (e == 2 && temp1->next != NULL) {
temp->next = temp1->next;
temp1->next = temp;
}
else if (temp1->next == NULL) {
temp1->next = temp;
}
else {
for (i = 0; i < e - 2; i++) {
temp1 = temp1->next;
}
temp->next = temp1->next;
temp1->next = temp;
}
当然 if 和 else 不是一个好的模式设计,但你应该在 C 中使用它。当你使用 OOP(面向对象编程)语言时你可以改变你的设计。
在 C 语言中,您应该拥有模块化代码,因此尽可能使用函数编写更小的代码部分。
您的 insert
函数可以稍微简化一下。本质上你有三个个条件需要考虑:
- inserting the first node into an empty list;
- inserting a new first node; and
- inserting a new node somewhere between the first and last.
在最后插入是默认的,不需要特别考虑。对每个单独编码,您可以重写 insert
如下:
void insert (int c, int e)
{
struct node *temp = malloc (sizeof *temp);
if (!temp) {
fprintf (stderr, "error: virtual memory exhausted.\n");
exit (EXIT_FAILURE);
}
temp->data = c;
temp->next = NULL;
if (!head) { head = temp; goto check; } /* empty list */
struct node *iter = head;
if (!e) { temp->next = head; head = temp; return; } /* new 1st node */
for (--e; e && iter->next; iter = iter->next, e--) {} /* iterate */
/* inserting before end, update temp->next */
if (iter->next) temp->next = iter->next;
iter->next = temp; /* add node as next */
check:;
if (e)
fprintf (stderr, "warning, 'e' beyond list, inserted at end.\n");
}
注意:使用insert
代替Insert
。 C 避免使用 Caps
和 caMelCase
作为变量名和函数名,取而代之的是所有 小写 。参见例如NASA - C Style Guide, 1994
如果您正在为列表分配内存,您应该跟踪已分配的内存,以便在不再需要时可以释放它。早点养成好习惯,不要简单地依靠退出为你做。你已经写了print()
,一个delete()
其实是一样的:
void delete ()
{
struct node *tmp = head;
while (tmp != NULL) {
struct node *victim = tmp;
tmp = tmp->next;
free (victim);
}
}
将所有部分放在一起并稍微清理剩余代码,您可以按如下方式重写您的示例:
#include <stdio.h>
#include <stdlib.h>
struct node {
int data;
struct node *next;
};
struct node *head = NULL;
void insert (int c, int e);
void print ();
void delete ();
int main (void) {
int a, b, c, e, rtn;
a = b = c = e = rtn = 0;
printf ("\nDefine list, values and positons (zero based positions)\n\n");
do {
printf (" numer of list elements?: ");
if ((rtn = scanf ("%d", &b)) != 1 || b < 1)
fprintf (stderr, "error: invalid input.\n");
if (rtn == EOF) exit (EXIT_FAILURE);
} while (b < 1);
for (a = 0; a < b; a++) {
do printf ("\n number %2d: ", a + 1);
while ((rtn = scanf ("%d", &c)) != 1 && rtn != EOF);
if (rtn == EOF) exit (EXIT_FAILURE);
do printf (" position : ");
while ((rtn = scanf ("%d", &e)) != 1 && e >= 0 && rtn != EOF);
if (rtn == EOF) exit (EXIT_FAILURE);
insert (c, e);
print ();
}
delete ();
return 0;
}
void insert (int c, int e)
{
struct node *temp = malloc (sizeof *temp);
if (!temp) {
fprintf (stderr, "error: virtual memory exhausted.\n");
exit (EXIT_FAILURE);
}
temp->data = c;
temp->next = NULL;
if (!head) { head = temp; goto check; } /* empty list */
struct node *iter = head;
if (!e) { temp->next = head; head = temp; return; } /* new 1st node */
for (--e; e && iter->next; iter = iter->next, e--) {} /* iterate */
/* inserting before end, update temp->next */
if (iter->next) temp->next = iter->next;
iter->next = temp; /* add node as next */
check:;
if (e)
fprintf (stderr, "warning, 'e' beyond list, inserted at end.\n");
}
void print ()
{
struct node *temp = head;
printf (" current list is: ");
while (temp != NULL) {
printf (" %d", temp->data);
temp = temp->next;
}
putchar ('\n');
}
void delete ()
{
struct node *tmp = head;
while (tmp != NULL) {
struct node *victim = tmp;
tmp = tmp->next;
free (victim);
}
}
例子Use/Output
$ ./bin/llins
Define list, values and positons (zero based positions)
numer of list elements?: 5
number 1: 6
position : 0
current list is: 6
number 2: 7
position : 3
warning, 'e' beyond list, inserted at end.
current list is: 6 7
number 3: 8
position : 0
current list is: 8 6 7
number 4: 9
position : 2
current list is: 8 6 9 7
number 5: 10
position : 3
current list is: 8 6 9 10 7
仔细阅读,如果您有任何问题,请告诉我。
所以我写了这个未完成但可以工作的代码。我是编程的新手,我认为我的逻辑是错误的(尽管代码 运行 正确)因为有太多 "ifs and elses" 我想不出另一种工作逻辑来将数据插入到的任何位置链表并输出数据 + 如果位置无效则进行错误处理 我正在尝试发展计算思维 有些东西告诉我这段代码可以写得更好
#include <stdio.h>
#include <stdlib.h>
struct node {
int data;
struct node* next;
};
struct node* head = NULL;
void Insert(int c ,int e)
{
int i;
static int p = 1;
struct node* temp = malloc(sizeof(struct node));
temp -> data = c;
temp -> next = NULL;
struct node* temp1 = head;
if (e > p+1)
{
printf("Invalid Position");
return;
}
else if (head == NULL)
{
head = temp;
return;
}
else if (e <= 1)
{
temp -> next = head;
head = temp;
return;
}
else if (e == 2)
{
if (temp1 -> next != NULL)
{
temp -> next = temp1 -> next;
temp1 -> next = temp;
}
else
{
temp1 -> next = temp;
}
}
else
{
for (i = 0;i<e-2;i++)
{
temp1 = temp1 -> next;
}
temp -> next = temp1 -> next;
temp1 -> next = temp;
}
p++;
}
void print() {
struct node* temp = head;
printf("list is: \n");
while (temp != NULL) {
printf( "%d ,",temp->data);
temp = temp->next;
}
}
int main () {
printf("How Many Numbers?\n");
int a ,b ,c, e;
scanf("%d" , &b);
for(a = 0;a<b;a++) {
printf("Enter the numbers \n");
scanf("%d",&c);
printf("Enter position \n");
scanf("%d",&e);
Insert(c , e);
print();
}
return 0;
}
是的,您可以通过将两个条件合并为一个来将深度降低一级:
if (e > p + 1) {
printf("Invalid Position");
return;
}
else if (head == NULL) {
head = temp;
return;
}
else if (e <= 1) {
temp->next = head;
head = temp;
return;
}
else if (e == 2 && temp1->next != NULL) {
temp->next = temp1->next;
temp1->next = temp;
}
else if (temp1->next == NULL) {
temp1->next = temp;
}
else {
for (i = 0; i < e - 2; i++) {
temp1 = temp1->next;
}
temp->next = temp1->next;
temp1->next = temp;
}
当然 if 和 else 不是一个好的模式设计,但你应该在 C 中使用它。当你使用 OOP(面向对象编程)语言时你可以改变你的设计。
在 C 语言中,您应该拥有模块化代码,因此尽可能使用函数编写更小的代码部分。
您的 insert
函数可以稍微简化一下。本质上你有三个个条件需要考虑:
- inserting the first node into an empty list;
- inserting a new first node; and
- inserting a new node somewhere between the first and last.
在最后插入是默认的,不需要特别考虑。对每个单独编码,您可以重写 insert
如下:
void insert (int c, int e)
{
struct node *temp = malloc (sizeof *temp);
if (!temp) {
fprintf (stderr, "error: virtual memory exhausted.\n");
exit (EXIT_FAILURE);
}
temp->data = c;
temp->next = NULL;
if (!head) { head = temp; goto check; } /* empty list */
struct node *iter = head;
if (!e) { temp->next = head; head = temp; return; } /* new 1st node */
for (--e; e && iter->next; iter = iter->next, e--) {} /* iterate */
/* inserting before end, update temp->next */
if (iter->next) temp->next = iter->next;
iter->next = temp; /* add node as next */
check:;
if (e)
fprintf (stderr, "warning, 'e' beyond list, inserted at end.\n");
}
注意:使用insert
代替Insert
。 C 避免使用 Caps
和 caMelCase
作为变量名和函数名,取而代之的是所有 小写 。参见例如NASA - C Style Guide, 1994
如果您正在为列表分配内存,您应该跟踪已分配的内存,以便在不再需要时可以释放它。早点养成好习惯,不要简单地依靠退出为你做。你已经写了print()
,一个delete()
其实是一样的:
void delete ()
{
struct node *tmp = head;
while (tmp != NULL) {
struct node *victim = tmp;
tmp = tmp->next;
free (victim);
}
}
将所有部分放在一起并稍微清理剩余代码,您可以按如下方式重写您的示例:
#include <stdio.h>
#include <stdlib.h>
struct node {
int data;
struct node *next;
};
struct node *head = NULL;
void insert (int c, int e);
void print ();
void delete ();
int main (void) {
int a, b, c, e, rtn;
a = b = c = e = rtn = 0;
printf ("\nDefine list, values and positons (zero based positions)\n\n");
do {
printf (" numer of list elements?: ");
if ((rtn = scanf ("%d", &b)) != 1 || b < 1)
fprintf (stderr, "error: invalid input.\n");
if (rtn == EOF) exit (EXIT_FAILURE);
} while (b < 1);
for (a = 0; a < b; a++) {
do printf ("\n number %2d: ", a + 1);
while ((rtn = scanf ("%d", &c)) != 1 && rtn != EOF);
if (rtn == EOF) exit (EXIT_FAILURE);
do printf (" position : ");
while ((rtn = scanf ("%d", &e)) != 1 && e >= 0 && rtn != EOF);
if (rtn == EOF) exit (EXIT_FAILURE);
insert (c, e);
print ();
}
delete ();
return 0;
}
void insert (int c, int e)
{
struct node *temp = malloc (sizeof *temp);
if (!temp) {
fprintf (stderr, "error: virtual memory exhausted.\n");
exit (EXIT_FAILURE);
}
temp->data = c;
temp->next = NULL;
if (!head) { head = temp; goto check; } /* empty list */
struct node *iter = head;
if (!e) { temp->next = head; head = temp; return; } /* new 1st node */
for (--e; e && iter->next; iter = iter->next, e--) {} /* iterate */
/* inserting before end, update temp->next */
if (iter->next) temp->next = iter->next;
iter->next = temp; /* add node as next */
check:;
if (e)
fprintf (stderr, "warning, 'e' beyond list, inserted at end.\n");
}
void print ()
{
struct node *temp = head;
printf (" current list is: ");
while (temp != NULL) {
printf (" %d", temp->data);
temp = temp->next;
}
putchar ('\n');
}
void delete ()
{
struct node *tmp = head;
while (tmp != NULL) {
struct node *victim = tmp;
tmp = tmp->next;
free (victim);
}
}
例子Use/Output
$ ./bin/llins
Define list, values and positons (zero based positions)
numer of list elements?: 5
number 1: 6
position : 0
current list is: 6
number 2: 7
position : 3
warning, 'e' beyond list, inserted at end.
current list is: 6 7
number 3: 8
position : 0
current list is: 8 6 7
number 4: 9
position : 2
current list is: 8 6 9 7
number 5: 10
position : 3
current list is: 8 6 9 10 7
仔细阅读,如果您有任何问题,请告诉我。