Can I delete the last node using the below prototype in C -: int delete(struct node *head, int item)
Note-: The first argument here is a point to start node and not pointer to pointer to start node .
Thanks
Yes. It is possible to delete the last node of a singly linked list, starting from the first node.
Try the following code,
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;
}
But if there is just a single element in your linked list, then after deleting that element your head pointer will still point to the now deleted memory location in the function from which you called the delete()
. In such a case use the following version of 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;
}
Call the function delete()
as follows,
head=delete(head);
The answer depends on what exactly is meant by the question.
You can, of course, easily and safely delete the last element (= tail element of the list), if the list contains more than one element. Simply iterate to the element before the last, delete the last and update the next
pointer in new last element. Note that in that case the caller's head
pointer will remain a perfectly valid pointer to a valid list.
However, if the list initially contained only one element (meaning that head
is already pointing to the last element) then, of course, you can still easily delete it, but unfortunately you can't update caller's head
pointer from inside delete
function. After such deletion the caller's head
pointer will become invalid. It will point to now-deallocated memory, ie it will become a dangling pointer.
Typically, when one implements a function like that, one should make sure that the caller will know when the list becomes empty. It can be implemented in different ways. For example, the caller's head
pointer can be made accessible and modifiable from inside the delete
function if the first parameter is declared as a pointer-to-pointer to head node
int delete(struct node **phead, int item)
...
delete(&head, 42);
Alternatively delete
function can be made to always return the updated head pointer value
struct node *delete(struct node *head, int item);
...
head = delete(head, 42);
I don't know whether that issue point is important in your case. The fact that you mention that head
"is not pointer-to-pointer" suggests that this might indeed be important.
PS I suspect that the word "last" in your question does not refer to the tail element of the list, but rather refers to the last remaining element of the list. Ie the question is specifically about the situation when there's only one element left. In that case, see above...
Yes, you can just cycling through each list_node->next, starting with head->next until list_node->next is null. At that point the current list_node is the one to be deleted. If I understand your question correctly...
If you're looking for a way to delete the last node of the linked list, this code will work for you :)
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;
}
This code will work for deleting the last element of a linked list.
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);
}
Yes it's easy.. Proceed as according.. Suppose your linked list has first node header last node 'last'..then adding any node temp and ctemp...
temp = header;
while(temp->link != NULL)
{
ctemp = temp;
temp = temp->link;
}
ctemp->link = NULL;
delete temp;
I've done the same as you and struggled at the same point, but finally implemented it cleanly. Feel free to use the code. Your problem is handled in int remove_end(LinkedList *list)
.
Here the full working implementation:
#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;
}
Deleting a node from any position of the linked list can done by the code given below.
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 ;
}
}
}
Time Complexity:O(n) Space Complexity:O(1)
void delete_last(){
struct node *ptr=start;
while(ptr->next->next!=NULL){
ptr=ptr->next;
}
ptr->next=NULL;
free(ptr->next);
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.