c - 寻找不同的逻辑

标签 c ubuntu codeblocks

<分区>

所以我写了这个未完成但有效的代码。我是编程的新手,我认为我的逻辑是错误的(尽管代码运行正常)因为有太多的“如果和其他”我想不出另一种工作逻辑来将数据插入链表的任何位置并输出如果位置无效,则数据 + 错误处理 我正在尝试发展计算思维 有些东西告诉我这段代码可以写得更好

#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;
}

最佳答案

您的insert 函数可以稍微简化一下。本质上,您需要考虑三个条件:

  1. inserting the first node into an empty list;
  2. inserting a new first node; and
  3. 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 避免使用 CapscaMelCase 变量和函数名称,以支持所有小写。参见例如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);
    }
}

示例使用/输出

$ ./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

仔细阅读,如果您有任何问题,请告诉我。

关于c - 寻找不同的逻辑,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37648863/

相关文章:

c++ - 静态内存使用的层次概述

c - open() 如何有两个定义,如手册页所示?

c++ - C++实现URL匹配

c# - 我对 Ubuntu/Mono/C# 有一个看似无法追踪的问题。我怎样才能找到它?

c - 使用 strcmp 的段错误 (Ubuntu)

c++ - 链接 libcurl 问题

无法在 code::blocks 13.12 on linuxmint 17 中运行 c/c++ 代码:状态 255

Cmocka:检查作为参数传递的结构

c++ - C++ [Codeblocks/Visual Studio] 中没有这样的目录或文件

c++ - GL/glx 没有正确链接