【问题标题】:LinkedList Delete End in CC中的LinkedList删除结束
【发布时间】:2013-07-31 10:30:49
【问题描述】:

我正在尝试用 C 编写一个简单的文本编辑器,并且我正在使用 LinkedList。 deleteEnd 函数有问题。我哪里做错了?

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

我将字符和字符的坐标存储在这样的结构中:

struct node {
    struct node *previous;
    char c;
    int x;
    int y;
    struct node *next;
}*head;

每当输入一个字母时都会调用它。

void characters(char typed, int xpos, int ypos)     //assign values of a node
{
    struct node *temp,*var,*temp2;
    temp=(struct node *)malloc(sizeof(struct node));
    temp->c=typed;
    temp->x=xpos;
    temp->y=ypos;

    if(head==NULL)
    {
        head=temp;
        head->next=NULL;
    }

    else
    {
        temp2=head;
        while(temp2!=NULL)
        {
            var=temp2;
            temp2=temp2->next;
        }
        temp2=temp;
        var->next=temp2;
        temp2->next=NULL;
    }
}

如果有变化,打印新节点。

void printer()          //to print everything
{
    struct node *temp;
    temp=head;
    while(temp!=NULL)
    {
        gotoxy(temp->x,temp->y);
        printf("%c",temp->c);
        temp=temp->next;
    }

}

现在到这里,不知道为什么head的最后一个元素不会被删除。

void deletesEnd()
{
    struct node *temp,*last;
    temp=head;
    while(temp!=NULL)
    {
        last=temp;
        temp=temp->next;
    }
    if(last->previous== NULL)
    {
        free(temp);
        head=NULL;
    }
    last=NULL;
    temp->previous=last;
    free(temp);
}

一切从这里开始。

main()
{
    char c;         //for storing the character
    int x,y;        //for the position of the character
    clrscr();
    for(;;)
    {
        c=getch();
        x=wherex();
        y=wherey();
        if(c==0x1b)     //escape for exit
        {
            exit(0);
        }

        else if (c==8)  //for backspace
        {
            deletesEnd();
            // clrscr();
            printer();
        }

        else            //normal characters
        {
            characters(c,x,y);
            printer();
        } 

    }
}

【问题讨论】:

  • 您有一个previous 链接,但在插入新节点时您从未设置过。
  • 我仍在处理 deleteFunction 然后插入将是下一个,然后在链表中间删除。我慢慢来,我是新手。 :)

标签: c list linked-list


【解决方案1】:

试试这个:

void deletesEnd()
{
struct node *temp,*last;
temp=head;
last = temp;
while(temp != NULL && temp->next!=NULL)
{
    last=temp;
    temp=temp->next;
}
if(last == temp)
{
    free(temp);
    head=NULL;
} else {
    free(last->next);
    last->next = NULL;
}

在您的算法中,您尝试使用 NULL 指针,因此您无法到达我认为的上一个节点。

【讨论】:

  • 这很好用。但是我仍然对使用 NULL 指针的部分感到困惑。如果这听起来很愚蠢,我很抱歉,我真的是linkedList的初学者。
  • 当你像这样循环时:while(temp!=NULL),当你到达一个 NULL 指针时你会停止。
  • 啊!是的,现在我明白了。谢谢你。 :)
【解决方案2】:

为了找到列表中的最后一个节点,最简单的方法是循环直到next指针为NULL

对于最后的删除,您还需要跟踪倒数第二个节点,它可能看起来像这样:

struct node *prev, *curr;

for (prev = NULL, curr = head; curr->next != NULL; prev = curr, curr = curr->next)
    ;

/* `curr` is now the last node in the list, `prev` is the next-to-last node */
if (prev != NULL)
    prev->next = NULL;  /* Unlink the last node */
else
    head = NULL;  /* List was only one node long */

/* Free the memory for the last node */
free(curr);

如果您正确地保持列表双链接,则循环会更容易,因为您不必再​​跟踪倒数第二个节点:

struct node *node;

for (node = head; node->next != NULL; node = node->next)
    ;

/* `node` is now the last node in the list */
if (node->previous != NULL)
    node->previous->next = NULL;  /* Unlink last node */
else
    head = NULL;  /* List was only one node long */

/* Free the memory for the last node */
free(curr);

并且从一开始就跟踪尾巴将使这更加简单:

if (tail != NULL)
{
    struct node *node = tail;

    if (node->previous != NULL)
    {
        node->previous->next = NULL;  /* Unlink last node */
        tail = node->previous;
    }
    else
        head = tail = NULL;  /* Removing last node in list */

    free(node);
}

【讨论】:

  • 我尝试了双链接,但一切都陷入了混乱。所以我想我应该先理解单链接,然后才能理解双链接。我是新手,慢慢来:D
  • @user2624491 即使使用单个链接列表,指向尾部的指针也很有用,特别是如果您像您一样只在末尾插入。 :)
【解决方案3】:

试试这个

void deletesEnd()
{
   struct node *temp,*last;
   temp=head;

   while(temp!=NULL)
   {
       last=temp;
       temp=temp->next;
   }

   if(last->previous== NULL)
   {
        free(temp);
        head=NULL;
   }

   last->previous->next = NULL;
   last=NULL;
   temp->previous=last;
   free(temp);
}

你看,你已经将列表中的最后一个元素放在last 中,然后last=NULL; 只是将null 放在last 变量中。 temp 已经是 NULL 所以 temp-&gt;previous=last; 没有意义。 您需要最后一项的上一项将指向NULL 作为行

last->previous->next = NULL;

【讨论】:

    【解决方案4】:

    链表只使用两个简单的通用规则...

    1. 首先制作链接
    2. 在制作之后,断开链接。

    只需检查条件...

    1. 如果您有空列表
    2. 如果列表只有一个节点
    3. 如果它有多个节点

    试试这些规则。我希望它对你有用。

    【讨论】:

      【解决方案5】:

      这一行:

      temp->previous=last;
      

      将给您带来问题,因为 temp 已经为 null (因为它是 while 循环中的终止条件)。

      将您的方法更改为:

      void deletesEnd()
      {
         struct node *temp,*last;
         temp=head;
         while(temp!=NULL)
         {
             last=temp;
             temp=temp->next;
         }
         if(last != NULL) {
             if (last->previous != null) { // Last element gonig to be deleted so the previous element if exists should point his next to null (end of list)       
                 last->previous->next = null;
             }   
             free(last); // Free the last element in the list
         }
      }
      

      【讨论】:

        猜你喜欢
        • 2013-11-02
        • 2015-08-26
        • 1970-01-01
        • 2012-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-08-14
        相关资源
        最近更新 更多