Эта функция мне кажется вполне подходящей, учитывая, как вы описали свои требования
CellPtr new_first_cell(CellPtr list, CellPtr c)
{
c->next=list;
return c;/*returnes the start of the list*/
}
Однако у last_cell_out
есть некоторые проблемы.
Прежде всего вам это не нужноблок кода
if (list->next->next==NULL)
{
c=list->next;
list->next=NULL;
}
в любом случае это будет рассматриваться в следующем цикле.
При этом ваша функция удаляет последний элемент из списка.Он просто не возвращает его и не изменяет его в вашем коде так, как вы можете видеть это.
Один из вариантов - вернуть последнюю ячейку вместо передачи ее в качестве параметра.
CellPtr last_cell_out(CellPtr *listPtr)
{
CellPtr list = *listPtr;
if (list==NULL)/*if list is empty*/
return NULL;/*doing nothing*/
if (list->next==NULL)/*if theres only one cell in the list*/
{
*listPtr = NULL;
return list;/*deleting from list and return*/
}
return last_cell_out(&(list->next));
}
Второй вариант передал бы c в качестве указателя, чтобы вы могли изменить его содержимое внутри кода.
void last_cell_out(CellPtr *listPtr, CellPtr *c)
{
CellPtr list = *listPtr;
if (list==NULL)/*if list is empty*/
{
*c = NULL;
return;/*doing nothing*/
}
if (list->next==NULL)/*if theres only one cell in the list*/
{
*c=list;
*listPtr = NULL;
return;/*deleting from list and moving to c*/
}
last_cell_out(&((*listPtr)->next), c);
return;
}
Вы также можете полностью избежать рекурсии, чтобы избежать возможного переполнения стека, если ваш список становится слишкомбольшой.
CellPtr last_cell_out(CellPtr *listPtr)
{
CellPtr list = *listPtr;
if(list == NULL)
return NULL;
if(list->next == NULL) {
*listPtr = NULL;
return list;
}
while(list->next->next != NULL)
list = list->next;
CellPtr tmp = list->next;
list->next = NULL;
return tmp;
}
Полная программа испытаний:
#include <stdlib.h>
#include <stdio.h>
typedef struct cell *CellPtr;
typedef struct cell
{
int contents; /* contents of the cell */
CellPtr next; /* next cell in the list */
} Cell;
CellPtr last_cell_out(CellPtr *listPtr)
{
CellPtr list = *listPtr;
if(list == NULL)
return NULL;
if(list->next == NULL) {
*listPtr = NULL;
return list;
}
while(list->next->next != NULL)
list = list->next;
CellPtr tmp = list->next;
list->next = NULL;
return tmp;
}
CellPtr new_first_cell(CellPtr list, CellPtr c)
{
c->next=list;
return c;/*returnes the start of the list*/
}
void show_list(CellPtr list)
{
if(list == NULL) {
printf("\n");
return;
}
printf("%d ", list->contents);
show_list(list->next);
}
int main()
{
CellPtr list = NULL;
CellPtr out;
int i;
show_list(list);
CellPtr elem = malloc(sizeof(struct cell));
elem->contents = 0;
list = new_first_cell(list, elem);
show_list(list);
out = last_cell_out(&list);
show_list(list);
list = new_first_cell(list, out);
show_list(list);
for(i = 1; i < 5; ++i) {
CellPtr elem = malloc(sizeof(struct cell));
elem->contents = i;
list = new_first_cell(list, elem);
}
show_list(list);
out = last_cell_out(&list);
show_list(list);
list = new_first_cell(list, out);
show_list(list);
}