删除链接列表中M个节点后的N个节点

时间:2013-08-10 07:23:38

标签: c pointers linked-list traversal

我写了一个C程序,用于删除m个节点后的n个节点。我无法弄清楚为什么它不起作用。使用头节点而不是头指针。使用头节点而不是头指针是否合适?

这是我的代码:

#include<stdio.h>
#include<stdlib.h>
struct node
{
    int data;
    struct node *next;
};

struct node* create()
{
    struct node *head=malloc(sizeof(struct node));
    head->next=NULL;
    return head;
}

void insert(struct node *head,int x)
{
    struct node *temp=head;
    struct node *new=malloc(sizeof(struct node));
    new->data=x;
    new->next=NULL;
    while(temp->next!=NULL)
        temp=temp->next;
    temp->next=new;

}

void display(struct node *head) {
    struct node *temp=head->next;
    while(temp!=NULL)
    {
        printf("\n%d\n",temp->data);
        temp=temp->next;
    }
}

void skipMDeleteN(struct node *head,int m,int n)
{
    int i;
    struct node *cur=head->next;
    while(cur)
    {printf("djhfj");
        for(i=1;i<m,cur!=NULL;i++)
            cur=cur->next;

        if(cur==NULL) return;

        struct node *t=cur->next;
        for(i=1;i<=n;i++)
        {
            struct node *temp=t;
            t=t->next;
            free(temp);
        }
        cur->next=t;
        cur=t;
    }
}

int main()
{
    struct node *head=create();
    int i;
    for(i=1;i<=10;i++)
    {
        insert(head,i);
    }
    int m=2,n=2;
    skipMDeleteN(head,m,n);
    display(head);
}

3 个答案:

答案 0 :(得分:0)

我修改了你的代码,可以使用头指针。

void skipMDeleteN(struct node *head,int m,int n)
{
    int i;
    struct node *cur=head->next; 
       // printf("djhfj");
        for(i=1;i<m&&cur!=NULL;i++)
            cur=cur->next;

        if(cur==NULL) 
            return;

        struct node *t=cur->next;
        for(i=1;i<=n&&t!= NULL;i++)
        {
            struct node *temp=t;
            t=t->next;
            free(temp);
        }
        cur->next=t;
 }

答案 1 :(得分:0)

以下是您的替代实现,我觉得这将简化您要实现的功能。诀窍是使用包装器结构。

从那以后,我将我的结构定义如下:

struct llnode {
  int item;
  struct llnode *next;
};

typedef struct llnode *Node;

struct linkedlist {
  Node front;
  int length; // Optional, useful for O(1) linked list length.
};

typedef struct linkedlist *LinkedList;

...在遍历n个节点后删除k个节点更容易实现。

实现列表的方式使得很多实现和客户端交互非常混乱,而且过于复杂。使用包装器结构可以简化一些抽象。现在,您的create函数如下所示。

LinkedList create_LinkedList( void ) {
  // Requests a block of memory from the memory pool for a struct linked list.
  LinkedList new_LinkedList = malloc( sizeof( struct linkedlist ) );

  // Determines whether we requested a valid block of memory.
  if ( new_LinkedList == NULL ) {
    // Handle the error appropriately.
  }

  // Mutates the fields of the new linked list structure.
  new_LinkedList->front = NULL;
  new_LinkedList->length = 0;

  return new_LinkedList;
}

遍历链接列表n个节点并删除k个节点 - 它与您实现它的方式类似。我只会将删除节点功能实现为遍历列表,如果为您提供删除节点的功能,则删除k个节点非常简单。它将实现如下:

int delete_FrontNode( LinkedList list ) {
  // Checks pre conditions.
  assert( list != NULL ); // Ensure it is not a NULL pointer.

  // Determines whether the length is already 0.
  if ( list->length == 0 ) return -1;

  // Define a backup pointer to the front node.
  Node ptr = list->front;

  // Define the return value (the node item).
  int const ret = ptr->item;

  // Mutate the front of the linked list to point to the next node.
  list->front = list->front->next;

  // Free the original front node.
  free( ptr );

  // Decrement the length of the linked list.
  list->length -= 1;

  return ret;
}

答案 2 :(得分:0)

修复如下:

for(i=1;i<m && cur != NULL;i++) //Replace ',' with &&
{
    cur=cur->next;
}
if(cur==NULL) return;

struct node *t=cur->next;
for(i=1;i<=n && t!=NULL;i++) // Check if t reaches end of node.
{
    struct node *temp=t;
    t=t->next;
    free(temp);
}