使用指向start节点的单个指针删除单个链表的最后一个节点

时间:2013-06-19 06:43:13

标签: c

我可以在C - 中使用以下原型删除最后一个节点: int delete(struct node * head,int item)

注意:这里的第一个参数是指向启动节点而不指向指向启动节点的指针。

由于

9 个答案:

答案 0 :(得分:5)

是。可以从第一个节点开始删除单链表的最后一个节点。

请尝试以下代码

int delete(struct node *head)
{
  struct node *temp =head;
  struct node *t;
  while(temp->next != NULL)
  {
    t=temp;
    temp=temp->next;
  }
  free(t->next);
  t->next=NULL; 
}  

但是如果链接列表中只有一个元素,那么在删除该元素之后,您的头指针仍将指向您调用delete()的函数中现在已删除的内存位置。在这种情况下,请使用以下版本的delete()

struct node *delete(struct node *head)
{
  struct node *temp =head;
  struct node *t;
  if(head->next==NULL)
  {
    free(head);
    head=NULL;
  }
  else
  {
     while(temp->next != NULL)
     {
        t=temp;
        temp=temp->next;
     }
     free(t->next);
     t->next=NULL; 
  }    
  return head;
}

按如下方式调用函数delete()

head=delete(head);

答案 1 :(得分:2)

答案取决于问题的确切含义。

当然,如果列表包含多个元素,您可以轻松安全地删除最后一个元素(=列表的尾部元素)。只需迭代到最后一个元素,删除最后一个元素并更新新的最后一个元素中的next指针。请注意,在这种情况下,调用者的head指针将仍然是指向有效列表的完全有效的指针。

但是,如果列表最初只包含一个元素(意味着head已经指向最后一个元素),那么,当然,您仍然可以轻松删除它,但遗憾的是您无法更新调用者的{来自head函数内部的{1}}指针。删除后,调用者的delete指针将变为无效。它将指向现在释放的内存,即它将成为一个悬空指针。

通常,当一个人实现这样的功能时,应该确保调用者知道列表何时变空。它可以以不同的方式实现。例如,如果第一个参数被声明为指向头节点的指针,那么调用者的head指针可以从head函数内部访问和修改

delete

或者,可以使int delete(struct node **phead, int item) ... delete(&head, 42); 函数始终返回更新的头指针值

delete

我不知道这个问题在你的案例中是否重要。你提到struct node *delete(struct node *head, int item); ... head = delete(head, 42); “不是指向指针的事实”表明这可能确实很重要。

P.S。我怀疑你的问题中的“last”一词并不是指列表的尾部元素,而是指列表中最后剩下的元素。即问题是关于只剩下一个元素的情况。在这种情况下,见上文......

答案 2 :(得分:0)

是的,您可以循环浏览每个list_node->接下来,从head->开始,直到list_node-> next为null。此时,当前list_node是要删除的那个。如果我理解你的问题......

答案 3 :(得分:0)

如果您正在寻找删除链接列表最后一个节点的方法,这段代码将适用于您:)

int delete(struct node *head, int item)
    {
        if(head==NULL)
        {
            printf("\n\t\t~~~NO NODE PRESENT~~~\n\t\t\t :p\n");
            return 0;
        }
        else
        {
            struct node*temp;
            struct node*temp2;
            temp=head; // just to keep a record of original head.
            while(temp->n->n !=NULL)
            {
                temp=temp->n;
            }
            temp2=temp->n;
            temp->n=NULL;
            free(temp2);
        }
        return 0;
    }

答案 4 :(得分:0)

此代码适用于删除链接列表的最后一个元素。

void dellast()
{

r=head;

    struct node* z;
    do
    {
        z=r;
        r=r->next;
        if(r->next==NULL)
        {
            z->next=NULL;
            free(r->next);
        }   
    }while(z->next!=NULL);
}

答案 5 :(得分:0)

是的,这很容易.. 继续按照... 假设你的链表有第一个节点头最后一个节点'last'..然后添加任何节点temp和ctemp ...

temp = header;
while(temp->link != NULL)
{
    ctemp = temp;
    temp = temp->link;
}
ctemp->link = NULL;
delete temp;

