2013-06-19 56 views
2

我可以使用下面的原型用C刪除最後一個節點刪除單鏈表的最後一個節點 - : INT刪除(結構節點*頭,INT項目)使用單一指針開始節點

注 - :這裏的第一個參數是一個指向開始節點的指針,而不是指向指向開始節點的指針。

感謝

+1

是的,當然。 – 2013-06-19 06:44:26

+0

但是爲了刪除單個列表的中間節點,我們必須使用原型delete(stuct node ** head,int data)對嗎? – arpita

+0

nope,僅用於第一個節點。 – 2013-06-19 06:49:48

回答

0

是的,你可以通過循環每個list_node->接下來,開始與頭戴式>下一步,直到list_node->接下來爲空。此時,當前list_node是要刪除的那個。如果我正確理解你的問題...

4

是的。可以從第一個節點開始刪除單向鏈表的最後一個節點。

嘗試下面的代碼,

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); 
+0

+1用於指出一個常見的內存錯誤。我會在while(temp!= NULL && temp-> next!= NULL)時將'while(temp-> next!= NULL)'改爲'好的措施。 – Anselm

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

答案取決於問題究竟是什麼意思。

如果列表包含多個元素,那麼當然,您可以輕鬆安全地刪除最後一個元素(列表中的尾部元素)。只需遍歷最後一個元素,刪除最後一個元素並更新next指針。請注意,在這種情況下,調用者的指針head將仍然是指向有效列表的完美有效指針。然而,如果列表最初僅包含一個元素(意味着head已經指向最後一個元素),那麼當然,您仍然可以輕鬆地將其刪除,但不幸的是,您不能更新來自內部的指針的指針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); 

我不知道您的情況下該問題點是否重要。事實上,你提到head「不是指針指針」,這表明這可能確實很重要。

P.S.我懷疑你的問題中的「last」一詞並不是指列表的尾部元素,而是指列表中最後的剩餘元素。即這個問題具體是關於只剩下一個元素的情況。在這種情況下,請參閱上面的...

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); 
} 
0

是的,它很容易.. 繼續爲根據.. 假設你的鏈接列表中有第一個節點標題最後一個節點「最後」 ..然後添加任何節點溫度和CTEMP ...

temp = header; 
while(temp->link != NULL) 
{ 
    ctemp = temp; 
    temp = temp->link; 
} 
ctemp->link = NULL; 
delete temp; 
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

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)

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

你應該給你的答案增加一個解釋如何解決OP的問題。 – moggi