答案 6 :(得分:0)

我和你一样做了同样的努力,但终于干净利落地实施了它。随意使用代码。 您的问题在int remove_end(LinkedList *list)处理。

这是完整的工作实施:

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

/********** GLOBALS *******************************/
#define OK 0
#define ERROR -1

/********** STRUCT AND TYPES DEFINTIONS ***********/
/* a node with key, data and reference to next node*/
typedef struct Node {
    int key;
    char string[1024];
    struct Node *next;  // pointer to next node
} Node;

/* the actual linked list: ref to first and last Node, size attribute */
typedef struct LinkedList {
    struct Node *first;
    struct Node *last;
    int size;
} LinkedList;

/********** FUNCTION HEADERS **********************/
LinkedList* init_list();
void insert_end(LinkedList *list, int key, char string[]);
void insert_beginning(LinkedList *list, int key, char string[]);
int remove_end(LinkedList *list);
int remove_beginning(LinkedList *list);
int print_list(LinkedList *list);
void free_list(LinkedList *list);
char * get_string(LinkedList *list, int key);

/*********** FUNCTION DEFINITIONS ***************/

/**
 * init_list Returns an appropriately (for an empty list) initialized struct List
 *
 * @return LinkedList *         ..ptr to the newly initialized list
 */
LinkedList * init_list() {
    printf("initializing list...\n");

    LinkedList *list = (LinkedList*) malloc(sizeof(LinkedList));

    list->first = NULL;
    list->last = NULL;
    list->size = 0;

    return list;
}

/**
 * Given a List, a key and a string adds a Node containing this
 * information at the end of the list
 *
 * @param list      LinkedList *    ..ptr to LinkedList
 * @param key       int             .. key of the Node to be inserted
 * @param string    char[]          .. the string of the Node to be inserted
 */
void insert_end(LinkedList *list, int key, char string[]) {
    printf("----------------------\n");

    list->size++;                    // increment size of list

    // intialize the new Node
    Node* newN = (Node*) malloc(sizeof(Node));
    newN->key = key;
    strcpy(newN->string, string);
    newN->next = NULL;

    Node* oldLast = list->last;      // get the old last
    oldLast->next = newN;          // make new Node the next Node for oldlast
    list->last = newN;              // set the new last  in the list

    printf("new Node(%p) at end: %d '%s' %p \n", newN, newN->key, newN->string,newN->next);
}

/**
 * Given a List, a key and a string adds a Node, containing
 * this information at the beginning of the list
 *
 * @param list      LinkedList *    ..ptr to LinkedList
 * @param key       int             .. key of the Node to be inserted
 * @param string    char[]          .. the string of the Node to be inserted
 */
void insert_beginning(LinkedList *list, int key, char string[]) {
    printf("----------------------\n");

    list->size++;                    // increment size of list
    Node* oldFirst = list->first;    //get the old first node

    /* intialize the new Node */
    Node* newN = (Node*) malloc(sizeof(Node));
    newN->key = key;
    strcpy(newN->string, string);
    newN->next = oldFirst;

    list->first = newN;              // set the new first

    /* special case: if list size == 1, then this new one is also the last one */
    if (list->size == 1)
        list->last = newN;

    printf("new Node(%p) at beginning: %d '%s' %p \n", newN, newN->key,newN->string, newN->next);
}

/**
 * Removes the first Node from the list
 *
 * @param list      LinkedList *        .. ptr to the List
 *
 * @return OK | ERROR
 */
int remove_beginning(LinkedList *list) {
    printf("----------------------\n");

    if (list->size <= 0)
        return ERROR;

    list->size--;

    Node * oldFirst = list->first;

    printf("delete Node(%p) at beginning: '%d' '%s' '%p' \n", oldFirst,oldFirst->key, oldFirst->string, oldFirst->next);

    free(list->first);          //free it
    list->first = oldFirst->next;
    oldFirst = NULL;

    return OK;
}

/**
 * Removes the last Node from the list.
 *
 * @param list      LinkedList *        .. ptr to the List
 *
 * @return OK | ERROR
 */
int remove_end(LinkedList *list) {
    printf("----------------------\n");

    /* special case #1 */
    if (list->size <= 0)
        return ERROR;

    /* special case #2 */
    if (list->size == 1) {
        free(list->first);
        list->first = NULL;
        list->last = NULL;
        return OK;
    }

    printf("delete Node(%p) at end: '%d' '%s' '%p' \n", list->last,list->last->key, list->last->string, list->last->next);

    list->size--;           // decrement list size
    Node * startNode = list->first;

    /* find the new last node (the one before the old last one); list->size >= 2 at this point!*/
    Node * newLast = startNode;
    while (newLast->next->next != NULL) {
        newLast = newLast->next;
    }

    free(newLast->next);    //free it
    newLast->next = NULL;   //set to NULL to denote new end of list
    list->last = newLast;   // set the new list->last

    return OK;
}

/**
 * Given a List prints all key/string pairs contained in the list to
 * the screen
 *
 * @param list      LinkedList *        .. ptr to the List
 *
 * @return  OK | ERROR
 */
int print_list(LinkedList *list) {

    printf("----------------------\n");

    if (list->size <= 0)
        return ERROR;

    printf("List.size = %d \n", list->size);

    Node *startN = list->first;  //get first

    /* iterate through list and print contents */
    do {
        printf("Node#%d.string = '%s', .next = '%p' \n", startN->key,startN->string, startN->next);
        startN = startN->next;
    } while (startN != NULL);

    return OK;
}

/**
 * Given a List, frees all memory associated with this list.
 *
 * @param list      LinkedList *        ..ptr to the list
 */
void free_list(LinkedList *list) {
    printf("----------------------\n");
    printf("freeing list...\n");

    if (list != NULL && list->size > 0) {
        Node * startN = list->first;
        Node * temp = list->first;

        do {
            free(temp);
            startN = startN->next;
            temp = startN;
        } while (startN != NULL);

        free(list);
    }
}

/**
 * Given a List and a key, iterates through the whole List and returns
 * the string of the first node which contains the key
 *
 * @param list      LinkedList *        ..ptr to the list
 * @param key       int                 .. the key of the Node to get the String from
 *
 * @return OK | ERROR
 */
char * get_string(LinkedList *list, int key) {
    printf("----------------------\n");

    Node *startN = list->first;  //get first

    /* if only one node.. */
    if(list->size == 1)
        return startN->string;

        /* iterate through list and find Node where node->key == key */
    while (startN->next != NULL) {
        if (startN->key == key)
            return startN->string;
        else
            startN = startN->next;
    }

    return NULL;
}

/*************** MAIN **************/
int main(void) {

    LinkedList *list = init_list();

    insert_beginning(list, 1, "im the first");
    insert_end(list, 2, "im the second");
    insert_end(list, 3, "im the third");
    insert_end(list, 4, "forth here");

    print_list(list);
    remove_end(list);
    print_list(list);
    remove_beginning(list);
    print_list(list);
    remove_end(list);
    print_list(list);
    printf("string at node with key %d = '%s' \n",2,get_string(list, 2));
    free_list(list);

    return OK;
}

TRY IT ONLINE

答案 7 :(得分:0)

从链接列表的任何位置删除节点可以通过下面给出的代码完成。

void DeleteNodeFromLinkedList(struct ListNode* head,int position){
 int k=1;
 struct ListNode *p,*q;
 if(*head==NULL){
     printf("List Empty");
     return;
 }
 if(postion==1){
     *head=(*head)->next;
      free(p);
      return ;
 }
 else{
   while(p!=NULL&&k<position)
       {
          k++;
          q=p;
          p=p->next;
        }
   if(p==NULL)
       {
          printf("Position of the node doesnt exist");
          return ;
          }
   else
       {
           q->next=P->next;
           free(p);
           return ;
       }
   }
  }

时间复杂度:O(n) 空间复杂度:O(1)

答案 8 :(得分:0)

void delete_last(){    
    struct node *ptr=start;
    while(ptr->next->next!=NULL){
        ptr=ptr->next;
    }
    ptr->next=NULL;
    free(ptr->next);    
}